ActivityManagerService.java revision df88d73092c62a1a3cd2b2056ca63ae2e70cc238
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.readIntAttribute; 21import static com.android.internal.util.XmlUtils.readLongAttribute; 22import static com.android.internal.util.XmlUtils.writeIntAttribute; 23import static com.android.internal.util.XmlUtils.writeLongAttribute; 24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 26import static org.xmlpull.v1.XmlPullParser.START_TAG; 27 28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 29 30import android.app.AppOpsManager; 31import android.app.IActivityContainer; 32import android.app.IActivityContainerCallback; 33import android.appwidget.AppWidgetManager; 34import android.graphics.Rect; 35import android.util.ArrayMap; 36import com.android.internal.R; 37import com.android.internal.annotations.GuardedBy; 38import com.android.internal.app.IAppOpsService; 39import com.android.internal.app.ProcessMap; 40import com.android.internal.app.ProcessStats; 41import com.android.internal.os.BackgroundThread; 42import com.android.internal.os.BatteryStatsImpl; 43import com.android.internal.os.ProcessCpuTracker; 44import com.android.internal.os.TransferPipe; 45import com.android.internal.util.FastPrintWriter; 46import com.android.internal.util.FastXmlSerializer; 47import com.android.internal.util.MemInfoReader; 48import com.android.internal.util.Preconditions; 49import com.android.server.AppOpsService; 50import com.android.server.AttributeCache; 51import com.android.server.IntentResolver; 52import com.android.server.ServiceThread; 53import com.android.server.SystemServer; 54import com.android.server.SystemService; 55import com.android.server.Watchdog; 56import com.android.server.am.ActivityStack.ActivityState; 57import com.android.server.firewall.IntentFirewall; 58import com.android.server.pm.UserManagerService; 59import com.android.server.wm.AppTransition; 60import com.android.server.wm.WindowManagerService; 61import com.google.android.collect.Lists; 62import com.google.android.collect.Maps; 63 64import dalvik.system.Zygote; 65 66import libcore.io.IoUtils; 67 68import org.xmlpull.v1.XmlPullParser; 69import org.xmlpull.v1.XmlPullParserException; 70import org.xmlpull.v1.XmlSerializer; 71 72import android.app.Activity; 73import android.app.ActivityManager; 74import android.app.ActivityManager.RunningTaskInfo; 75import android.app.ActivityManager.StackInfo; 76import android.app.ActivityManagerNative; 77import android.app.ActivityOptions; 78import android.app.ActivityThread; 79import android.app.AlertDialog; 80import android.app.AppGlobals; 81import android.app.ApplicationErrorReport; 82import android.app.Dialog; 83import android.app.IActivityController; 84import android.app.IApplicationThread; 85import android.app.IInstrumentationWatcher; 86import android.app.INotificationManager; 87import android.app.IProcessObserver; 88import android.app.IServiceConnection; 89import android.app.IStopUserCallback; 90import android.app.IThumbnailReceiver; 91import android.app.IUiAutomationConnection; 92import android.app.IUserSwitchObserver; 93import android.app.Instrumentation; 94import android.app.Notification; 95import android.app.NotificationManager; 96import android.app.PendingIntent; 97import android.app.backup.IBackupManager; 98import android.content.ActivityNotFoundException; 99import android.content.BroadcastReceiver; 100import android.content.ClipData; 101import android.content.ComponentCallbacks2; 102import android.content.ComponentName; 103import android.content.ContentProvider; 104import android.content.ContentResolver; 105import android.content.Context; 106import android.content.DialogInterface; 107import android.content.IContentProvider; 108import android.content.IIntentReceiver; 109import android.content.IIntentSender; 110import android.content.Intent; 111import android.content.IntentFilter; 112import android.content.IntentSender; 113import android.content.pm.ActivityInfo; 114import android.content.pm.ApplicationInfo; 115import android.content.pm.ConfigurationInfo; 116import android.content.pm.IPackageDataObserver; 117import android.content.pm.IPackageManager; 118import android.content.pm.InstrumentationInfo; 119import android.content.pm.PackageInfo; 120import android.content.pm.PackageManager; 121import android.content.pm.ParceledListSlice; 122import android.content.pm.UserInfo; 123import android.content.pm.PackageManager.NameNotFoundException; 124import android.content.pm.PathPermission; 125import android.content.pm.ProviderInfo; 126import android.content.pm.ResolveInfo; 127import android.content.pm.ServiceInfo; 128import android.content.res.CompatibilityInfo; 129import android.content.res.Configuration; 130import android.graphics.Bitmap; 131import android.net.Proxy; 132import android.net.ProxyProperties; 133import android.net.Uri; 134import android.os.Binder; 135import android.os.Build; 136import android.os.Bundle; 137import android.os.Debug; 138import android.os.DropBoxManager; 139import android.os.Environment; 140import android.os.FactoryTest; 141import android.os.FileObserver; 142import android.os.FileUtils; 143import android.os.Handler; 144import android.os.IBinder; 145import android.os.IPermissionController; 146import android.os.IRemoteCallback; 147import android.os.IUserManager; 148import android.os.Looper; 149import android.os.Message; 150import android.os.Parcel; 151import android.os.ParcelFileDescriptor; 152import android.os.Process; 153import android.os.RemoteCallbackList; 154import android.os.RemoteException; 155import android.os.SELinux; 156import android.os.ServiceManager; 157import android.os.StrictMode; 158import android.os.SystemClock; 159import android.os.SystemProperties; 160import android.os.UpdateLock; 161import android.os.UserHandle; 162import android.provider.Settings; 163import android.text.format.DateUtils; 164import android.text.format.Time; 165import android.util.AtomicFile; 166import android.util.EventLog; 167import android.util.Log; 168import android.util.Pair; 169import android.util.PrintWriterPrinter; 170import android.util.Slog; 171import android.util.SparseArray; 172import android.util.TimeUtils; 173import android.util.Xml; 174import android.view.Gravity; 175import android.view.LayoutInflater; 176import android.view.View; 177import android.view.WindowManager; 178 179import java.io.BufferedInputStream; 180import java.io.BufferedOutputStream; 181import java.io.DataInputStream; 182import java.io.DataOutputStream; 183import java.io.File; 184import java.io.FileDescriptor; 185import java.io.FileInputStream; 186import java.io.FileNotFoundException; 187import java.io.FileOutputStream; 188import java.io.IOException; 189import java.io.InputStreamReader; 190import java.io.PrintWriter; 191import java.io.StringWriter; 192import java.lang.ref.WeakReference; 193import java.util.ArrayList; 194import java.util.Arrays; 195import java.util.Collections; 196import java.util.Comparator; 197import java.util.HashMap; 198import java.util.HashSet; 199import java.util.Iterator; 200import java.util.List; 201import java.util.Locale; 202import java.util.Map; 203import java.util.Set; 204import java.util.concurrent.atomic.AtomicBoolean; 205import java.util.concurrent.atomic.AtomicLong; 206 207public final class ActivityManagerService extends ActivityManagerNative 208 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 209 private static final String USER_DATA_DIR = "/data/user/"; 210 static final String TAG = "ActivityManager"; 211 static final String TAG_MU = "ActivityManagerServiceMU"; 212 static final boolean DEBUG = false; 213 static final boolean localLOGV = DEBUG; 214 static final boolean DEBUG_BACKUP = localLOGV || false; 215 static final boolean DEBUG_BROADCAST = localLOGV || false; 216 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 217 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 218 static final boolean DEBUG_CLEANUP = localLOGV || false; 219 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 220 static final boolean DEBUG_FOCUS = false; 221 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 222 static final boolean DEBUG_MU = localLOGV || false; 223 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 224 static final boolean DEBUG_LRU = localLOGV || false; 225 static final boolean DEBUG_PAUSE = localLOGV || false; 226 static final boolean DEBUG_POWER = localLOGV || false; 227 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 228 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 229 static final boolean DEBUG_PROCESSES = localLOGV || false; 230 static final boolean DEBUG_PROVIDER = localLOGV || false; 231 static final boolean DEBUG_RESULTS = localLOGV || false; 232 static final boolean DEBUG_SERVICE = localLOGV || false; 233 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 234 static final boolean DEBUG_STACK = localLOGV || false; 235 static final boolean DEBUG_SWITCH = localLOGV || false; 236 static final boolean DEBUG_TASKS = localLOGV || false; 237 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 238 static final boolean DEBUG_TRANSITION = localLOGV || false; 239 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 240 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 241 static final boolean DEBUG_VISBILITY = localLOGV || false; 242 static final boolean DEBUG_PSS = localLOGV || false; 243 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 244 static final boolean VALIDATE_TOKENS = false; 245 static final boolean SHOW_ACTIVITY_START_TIME = true; 246 247 // Control over CPU and battery monitoring. 248 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 249 static final boolean MONITOR_CPU_USAGE = true; 250 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 251 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 252 static final boolean MONITOR_THREAD_CPU_USAGE = false; 253 254 // The flags that are set for all calls we make to the package manager. 255 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 256 257 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 258 259 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 260 261 // Maximum number of recent tasks that we can remember. 262 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 263 264 // Amount of time after a call to stopAppSwitches() during which we will 265 // prevent further untrusted switches from happening. 266 static final long APP_SWITCH_DELAY_TIME = 5*1000; 267 268 // How long we wait for a launched process to attach to the activity manager 269 // before we decide it's never going to come up for real. 270 static final int PROC_START_TIMEOUT = 10*1000; 271 272 // How long we wait for a launched process to attach to the activity manager 273 // before we decide it's never going to come up for real, when the process was 274 // started with a wrapper for instrumentation (such as Valgrind) because it 275 // could take much longer than usual. 276 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 277 278 // How long to wait after going idle before forcing apps to GC. 279 static final int GC_TIMEOUT = 5*1000; 280 281 // The minimum amount of time between successive GC requests for a process. 282 static final int GC_MIN_INTERVAL = 60*1000; 283 284 // The minimum amount of time between successive PSS requests for a process. 285 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 286 287 // The minimum amount of time between successive PSS requests for a process 288 // when the request is due to the memory state being lowered. 289 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 290 291 // The rate at which we check for apps using excessive power -- 15 mins. 292 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 293 294 // The minimum sample duration we will allow before deciding we have 295 // enough data on wake locks to start killing things. 296 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 297 298 // The minimum sample duration we will allow before deciding we have 299 // enough data on CPU usage to start killing things. 300 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 301 302 // How long we allow a receiver to run before giving up on it. 303 static final int BROADCAST_FG_TIMEOUT = 10*1000; 304 static final int BROADCAST_BG_TIMEOUT = 60*1000; 305 306 // How long we wait until we timeout on key dispatching. 307 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 308 309 // How long we wait until we timeout on key dispatching during instrumentation. 310 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 311 312 // Amount of time we wait for observers to handle a user switch before 313 // giving up on them and unfreezing the screen. 314 static final int USER_SWITCH_TIMEOUT = 2*1000; 315 316 // Maximum number of users we allow to be running at a time. 317 static final int MAX_RUNNING_USERS = 3; 318 319 // How long to wait in getAssistContextExtras for the activity and foreground services 320 // to respond with the result. 321 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 322 323 // Maximum number of persisted Uri grants a package is allowed 324 static final int MAX_PERSISTED_URI_GRANTS = 128; 325 326 static final int MY_PID = Process.myPid(); 327 328 static final String[] EMPTY_STRING_ARRAY = new String[0]; 329 330 // How many bytes to write into the dropbox log before truncating 331 static final int DROPBOX_MAX_SIZE = 256 * 1024; 332 333 /** Run all ActivityStacks through this */ 334 ActivityStackSupervisor mStackSupervisor; 335 336 public IntentFirewall mIntentFirewall; 337 338 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 339 // default actuion automatically. Important for devices without direct input 340 // devices. 341 private boolean mShowDialogs = true; 342 343 /** 344 * Description of a request to start a new activity, which has been held 345 * due to app switches being disabled. 346 */ 347 static class PendingActivityLaunch { 348 final ActivityRecord r; 349 final ActivityRecord sourceRecord; 350 final int startFlags; 351 final ActivityStack stack; 352 353 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 354 int _startFlags, ActivityStack _stack) { 355 r = _r; 356 sourceRecord = _sourceRecord; 357 startFlags = _startFlags; 358 stack = _stack; 359 } 360 } 361 362 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 363 = new ArrayList<PendingActivityLaunch>(); 364 365 BroadcastQueue mFgBroadcastQueue; 366 BroadcastQueue mBgBroadcastQueue; 367 // Convenient for easy iteration over the queues. Foreground is first 368 // so that dispatch of foreground broadcasts gets precedence. 369 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 370 371 BroadcastQueue broadcastQueueForIntent(Intent intent) { 372 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 373 if (DEBUG_BACKGROUND_BROADCAST) { 374 Slog.i(TAG, "Broadcast intent " + intent + " on " 375 + (isFg ? "foreground" : "background") 376 + " queue"); 377 } 378 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 379 } 380 381 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 382 for (BroadcastQueue queue : mBroadcastQueues) { 383 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 384 if (r != null) { 385 return r; 386 } 387 } 388 return null; 389 } 390 391 /** 392 * Activity we have told the window manager to have key focus. 393 */ 394 ActivityRecord mFocusedActivity = null; 395 396 /** 397 * List of intents that were used to start the most recent tasks. 398 */ 399 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 400 401 public class PendingAssistExtras extends Binder implements Runnable { 402 public final ActivityRecord activity; 403 public boolean haveResult = false; 404 public Bundle result = null; 405 public PendingAssistExtras(ActivityRecord _activity) { 406 activity = _activity; 407 } 408 @Override 409 public void run() { 410 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 411 synchronized (this) { 412 haveResult = true; 413 notifyAll(); 414 } 415 } 416 } 417 418 final ArrayList<PendingAssistExtras> mPendingAssistExtras 419 = new ArrayList<PendingAssistExtras>(); 420 421 /** 422 * Process management. 423 */ 424 final ProcessList mProcessList = new ProcessList(); 425 426 /** 427 * All of the applications we currently have running organized by name. 428 * The keys are strings of the application package name (as 429 * returned by the package manager), and the keys are ApplicationRecord 430 * objects. 431 */ 432 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 433 434 /** 435 * Tracking long-term execution of processes to look for abuse and other 436 * bad app behavior. 437 */ 438 final ProcessStatsService mProcessStats; 439 440 /** 441 * The currently running isolated processes. 442 */ 443 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 444 445 /** 446 * Counter for assigning isolated process uids, to avoid frequently reusing the 447 * same ones. 448 */ 449 int mNextIsolatedProcessUid = 0; 450 451 /** 452 * The currently running heavy-weight process, if any. 453 */ 454 ProcessRecord mHeavyWeightProcess = null; 455 456 /** 457 * The last time that various processes have crashed. 458 */ 459 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 460 461 /** 462 * Information about a process that is currently marked as bad. 463 */ 464 static final class BadProcessInfo { 465 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 466 this.time = time; 467 this.shortMsg = shortMsg; 468 this.longMsg = longMsg; 469 this.stack = stack; 470 } 471 472 final long time; 473 final String shortMsg; 474 final String longMsg; 475 final String stack; 476 } 477 478 /** 479 * Set of applications that we consider to be bad, and will reject 480 * incoming broadcasts from (which the user has no control over). 481 * Processes are added to this set when they have crashed twice within 482 * a minimum amount of time; they are removed from it when they are 483 * later restarted (hopefully due to some user action). The value is the 484 * time it was added to the list. 485 */ 486 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 487 488 /** 489 * All of the processes we currently have running organized by pid. 490 * The keys are the pid running the application. 491 * 492 * <p>NOTE: This object is protected by its own lock, NOT the global 493 * activity manager lock! 494 */ 495 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 496 497 /** 498 * All of the processes that have been forced to be foreground. The key 499 * is the pid of the caller who requested it (we hold a death 500 * link on it). 501 */ 502 abstract class ForegroundToken implements IBinder.DeathRecipient { 503 int pid; 504 IBinder token; 505 } 506 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 507 508 /** 509 * List of records for processes that someone had tried to start before the 510 * system was ready. We don't start them at that point, but ensure they 511 * are started by the time booting is complete. 512 */ 513 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 514 515 /** 516 * List of persistent applications that are in the process 517 * of being started. 518 */ 519 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 520 521 /** 522 * Processes that are being forcibly torn down. 523 */ 524 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 525 526 /** 527 * List of running applications, sorted by recent usage. 528 * The first entry in the list is the least recently used. 529 */ 530 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 531 532 /** 533 * Where in mLruProcesses that the processes hosting activities start. 534 */ 535 int mLruProcessActivityStart = 0; 536 537 /** 538 * Where in mLruProcesses that the processes hosting services start. 539 * This is after (lower index) than mLruProcessesActivityStart. 540 */ 541 int mLruProcessServiceStart = 0; 542 543 /** 544 * List of processes that should gc as soon as things are idle. 545 */ 546 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 547 548 /** 549 * Processes we want to collect PSS data from. 550 */ 551 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 552 553 /** 554 * Last time we requested PSS data of all processes. 555 */ 556 long mLastFullPssTime = SystemClock.uptimeMillis(); 557 558 /** 559 * This is the process holding what we currently consider to be 560 * the "home" activity. 561 */ 562 ProcessRecord mHomeProcess; 563 564 /** 565 * This is the process holding the activity the user last visited that 566 * is in a different process from the one they are currently in. 567 */ 568 ProcessRecord mPreviousProcess; 569 570 /** 571 * The time at which the previous process was last visible. 572 */ 573 long mPreviousProcessVisibleTime; 574 575 /** 576 * Which uses have been started, so are allowed to run code. 577 */ 578 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 579 580 /** 581 * LRU list of history of current users. Most recently current is at the end. 582 */ 583 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 584 585 /** 586 * Constant array of the users that are currently started. 587 */ 588 int[] mStartedUserArray = new int[] { 0 }; 589 590 /** 591 * Registered observers of the user switching mechanics. 592 */ 593 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 594 = new RemoteCallbackList<IUserSwitchObserver>(); 595 596 /** 597 * Currently active user switch. 598 */ 599 Object mCurUserSwitchCallback; 600 601 /** 602 * Packages that the user has asked to have run in screen size 603 * compatibility mode instead of filling the screen. 604 */ 605 final CompatModePackages mCompatModePackages; 606 607 /** 608 * Set of IntentSenderRecord objects that are currently active. 609 */ 610 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 611 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 612 613 /** 614 * Fingerprints (hashCode()) of stack traces that we've 615 * already logged DropBox entries for. Guarded by itself. If 616 * something (rogue user app) forces this over 617 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 618 */ 619 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 620 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 621 622 /** 623 * Strict Mode background batched logging state. 624 * 625 * The string buffer is guarded by itself, and its lock is also 626 * used to determine if another batched write is already 627 * in-flight. 628 */ 629 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 630 631 /** 632 * Keeps track of all IIntentReceivers that have been registered for 633 * broadcasts. Hash keys are the receiver IBinder, hash value is 634 * a ReceiverList. 635 */ 636 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 637 new HashMap<IBinder, ReceiverList>(); 638 639 /** 640 * Resolver for broadcast intents to registered receivers. 641 * Holds BroadcastFilter (subclass of IntentFilter). 642 */ 643 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 644 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 645 @Override 646 protected boolean allowFilterResult( 647 BroadcastFilter filter, List<BroadcastFilter> dest) { 648 IBinder target = filter.receiverList.receiver.asBinder(); 649 for (int i=dest.size()-1; i>=0; i--) { 650 if (dest.get(i).receiverList.receiver.asBinder() == target) { 651 return false; 652 } 653 } 654 return true; 655 } 656 657 @Override 658 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 659 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 660 || userId == filter.owningUserId) { 661 return super.newResult(filter, match, userId); 662 } 663 return null; 664 } 665 666 @Override 667 protected BroadcastFilter[] newArray(int size) { 668 return new BroadcastFilter[size]; 669 } 670 671 @Override 672 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 673 return packageName.equals(filter.packageName); 674 } 675 }; 676 677 /** 678 * State of all active sticky broadcasts per user. Keys are the action of the 679 * sticky Intent, values are an ArrayList of all broadcasted intents with 680 * that action (which should usually be one). The SparseArray is keyed 681 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 682 * for stickies that are sent to all users. 683 */ 684 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 685 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 686 687 final ActiveServices mServices; 688 689 /** 690 * Backup/restore process management 691 */ 692 String mBackupAppName = null; 693 BackupRecord mBackupTarget = null; 694 695 /** 696 * List of PendingThumbnailsRecord objects of clients who are still 697 * waiting to receive all of the thumbnails for a task. 698 */ 699 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 700 new ArrayList<PendingThumbnailsRecord>(); 701 702 final ProviderMap mProviderMap; 703 704 /** 705 * List of content providers who have clients waiting for them. The 706 * application is currently being launched and the provider will be 707 * removed from this list once it is published. 708 */ 709 final ArrayList<ContentProviderRecord> mLaunchingProviders 710 = new ArrayList<ContentProviderRecord>(); 711 712 /** 713 * File storing persisted {@link #mGrantedUriPermissions}. 714 */ 715 private final AtomicFile mGrantFile; 716 717 /** XML constants used in {@link #mGrantFile} */ 718 private static final String TAG_URI_GRANTS = "uri-grants"; 719 private static final String TAG_URI_GRANT = "uri-grant"; 720 private static final String ATTR_USER_HANDLE = "userHandle"; 721 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 722 private static final String ATTR_TARGET_PKG = "targetPkg"; 723 private static final String ATTR_URI = "uri"; 724 private static final String ATTR_MODE_FLAGS = "modeFlags"; 725 private static final String ATTR_CREATED_TIME = "createdTime"; 726 727 /** 728 * Global set of specific {@link Uri} permissions that have been granted. 729 * This optimized lookup structure maps from {@link UriPermission#targetUid} 730 * to {@link UriPermission#uri} to {@link UriPermission}. 731 */ 732 @GuardedBy("this") 733 private final SparseArray<ArrayMap<Uri, UriPermission>> 734 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 735 736 CoreSettingsObserver mCoreSettingsObserver; 737 738 /** 739 * Thread-local storage used to carry caller permissions over through 740 * indirect content-provider access. 741 */ 742 private class Identity { 743 public int pid; 744 public int uid; 745 746 Identity(int _pid, int _uid) { 747 pid = _pid; 748 uid = _uid; 749 } 750 } 751 752 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 753 754 /** 755 * All information we have collected about the runtime performance of 756 * any user id that can impact battery performance. 757 */ 758 final BatteryStatsService mBatteryStatsService; 759 760 /** 761 * Information about component usage 762 */ 763 final UsageStatsService mUsageStatsService; 764 765 /** 766 * Information about and control over application operations 767 */ 768 final AppOpsService mAppOpsService; 769 770 /** 771 * Current configuration information. HistoryRecord objects are given 772 * a reference to this object to indicate which configuration they are 773 * currently running in, so this object must be kept immutable. 774 */ 775 Configuration mConfiguration = new Configuration(); 776 777 /** 778 * Current sequencing integer of the configuration, for skipping old 779 * configurations. 780 */ 781 int mConfigurationSeq = 0; 782 783 /** 784 * Hardware-reported OpenGLES version. 785 */ 786 final int GL_ES_VERSION; 787 788 /** 789 * List of initialization arguments to pass to all processes when binding applications to them. 790 * For example, references to the commonly used services. 791 */ 792 HashMap<String, IBinder> mAppBindArgs; 793 794 /** 795 * Temporary to avoid allocations. Protected by main lock. 796 */ 797 final StringBuilder mStringBuilder = new StringBuilder(256); 798 799 /** 800 * Used to control how we initialize the service. 801 */ 802 boolean mStartRunning = false; 803 ComponentName mTopComponent; 804 String mTopAction; 805 String mTopData; 806 boolean mProcessesReady = false; 807 boolean mSystemReady = false; 808 boolean mBooting = false; 809 boolean mWaitingUpdate = false; 810 boolean mDidUpdate = false; 811 boolean mOnBattery = false; 812 boolean mLaunchWarningShown = false; 813 814 Context mContext; 815 816 int mFactoryTest; 817 818 boolean mCheckedForSetup; 819 820 /** 821 * The time at which we will allow normal application switches again, 822 * after a call to {@link #stopAppSwitches()}. 823 */ 824 long mAppSwitchesAllowedTime; 825 826 /** 827 * This is set to true after the first switch after mAppSwitchesAllowedTime 828 * is set; any switches after that will clear the time. 829 */ 830 boolean mDidAppSwitch; 831 832 /** 833 * Last time (in realtime) at which we checked for power usage. 834 */ 835 long mLastPowerCheckRealtime; 836 837 /** 838 * Last time (in uptime) at which we checked for power usage. 839 */ 840 long mLastPowerCheckUptime; 841 842 /** 843 * Set while we are wanting to sleep, to prevent any 844 * activities from being started/resumed. 845 */ 846 boolean mSleeping = false; 847 848 /** 849 * State of external calls telling us if the device is asleep. 850 */ 851 boolean mWentToSleep = false; 852 853 /** 854 * State of external call telling us if the lock screen is shown. 855 */ 856 boolean mLockScreenShown = false; 857 858 /** 859 * Set if we are shutting down the system, similar to sleeping. 860 */ 861 boolean mShuttingDown = false; 862 863 /** 864 * Current sequence id for oom_adj computation traversal. 865 */ 866 int mAdjSeq = 0; 867 868 /** 869 * Current sequence id for process LRU updating. 870 */ 871 int mLruSeq = 0; 872 873 /** 874 * Keep track of the non-cached/empty process we last found, to help 875 * determine how to distribute cached/empty processes next time. 876 */ 877 int mNumNonCachedProcs = 0; 878 879 /** 880 * Keep track of the number of cached hidden procs, to balance oom adj 881 * distribution between those and empty procs. 882 */ 883 int mNumCachedHiddenProcs = 0; 884 885 /** 886 * Keep track of the number of service processes we last found, to 887 * determine on the next iteration which should be B services. 888 */ 889 int mNumServiceProcs = 0; 890 int mNewNumAServiceProcs = 0; 891 int mNewNumServiceProcs = 0; 892 893 /** 894 * Allow the current computed overall memory level of the system to go down? 895 * This is set to false when we are killing processes for reasons other than 896 * memory management, so that the now smaller process list will not be taken as 897 * an indication that memory is tighter. 898 */ 899 boolean mAllowLowerMemLevel = false; 900 901 /** 902 * The last computed memory level, for holding when we are in a state that 903 * processes are going away for other reasons. 904 */ 905 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 906 907 /** 908 * The last total number of process we have, to determine if changes actually look 909 * like a shrinking number of process due to lower RAM. 910 */ 911 int mLastNumProcesses; 912 913 /** 914 * The uptime of the last time we performed idle maintenance. 915 */ 916 long mLastIdleTime = SystemClock.uptimeMillis(); 917 918 /** 919 * Total time spent with RAM that has been added in the past since the last idle time. 920 */ 921 long mLowRamTimeSinceLastIdle = 0; 922 923 /** 924 * If RAM is currently low, when that horrible situatin started. 925 */ 926 long mLowRamStartTime = 0; 927 928 /** 929 * This is set if we had to do a delayed dexopt of an app before launching 930 * it, to increasing the ANR timeouts in that case. 931 */ 932 boolean mDidDexOpt; 933 934 String mDebugApp = null; 935 boolean mWaitForDebugger = false; 936 boolean mDebugTransient = false; 937 String mOrigDebugApp = null; 938 boolean mOrigWaitForDebugger = false; 939 boolean mAlwaysFinishActivities = false; 940 IActivityController mController = null; 941 String mProfileApp = null; 942 ProcessRecord mProfileProc = null; 943 String mProfileFile; 944 ParcelFileDescriptor mProfileFd; 945 int mProfileType = 0; 946 boolean mAutoStopProfiler = false; 947 String mOpenGlTraceApp = null; 948 949 static class ProcessChangeItem { 950 static final int CHANGE_ACTIVITIES = 1<<0; 951 static final int CHANGE_IMPORTANCE= 1<<1; 952 int changes; 953 int uid; 954 int pid; 955 int importance; 956 boolean foregroundActivities; 957 } 958 959 final RemoteCallbackList<IProcessObserver> mProcessObservers 960 = new RemoteCallbackList<IProcessObserver>(); 961 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 962 963 final ArrayList<ProcessChangeItem> mPendingProcessChanges 964 = new ArrayList<ProcessChangeItem>(); 965 final ArrayList<ProcessChangeItem> mAvailProcessChanges 966 = new ArrayList<ProcessChangeItem>(); 967 968 /** 969 * Runtime CPU use collection thread. This object's lock is used to 970 * protect all related state. 971 */ 972 final Thread mProcessCpuThread; 973 974 /** 975 * Used to collect process stats when showing not responding dialog. 976 * Protected by mProcessCpuThread. 977 */ 978 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 979 MONITOR_THREAD_CPU_USAGE); 980 final AtomicLong mLastCpuTime = new AtomicLong(0); 981 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 982 983 long mLastWriteTime = 0; 984 985 /** 986 * Used to retain an update lock when the foreground activity is in 987 * immersive mode. 988 */ 989 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 990 991 /** 992 * Set to true after the system has finished booting. 993 */ 994 boolean mBooted = false; 995 996 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 997 int mProcessLimitOverride = -1; 998 999 WindowManagerService mWindowManager; 1000 1001 final ActivityThread mSystemThread; 1002 1003 int mCurrentUserId = 0; 1004 private UserManagerService mUserManager; 1005 1006 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1007 final ProcessRecord mApp; 1008 final int mPid; 1009 final IApplicationThread mAppThread; 1010 1011 AppDeathRecipient(ProcessRecord app, int pid, 1012 IApplicationThread thread) { 1013 if (localLOGV) Slog.v( 1014 TAG, "New death recipient " + this 1015 + " for thread " + thread.asBinder()); 1016 mApp = app; 1017 mPid = pid; 1018 mAppThread = thread; 1019 } 1020 1021 @Override 1022 public void binderDied() { 1023 if (localLOGV) Slog.v( 1024 TAG, "Death received in " + this 1025 + " for thread " + mAppThread.asBinder()); 1026 synchronized(ActivityManagerService.this) { 1027 appDiedLocked(mApp, mPid, mAppThread); 1028 } 1029 } 1030 } 1031 1032 static final int SHOW_ERROR_MSG = 1; 1033 static final int SHOW_NOT_RESPONDING_MSG = 2; 1034 static final int SHOW_FACTORY_ERROR_MSG = 3; 1035 static final int UPDATE_CONFIGURATION_MSG = 4; 1036 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1037 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1038 static final int SERVICE_TIMEOUT_MSG = 12; 1039 static final int UPDATE_TIME_ZONE = 13; 1040 static final int SHOW_UID_ERROR_MSG = 14; 1041 static final int IM_FEELING_LUCKY_MSG = 15; 1042 static final int PROC_START_TIMEOUT_MSG = 20; 1043 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1044 static final int KILL_APPLICATION_MSG = 22; 1045 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1046 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1047 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1048 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1049 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1050 static final int CLEAR_DNS_CACHE_MSG = 28; 1051 static final int UPDATE_HTTP_PROXY_MSG = 29; 1052 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1053 static final int DISPATCH_PROCESSES_CHANGED = 31; 1054 static final int DISPATCH_PROCESS_DIED = 32; 1055 static final int REPORT_MEM_USAGE_MSG = 33; 1056 static final int REPORT_USER_SWITCH_MSG = 34; 1057 static final int CONTINUE_USER_SWITCH_MSG = 35; 1058 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1059 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1060 static final int PERSIST_URI_GRANTS_MSG = 38; 1061 static final int REQUEST_ALL_PSS_MSG = 39; 1062 1063 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1064 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1065 static final int FIRST_COMPAT_MODE_MSG = 300; 1066 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1067 1068 AlertDialog mUidAlert; 1069 CompatModeDialog mCompatModeDialog; 1070 long mLastMemUsageReportTime = 0; 1071 1072 /** 1073 * Flag whether the current user is a "monkey", i.e. whether 1074 * the UI is driven by a UI automation tool. 1075 */ 1076 private boolean mUserIsMonkey; 1077 1078 final ServiceThread mHandlerThread; 1079 final MainHandler mHandler; 1080 1081 final class MainHandler extends Handler { 1082 public MainHandler(Looper looper) { 1083 super(looper, null, true); 1084 } 1085 1086 @Override 1087 public void handleMessage(Message msg) { 1088 switch (msg.what) { 1089 case SHOW_ERROR_MSG: { 1090 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1091 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1092 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1093 synchronized (ActivityManagerService.this) { 1094 ProcessRecord proc = (ProcessRecord)data.get("app"); 1095 AppErrorResult res = (AppErrorResult) data.get("result"); 1096 if (proc != null && proc.crashDialog != null) { 1097 Slog.e(TAG, "App already has crash dialog: " + proc); 1098 if (res != null) { 1099 res.set(0); 1100 } 1101 return; 1102 } 1103 if (!showBackground && UserHandle.getAppId(proc.uid) 1104 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1105 && proc.pid != MY_PID) { 1106 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1107 if (res != null) { 1108 res.set(0); 1109 } 1110 return; 1111 } 1112 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1113 Dialog d = new AppErrorDialog(mContext, 1114 ActivityManagerService.this, res, proc); 1115 d.show(); 1116 proc.crashDialog = d; 1117 } else { 1118 // The device is asleep, so just pretend that the user 1119 // saw a crash dialog and hit "force quit". 1120 if (res != null) { 1121 res.set(0); 1122 } 1123 } 1124 } 1125 1126 ensureBootCompleted(); 1127 } break; 1128 case SHOW_NOT_RESPONDING_MSG: { 1129 synchronized (ActivityManagerService.this) { 1130 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1131 ProcessRecord proc = (ProcessRecord)data.get("app"); 1132 if (proc != null && proc.anrDialog != null) { 1133 Slog.e(TAG, "App already has anr dialog: " + proc); 1134 return; 1135 } 1136 1137 Intent intent = new Intent("android.intent.action.ANR"); 1138 if (!mProcessesReady) { 1139 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1140 | Intent.FLAG_RECEIVER_FOREGROUND); 1141 } 1142 broadcastIntentLocked(null, null, intent, 1143 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1144 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1145 1146 if (mShowDialogs) { 1147 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1148 mContext, proc, (ActivityRecord)data.get("activity"), 1149 msg.arg1 != 0); 1150 d.show(); 1151 proc.anrDialog = d; 1152 } else { 1153 // Just kill the app if there is no dialog to be shown. 1154 killAppAtUsersRequest(proc, null); 1155 } 1156 } 1157 1158 ensureBootCompleted(); 1159 } break; 1160 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1161 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1162 synchronized (ActivityManagerService.this) { 1163 ProcessRecord proc = (ProcessRecord) data.get("app"); 1164 if (proc == null) { 1165 Slog.e(TAG, "App not found when showing strict mode dialog."); 1166 break; 1167 } 1168 if (proc.crashDialog != null) { 1169 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1170 return; 1171 } 1172 AppErrorResult res = (AppErrorResult) data.get("result"); 1173 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1174 Dialog d = new StrictModeViolationDialog(mContext, 1175 ActivityManagerService.this, res, proc); 1176 d.show(); 1177 proc.crashDialog = d; 1178 } else { 1179 // The device is asleep, so just pretend that the user 1180 // saw a crash dialog and hit "force quit". 1181 res.set(0); 1182 } 1183 } 1184 ensureBootCompleted(); 1185 } break; 1186 case SHOW_FACTORY_ERROR_MSG: { 1187 Dialog d = new FactoryErrorDialog( 1188 mContext, msg.getData().getCharSequence("msg")); 1189 d.show(); 1190 ensureBootCompleted(); 1191 } break; 1192 case UPDATE_CONFIGURATION_MSG: { 1193 final ContentResolver resolver = mContext.getContentResolver(); 1194 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1195 } break; 1196 case GC_BACKGROUND_PROCESSES_MSG: { 1197 synchronized (ActivityManagerService.this) { 1198 performAppGcsIfAppropriateLocked(); 1199 } 1200 } break; 1201 case WAIT_FOR_DEBUGGER_MSG: { 1202 synchronized (ActivityManagerService.this) { 1203 ProcessRecord app = (ProcessRecord)msg.obj; 1204 if (msg.arg1 != 0) { 1205 if (!app.waitedForDebugger) { 1206 Dialog d = new AppWaitingForDebuggerDialog( 1207 ActivityManagerService.this, 1208 mContext, app); 1209 app.waitDialog = d; 1210 app.waitedForDebugger = true; 1211 d.show(); 1212 } 1213 } else { 1214 if (app.waitDialog != null) { 1215 app.waitDialog.dismiss(); 1216 app.waitDialog = null; 1217 } 1218 } 1219 } 1220 } break; 1221 case SERVICE_TIMEOUT_MSG: { 1222 if (mDidDexOpt) { 1223 mDidDexOpt = false; 1224 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1225 nmsg.obj = msg.obj; 1226 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1227 return; 1228 } 1229 mServices.serviceTimeout((ProcessRecord)msg.obj); 1230 } break; 1231 case UPDATE_TIME_ZONE: { 1232 synchronized (ActivityManagerService.this) { 1233 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1234 ProcessRecord r = mLruProcesses.get(i); 1235 if (r.thread != null) { 1236 try { 1237 r.thread.updateTimeZone(); 1238 } catch (RemoteException ex) { 1239 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1240 } 1241 } 1242 } 1243 } 1244 } break; 1245 case CLEAR_DNS_CACHE_MSG: { 1246 synchronized (ActivityManagerService.this) { 1247 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1248 ProcessRecord r = mLruProcesses.get(i); 1249 if (r.thread != null) { 1250 try { 1251 r.thread.clearDnsCache(); 1252 } catch (RemoteException ex) { 1253 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1254 } 1255 } 1256 } 1257 } 1258 } break; 1259 case UPDATE_HTTP_PROXY_MSG: { 1260 ProxyProperties proxy = (ProxyProperties)msg.obj; 1261 String host = ""; 1262 String port = ""; 1263 String exclList = ""; 1264 String pacFileUrl = null; 1265 if (proxy != null) { 1266 host = proxy.getHost(); 1267 port = Integer.toString(proxy.getPort()); 1268 exclList = proxy.getExclusionList(); 1269 pacFileUrl = proxy.getPacFileUrl(); 1270 } 1271 synchronized (ActivityManagerService.this) { 1272 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1273 ProcessRecord r = mLruProcesses.get(i); 1274 if (r.thread != null) { 1275 try { 1276 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1277 } catch (RemoteException ex) { 1278 Slog.w(TAG, "Failed to update http proxy for: " + 1279 r.info.processName); 1280 } 1281 } 1282 } 1283 } 1284 } break; 1285 case SHOW_UID_ERROR_MSG: { 1286 String title = "System UIDs Inconsistent"; 1287 String text = "UIDs on the system are inconsistent, you need to wipe your" 1288 + " data partition or your device will be unstable."; 1289 Log.e(TAG, title + ": " + text); 1290 if (mShowDialogs) { 1291 // XXX This is a temporary dialog, no need to localize. 1292 AlertDialog d = new BaseErrorDialog(mContext); 1293 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1294 d.setCancelable(false); 1295 d.setTitle(title); 1296 d.setMessage(text); 1297 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1298 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1299 mUidAlert = d; 1300 d.show(); 1301 } 1302 } break; 1303 case IM_FEELING_LUCKY_MSG: { 1304 if (mUidAlert != null) { 1305 mUidAlert.dismiss(); 1306 mUidAlert = null; 1307 } 1308 } break; 1309 case PROC_START_TIMEOUT_MSG: { 1310 if (mDidDexOpt) { 1311 mDidDexOpt = false; 1312 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1313 nmsg.obj = msg.obj; 1314 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1315 return; 1316 } 1317 ProcessRecord app = (ProcessRecord)msg.obj; 1318 synchronized (ActivityManagerService.this) { 1319 processStartTimedOutLocked(app); 1320 } 1321 } break; 1322 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1323 synchronized (ActivityManagerService.this) { 1324 doPendingActivityLaunchesLocked(true); 1325 } 1326 } break; 1327 case KILL_APPLICATION_MSG: { 1328 synchronized (ActivityManagerService.this) { 1329 int appid = msg.arg1; 1330 boolean restart = (msg.arg2 == 1); 1331 Bundle bundle = (Bundle)msg.obj; 1332 String pkg = bundle.getString("pkg"); 1333 String reason = bundle.getString("reason"); 1334 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1335 UserHandle.USER_ALL, reason); 1336 } 1337 } break; 1338 case FINALIZE_PENDING_INTENT_MSG: { 1339 ((PendingIntentRecord)msg.obj).completeFinalize(); 1340 } break; 1341 case POST_HEAVY_NOTIFICATION_MSG: { 1342 INotificationManager inm = NotificationManager.getService(); 1343 if (inm == null) { 1344 return; 1345 } 1346 1347 ActivityRecord root = (ActivityRecord)msg.obj; 1348 ProcessRecord process = root.app; 1349 if (process == null) { 1350 return; 1351 } 1352 1353 try { 1354 Context context = mContext.createPackageContext(process.info.packageName, 0); 1355 String text = mContext.getString(R.string.heavy_weight_notification, 1356 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1357 Notification notification = new Notification(); 1358 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1359 notification.when = 0; 1360 notification.flags = Notification.FLAG_ONGOING_EVENT; 1361 notification.tickerText = text; 1362 notification.defaults = 0; // please be quiet 1363 notification.sound = null; 1364 notification.vibrate = null; 1365 notification.setLatestEventInfo(context, text, 1366 mContext.getText(R.string.heavy_weight_notification_detail), 1367 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1368 PendingIntent.FLAG_CANCEL_CURRENT, null, 1369 new UserHandle(root.userId))); 1370 1371 try { 1372 int[] outId = new int[1]; 1373 inm.enqueueNotificationWithTag("android", "android", null, 1374 R.string.heavy_weight_notification, 1375 notification, outId, root.userId); 1376 } catch (RuntimeException e) { 1377 Slog.w(ActivityManagerService.TAG, 1378 "Error showing notification for heavy-weight app", e); 1379 } catch (RemoteException e) { 1380 } 1381 } catch (NameNotFoundException e) { 1382 Slog.w(TAG, "Unable to create context for heavy notification", e); 1383 } 1384 } break; 1385 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1386 INotificationManager inm = NotificationManager.getService(); 1387 if (inm == null) { 1388 return; 1389 } 1390 try { 1391 inm.cancelNotificationWithTag("android", null, 1392 R.string.heavy_weight_notification, msg.arg1); 1393 } catch (RuntimeException e) { 1394 Slog.w(ActivityManagerService.TAG, 1395 "Error canceling notification for service", e); 1396 } catch (RemoteException e) { 1397 } 1398 } break; 1399 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1400 synchronized (ActivityManagerService.this) { 1401 checkExcessivePowerUsageLocked(true); 1402 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1403 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1404 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1405 } 1406 } break; 1407 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1408 synchronized (ActivityManagerService.this) { 1409 ActivityRecord ar = (ActivityRecord)msg.obj; 1410 if (mCompatModeDialog != null) { 1411 if (mCompatModeDialog.mAppInfo.packageName.equals( 1412 ar.info.applicationInfo.packageName)) { 1413 return; 1414 } 1415 mCompatModeDialog.dismiss(); 1416 mCompatModeDialog = null; 1417 } 1418 if (ar != null && false) { 1419 if (mCompatModePackages.getPackageAskCompatModeLocked( 1420 ar.packageName)) { 1421 int mode = mCompatModePackages.computeCompatModeLocked( 1422 ar.info.applicationInfo); 1423 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1424 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1425 mCompatModeDialog = new CompatModeDialog( 1426 ActivityManagerService.this, mContext, 1427 ar.info.applicationInfo); 1428 mCompatModeDialog.show(); 1429 } 1430 } 1431 } 1432 } 1433 break; 1434 } 1435 case DISPATCH_PROCESSES_CHANGED: { 1436 dispatchProcessesChanged(); 1437 break; 1438 } 1439 case DISPATCH_PROCESS_DIED: { 1440 final int pid = msg.arg1; 1441 final int uid = msg.arg2; 1442 dispatchProcessDied(pid, uid); 1443 break; 1444 } 1445 case REPORT_MEM_USAGE_MSG: { 1446 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1447 Thread thread = new Thread() { 1448 @Override public void run() { 1449 final SparseArray<ProcessMemInfo> infoMap 1450 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1451 for (int i=0, N=memInfos.size(); i<N; i++) { 1452 ProcessMemInfo mi = memInfos.get(i); 1453 infoMap.put(mi.pid, mi); 1454 } 1455 updateCpuStatsNow(); 1456 synchronized (mProcessCpuThread) { 1457 final int N = mProcessCpuTracker.countStats(); 1458 for (int i=0; i<N; i++) { 1459 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1460 if (st.vsize > 0) { 1461 long pss = Debug.getPss(st.pid, null); 1462 if (pss > 0) { 1463 if (infoMap.indexOfKey(st.pid) < 0) { 1464 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1465 ProcessList.NATIVE_ADJ, -1, "native", null); 1466 mi.pss = pss; 1467 memInfos.add(mi); 1468 } 1469 } 1470 } 1471 } 1472 } 1473 1474 long totalPss = 0; 1475 for (int i=0, N=memInfos.size(); i<N; i++) { 1476 ProcessMemInfo mi = memInfos.get(i); 1477 if (mi.pss == 0) { 1478 mi.pss = Debug.getPss(mi.pid, null); 1479 } 1480 totalPss += mi.pss; 1481 } 1482 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1483 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1484 if (lhs.oomAdj != rhs.oomAdj) { 1485 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1486 } 1487 if (lhs.pss != rhs.pss) { 1488 return lhs.pss < rhs.pss ? 1 : -1; 1489 } 1490 return 0; 1491 } 1492 }); 1493 1494 StringBuilder tag = new StringBuilder(128); 1495 StringBuilder stack = new StringBuilder(128); 1496 tag.append("Low on memory -- "); 1497 appendMemBucket(tag, totalPss, "total", false); 1498 appendMemBucket(stack, totalPss, "total", true); 1499 1500 StringBuilder logBuilder = new StringBuilder(1024); 1501 logBuilder.append("Low on memory:\n"); 1502 1503 boolean firstLine = true; 1504 int lastOomAdj = Integer.MIN_VALUE; 1505 for (int i=0, N=memInfos.size(); i<N; i++) { 1506 ProcessMemInfo mi = memInfos.get(i); 1507 1508 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1509 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1510 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1511 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1512 if (lastOomAdj != mi.oomAdj) { 1513 lastOomAdj = mi.oomAdj; 1514 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1515 tag.append(" / "); 1516 } 1517 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1518 if (firstLine) { 1519 stack.append(":"); 1520 firstLine = false; 1521 } 1522 stack.append("\n\t at "); 1523 } else { 1524 stack.append("$"); 1525 } 1526 } else { 1527 tag.append(" "); 1528 stack.append("$"); 1529 } 1530 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1531 appendMemBucket(tag, mi.pss, mi.name, false); 1532 } 1533 appendMemBucket(stack, mi.pss, mi.name, true); 1534 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1535 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1536 stack.append("("); 1537 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1538 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1539 stack.append(DUMP_MEM_OOM_LABEL[k]); 1540 stack.append(":"); 1541 stack.append(DUMP_MEM_OOM_ADJ[k]); 1542 } 1543 } 1544 stack.append(")"); 1545 } 1546 } 1547 1548 logBuilder.append(" "); 1549 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1550 logBuilder.append(' '); 1551 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1552 logBuilder.append(' '); 1553 ProcessList.appendRamKb(logBuilder, mi.pss); 1554 logBuilder.append(" kB: "); 1555 logBuilder.append(mi.name); 1556 logBuilder.append(" ("); 1557 logBuilder.append(mi.pid); 1558 logBuilder.append(") "); 1559 logBuilder.append(mi.adjType); 1560 logBuilder.append('\n'); 1561 if (mi.adjReason != null) { 1562 logBuilder.append(" "); 1563 logBuilder.append(mi.adjReason); 1564 logBuilder.append('\n'); 1565 } 1566 } 1567 1568 logBuilder.append(" "); 1569 ProcessList.appendRamKb(logBuilder, totalPss); 1570 logBuilder.append(" kB: TOTAL\n"); 1571 1572 long[] infos = new long[Debug.MEMINFO_COUNT]; 1573 Debug.getMemInfo(infos); 1574 logBuilder.append(" MemInfo: "); 1575 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1576 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1577 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1578 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1579 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1580 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1581 logBuilder.append(" ZRAM: "); 1582 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1583 logBuilder.append(" kB RAM, "); 1584 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1585 logBuilder.append(" kB swap total, "); 1586 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1587 logBuilder.append(" kB swap free\n"); 1588 } 1589 Slog.i(TAG, logBuilder.toString()); 1590 1591 StringBuilder dropBuilder = new StringBuilder(1024); 1592 /* 1593 StringWriter oomSw = new StringWriter(); 1594 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1595 StringWriter catSw = new StringWriter(); 1596 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1597 String[] emptyArgs = new String[] { }; 1598 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1599 oomPw.flush(); 1600 String oomString = oomSw.toString(); 1601 */ 1602 dropBuilder.append(stack); 1603 dropBuilder.append('\n'); 1604 dropBuilder.append('\n'); 1605 dropBuilder.append(logBuilder); 1606 dropBuilder.append('\n'); 1607 /* 1608 dropBuilder.append(oomString); 1609 dropBuilder.append('\n'); 1610 */ 1611 StringWriter catSw = new StringWriter(); 1612 synchronized (ActivityManagerService.this) { 1613 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1614 String[] emptyArgs = new String[] { }; 1615 catPw.println(); 1616 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1617 catPw.println(); 1618 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1619 false, false, null); 1620 catPw.println(); 1621 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1622 catPw.flush(); 1623 } 1624 dropBuilder.append(catSw.toString()); 1625 addErrorToDropBox("lowmem", null, "system_server", null, 1626 null, tag.toString(), dropBuilder.toString(), null, null); 1627 //Slog.i(TAG, "Sent to dropbox:"); 1628 //Slog.i(TAG, dropBuilder.toString()); 1629 synchronized (ActivityManagerService.this) { 1630 long now = SystemClock.uptimeMillis(); 1631 if (mLastMemUsageReportTime < now) { 1632 mLastMemUsageReportTime = now; 1633 } 1634 } 1635 } 1636 }; 1637 thread.start(); 1638 break; 1639 } 1640 case REPORT_USER_SWITCH_MSG: { 1641 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1642 break; 1643 } 1644 case CONTINUE_USER_SWITCH_MSG: { 1645 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1646 break; 1647 } 1648 case USER_SWITCH_TIMEOUT_MSG: { 1649 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1650 break; 1651 } 1652 case IMMERSIVE_MODE_LOCK_MSG: { 1653 final boolean nextState = (msg.arg1 != 0); 1654 if (mUpdateLock.isHeld() != nextState) { 1655 if (DEBUG_IMMERSIVE) { 1656 final ActivityRecord r = (ActivityRecord) msg.obj; 1657 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1658 } 1659 if (nextState) { 1660 mUpdateLock.acquire(); 1661 } else { 1662 mUpdateLock.release(); 1663 } 1664 } 1665 break; 1666 } 1667 case PERSIST_URI_GRANTS_MSG: { 1668 writeGrantedUriPermissions(); 1669 break; 1670 } 1671 case REQUEST_ALL_PSS_MSG: { 1672 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1673 break; 1674 } 1675 } 1676 } 1677 }; 1678 1679 static final int COLLECT_PSS_BG_MSG = 1; 1680 1681 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1682 @Override 1683 public void handleMessage(Message msg) { 1684 switch (msg.what) { 1685 case COLLECT_PSS_BG_MSG: { 1686 int i=0, num=0; 1687 long start = SystemClock.uptimeMillis(); 1688 long[] tmp = new long[1]; 1689 do { 1690 ProcessRecord proc; 1691 int procState; 1692 int pid; 1693 synchronized (ActivityManagerService.this) { 1694 if (i >= mPendingPssProcesses.size()) { 1695 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1696 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1697 mPendingPssProcesses.clear(); 1698 return; 1699 } 1700 proc = mPendingPssProcesses.get(i); 1701 procState = proc.pssProcState; 1702 if (proc.thread != null && procState == proc.setProcState) { 1703 pid = proc.pid; 1704 } else { 1705 proc = null; 1706 pid = 0; 1707 } 1708 i++; 1709 } 1710 if (proc != null) { 1711 long pss = Debug.getPss(pid, tmp); 1712 synchronized (ActivityManagerService.this) { 1713 if (proc.thread != null && proc.setProcState == procState 1714 && proc.pid == pid) { 1715 num++; 1716 proc.lastPssTime = SystemClock.uptimeMillis(); 1717 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1718 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1719 + ": " + pss + " lastPss=" + proc.lastPss 1720 + " state=" + ProcessList.makeProcStateString(procState)); 1721 if (proc.initialIdlePss == 0) { 1722 proc.initialIdlePss = pss; 1723 } 1724 proc.lastPss = pss; 1725 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1726 proc.lastCachedPss = pss; 1727 } 1728 } 1729 } 1730 } 1731 } while (true); 1732 } 1733 } 1734 } 1735 }; 1736 1737 public void setSystemProcess() { 1738 try { 1739 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1740 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1741 ServiceManager.addService("meminfo", new MemBinder(this)); 1742 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1743 ServiceManager.addService("dbinfo", new DbBinder(this)); 1744 if (MONITOR_CPU_USAGE) { 1745 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1746 } 1747 ServiceManager.addService("permission", new PermissionController(this)); 1748 1749 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1750 "android", STOCK_PM_FLAGS); 1751 mSystemThread.installSystemApplicationInfo(info); 1752 1753 synchronized (this) { 1754 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1755 app.persistent = true; 1756 app.pid = MY_PID; 1757 app.maxAdj = ProcessList.SYSTEM_ADJ; 1758 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1759 mProcessNames.put(app.processName, app.uid, app); 1760 synchronized (mPidsSelfLocked) { 1761 mPidsSelfLocked.put(app.pid, app); 1762 } 1763 updateLruProcessLocked(app, false, null); 1764 updateOomAdjLocked(); 1765 } 1766 } catch (PackageManager.NameNotFoundException e) { 1767 throw new RuntimeException( 1768 "Unable to find android system package", e); 1769 } 1770 } 1771 1772 public void setWindowManager(WindowManagerService wm) { 1773 mWindowManager = wm; 1774 mStackSupervisor.setWindowManager(wm); 1775 } 1776 1777 public void startObservingNativeCrashes() { 1778 final NativeCrashListener ncl = new NativeCrashListener(this); 1779 ncl.start(); 1780 } 1781 1782 public IAppOpsService getAppOpsService() { 1783 return mAppOpsService; 1784 } 1785 1786 static class MemBinder extends Binder { 1787 ActivityManagerService mActivityManagerService; 1788 MemBinder(ActivityManagerService activityManagerService) { 1789 mActivityManagerService = activityManagerService; 1790 } 1791 1792 @Override 1793 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1794 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1795 != PackageManager.PERMISSION_GRANTED) { 1796 pw.println("Permission Denial: can't dump meminfo from from pid=" 1797 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1798 + " without permission " + android.Manifest.permission.DUMP); 1799 return; 1800 } 1801 1802 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1803 } 1804 } 1805 1806 static class GraphicsBinder extends Binder { 1807 ActivityManagerService mActivityManagerService; 1808 GraphicsBinder(ActivityManagerService activityManagerService) { 1809 mActivityManagerService = activityManagerService; 1810 } 1811 1812 @Override 1813 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1814 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1815 != PackageManager.PERMISSION_GRANTED) { 1816 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1817 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1818 + " without permission " + android.Manifest.permission.DUMP); 1819 return; 1820 } 1821 1822 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1823 } 1824 } 1825 1826 static class DbBinder extends Binder { 1827 ActivityManagerService mActivityManagerService; 1828 DbBinder(ActivityManagerService activityManagerService) { 1829 mActivityManagerService = activityManagerService; 1830 } 1831 1832 @Override 1833 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1834 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1835 != PackageManager.PERMISSION_GRANTED) { 1836 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1837 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1838 + " without permission " + android.Manifest.permission.DUMP); 1839 return; 1840 } 1841 1842 mActivityManagerService.dumpDbInfo(fd, pw, args); 1843 } 1844 } 1845 1846 static class CpuBinder extends Binder { 1847 ActivityManagerService mActivityManagerService; 1848 CpuBinder(ActivityManagerService activityManagerService) { 1849 mActivityManagerService = activityManagerService; 1850 } 1851 1852 @Override 1853 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1854 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1855 != PackageManager.PERMISSION_GRANTED) { 1856 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1857 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1858 + " without permission " + android.Manifest.permission.DUMP); 1859 return; 1860 } 1861 1862 synchronized (mActivityManagerService.mProcessCpuThread) { 1863 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1864 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1865 SystemClock.uptimeMillis())); 1866 } 1867 } 1868 } 1869 1870 public static class Lifecycle extends SystemService { 1871 private ActivityManagerService mService; 1872 1873 @Override 1874 public void onCreate(Context context) { 1875 mService = new ActivityManagerService(context); 1876 } 1877 1878 @Override 1879 public void onStart() { 1880 mService.start(); 1881 } 1882 1883 public ActivityManagerService getService() { 1884 return mService; 1885 } 1886 } 1887 1888 // Note: This method is invoked on the main thread but may need to attach various 1889 // handlers to other threads. So take care to be explicit about the looper. 1890 public ActivityManagerService(Context systemContext) { 1891 mContext = systemContext; 1892 mFactoryTest = FactoryTest.getMode(); 1893 mSystemThread = ActivityThread.currentActivityThread(); 1894 1895 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1896 1897 mHandlerThread = new ServiceThread(TAG, 1898 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1899 mHandlerThread.start(); 1900 mHandler = new MainHandler(mHandlerThread.getLooper()); 1901 1902 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1903 "foreground", BROADCAST_FG_TIMEOUT, false); 1904 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1905 "background", BROADCAST_BG_TIMEOUT, true); 1906 mBroadcastQueues[0] = mFgBroadcastQueue; 1907 mBroadcastQueues[1] = mBgBroadcastQueue; 1908 1909 mServices = new ActiveServices(this); 1910 mProviderMap = new ProviderMap(this); 1911 1912 // TODO: Move creation of battery stats service outside of activity manager service. 1913 File dataDir = Environment.getDataDirectory(); 1914 File systemDir = new File(dataDir, "system"); 1915 systemDir.mkdirs(); 1916 mBatteryStatsService = new BatteryStatsService(new File( 1917 systemDir, "batterystats.bin").toString(), mHandler); 1918 mBatteryStatsService.getActiveStatistics().readLocked(); 1919 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1920 mOnBattery = DEBUG_POWER ? true 1921 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1922 mBatteryStatsService.getActiveStatistics().setCallback(this); 1923 1924 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1925 1926 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1927 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1928 1929 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1930 1931 // User 0 is the first and only user that runs at boot. 1932 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1933 mUserLru.add(Integer.valueOf(0)); 1934 updateStartedUserArrayLocked(); 1935 1936 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1937 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1938 1939 mConfiguration.setToDefaults(); 1940 mConfiguration.setLocale(Locale.getDefault()); 1941 1942 mConfigurationSeq = mConfiguration.seq = 1; 1943 mProcessCpuTracker.init(); 1944 1945 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1946 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1947 mStackSupervisor = new ActivityStackSupervisor(this); 1948 1949 mProcessCpuThread = new Thread("CpuTracker") { 1950 @Override 1951 public void run() { 1952 while (true) { 1953 try { 1954 try { 1955 synchronized(this) { 1956 final long now = SystemClock.uptimeMillis(); 1957 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1958 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1959 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1960 // + ", write delay=" + nextWriteDelay); 1961 if (nextWriteDelay < nextCpuDelay) { 1962 nextCpuDelay = nextWriteDelay; 1963 } 1964 if (nextCpuDelay > 0) { 1965 mProcessCpuMutexFree.set(true); 1966 this.wait(nextCpuDelay); 1967 } 1968 } 1969 } catch (InterruptedException e) { 1970 } 1971 updateCpuStatsNow(); 1972 } catch (Exception e) { 1973 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1974 } 1975 } 1976 } 1977 }; 1978 1979 Watchdog.getInstance().addMonitor(this); 1980 Watchdog.getInstance().addThread(mHandler); 1981 } 1982 1983 private void start() { 1984 mProcessCpuThread.start(); 1985 1986 mBatteryStatsService.publish(mContext); 1987 mUsageStatsService.publish(mContext); 1988 mAppOpsService.publish(mContext); 1989 startRunning(null, null, null, null); 1990 } 1991 1992 @Override 1993 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1994 throws RemoteException { 1995 if (code == SYSPROPS_TRANSACTION) { 1996 // We need to tell all apps about the system property change. 1997 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1998 synchronized(this) { 1999 final int NP = mProcessNames.getMap().size(); 2000 for (int ip=0; ip<NP; ip++) { 2001 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2002 final int NA = apps.size(); 2003 for (int ia=0; ia<NA; ia++) { 2004 ProcessRecord app = apps.valueAt(ia); 2005 if (app.thread != null) { 2006 procs.add(app.thread.asBinder()); 2007 } 2008 } 2009 } 2010 } 2011 2012 int N = procs.size(); 2013 for (int i=0; i<N; i++) { 2014 Parcel data2 = Parcel.obtain(); 2015 try { 2016 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2017 } catch (RemoteException e) { 2018 } 2019 data2.recycle(); 2020 } 2021 } 2022 try { 2023 return super.onTransact(code, data, reply, flags); 2024 } catch (RuntimeException e) { 2025 // The activity manager only throws security exceptions, so let's 2026 // log all others. 2027 if (!(e instanceof SecurityException)) { 2028 Slog.wtf(TAG, "Activity Manager Crash", e); 2029 } 2030 throw e; 2031 } 2032 } 2033 2034 void updateCpuStats() { 2035 final long now = SystemClock.uptimeMillis(); 2036 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2037 return; 2038 } 2039 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2040 synchronized (mProcessCpuThread) { 2041 mProcessCpuThread.notify(); 2042 } 2043 } 2044 } 2045 2046 void updateCpuStatsNow() { 2047 synchronized (mProcessCpuThread) { 2048 mProcessCpuMutexFree.set(false); 2049 final long now = SystemClock.uptimeMillis(); 2050 boolean haveNewCpuStats = false; 2051 2052 if (MONITOR_CPU_USAGE && 2053 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2054 mLastCpuTime.set(now); 2055 haveNewCpuStats = true; 2056 mProcessCpuTracker.update(); 2057 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2058 //Slog.i(TAG, "Total CPU usage: " 2059 // + mProcessCpu.getTotalCpuPercent() + "%"); 2060 2061 // Slog the cpu usage if the property is set. 2062 if ("true".equals(SystemProperties.get("events.cpu"))) { 2063 int user = mProcessCpuTracker.getLastUserTime(); 2064 int system = mProcessCpuTracker.getLastSystemTime(); 2065 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2066 int irq = mProcessCpuTracker.getLastIrqTime(); 2067 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2068 int idle = mProcessCpuTracker.getLastIdleTime(); 2069 2070 int total = user + system + iowait + irq + softIrq + idle; 2071 if (total == 0) total = 1; 2072 2073 EventLog.writeEvent(EventLogTags.CPU, 2074 ((user+system+iowait+irq+softIrq) * 100) / total, 2075 (user * 100) / total, 2076 (system * 100) / total, 2077 (iowait * 100) / total, 2078 (irq * 100) / total, 2079 (softIrq * 100) / total); 2080 } 2081 } 2082 2083 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2084 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2085 synchronized(bstats) { 2086 synchronized(mPidsSelfLocked) { 2087 if (haveNewCpuStats) { 2088 if (mOnBattery) { 2089 int perc = bstats.startAddingCpuLocked(); 2090 int totalUTime = 0; 2091 int totalSTime = 0; 2092 final int N = mProcessCpuTracker.countStats(); 2093 for (int i=0; i<N; i++) { 2094 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2095 if (!st.working) { 2096 continue; 2097 } 2098 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2099 int otherUTime = (st.rel_utime*perc)/100; 2100 int otherSTime = (st.rel_stime*perc)/100; 2101 totalUTime += otherUTime; 2102 totalSTime += otherSTime; 2103 if (pr != null) { 2104 BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked( 2105 st.name, st.pid); 2106 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2107 st.rel_stime-otherSTime); 2108 ps.addSpeedStepTimes(cpuSpeedTimes); 2109 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2110 } else if (st.uid >= Process.FIRST_APPLICATION_UID) { 2111 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2112 if (ps == null) { 2113 st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid, 2114 "(Unknown)"); 2115 } 2116 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2117 st.rel_stime-otherSTime); 2118 ps.addSpeedStepTimes(cpuSpeedTimes); 2119 } else { 2120 BatteryStatsImpl.Uid.Proc ps = 2121 bstats.getProcessStatsLocked(st.name, st.pid); 2122 if (ps != null) { 2123 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2124 st.rel_stime-otherSTime); 2125 ps.addSpeedStepTimes(cpuSpeedTimes); 2126 } 2127 } 2128 } 2129 bstats.finishAddingCpuLocked(perc, totalUTime, 2130 totalSTime, cpuSpeedTimes); 2131 } 2132 } 2133 } 2134 2135 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2136 mLastWriteTime = now; 2137 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2138 } 2139 } 2140 } 2141 } 2142 2143 @Override 2144 public void batteryNeedsCpuUpdate() { 2145 updateCpuStatsNow(); 2146 } 2147 2148 @Override 2149 public void batteryPowerChanged(boolean onBattery) { 2150 // When plugging in, update the CPU stats first before changing 2151 // the plug state. 2152 updateCpuStatsNow(); 2153 synchronized (this) { 2154 synchronized(mPidsSelfLocked) { 2155 mOnBattery = DEBUG_POWER ? true : onBattery; 2156 } 2157 } 2158 } 2159 2160 /** 2161 * Initialize the application bind args. These are passed to each 2162 * process when the bindApplication() IPC is sent to the process. They're 2163 * lazily setup to make sure the services are running when they're asked for. 2164 */ 2165 private HashMap<String, IBinder> getCommonServicesLocked() { 2166 if (mAppBindArgs == null) { 2167 mAppBindArgs = new HashMap<String, IBinder>(); 2168 2169 // Setup the application init args 2170 mAppBindArgs.put("package", ServiceManager.getService("package")); 2171 mAppBindArgs.put("window", ServiceManager.getService("window")); 2172 mAppBindArgs.put(Context.ALARM_SERVICE, 2173 ServiceManager.getService(Context.ALARM_SERVICE)); 2174 } 2175 return mAppBindArgs; 2176 } 2177 2178 final void setFocusedActivityLocked(ActivityRecord r) { 2179 if (mFocusedActivity != r) { 2180 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2181 mFocusedActivity = r; 2182 mStackSupervisor.setFocusedStack(r); 2183 if (r != null) { 2184 mWindowManager.setFocusedApp(r.appToken, true); 2185 } 2186 applyUpdateLockStateLocked(r); 2187 } 2188 } 2189 2190 @Override 2191 public void setFocusedStack(int stackId) { 2192 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2193 synchronized (ActivityManagerService.this) { 2194 ActivityStack stack = mStackSupervisor.getStack(stackId); 2195 if (stack != null) { 2196 ActivityRecord r = stack.topRunningActivityLocked(null); 2197 if (r != null) { 2198 setFocusedActivityLocked(r); 2199 } 2200 } 2201 } 2202 } 2203 2204 @Override 2205 public void notifyActivityDrawn(IBinder token) { 2206 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2207 synchronized (this) { 2208 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2209 if (r != null) { 2210 r.task.stack.notifyActivityDrawnLocked(r); 2211 } 2212 } 2213 } 2214 2215 final void applyUpdateLockStateLocked(ActivityRecord r) { 2216 // Modifications to the UpdateLock state are done on our handler, outside 2217 // the activity manager's locks. The new state is determined based on the 2218 // state *now* of the relevant activity record. The object is passed to 2219 // the handler solely for logging detail, not to be consulted/modified. 2220 final boolean nextState = r != null && r.immersive; 2221 mHandler.sendMessage( 2222 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2223 } 2224 2225 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2226 Message msg = Message.obtain(); 2227 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2228 msg.obj = r.task.askedCompatMode ? null : r; 2229 mHandler.sendMessage(msg); 2230 } 2231 2232 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2233 String what, Object obj, ProcessRecord srcApp) { 2234 app.lastActivityTime = now; 2235 2236 if (app.activities.size() > 0) { 2237 // Don't want to touch dependent processes that are hosting activities. 2238 return index; 2239 } 2240 2241 int lrui = mLruProcesses.lastIndexOf(app); 2242 if (lrui < 0) { 2243 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2244 + what + " " + obj + " from " + srcApp); 2245 return index; 2246 } 2247 2248 if (lrui >= index) { 2249 // Don't want to cause this to move dependent processes *back* in the 2250 // list as if they were less frequently used. 2251 return index; 2252 } 2253 2254 if (lrui >= mLruProcessActivityStart) { 2255 // Don't want to touch dependent processes that are hosting activities. 2256 return index; 2257 } 2258 2259 mLruProcesses.remove(lrui); 2260 if (index > 0) { 2261 index--; 2262 } 2263 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2264 + " in LRU list: " + app); 2265 mLruProcesses.add(index, app); 2266 return index; 2267 } 2268 2269 final void removeLruProcessLocked(ProcessRecord app) { 2270 int lrui = mLruProcesses.lastIndexOf(app); 2271 if (lrui >= 0) { 2272 if (lrui <= mLruProcessActivityStart) { 2273 mLruProcessActivityStart--; 2274 } 2275 if (lrui <= mLruProcessServiceStart) { 2276 mLruProcessServiceStart--; 2277 } 2278 mLruProcesses.remove(lrui); 2279 } 2280 } 2281 2282 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2283 ProcessRecord client) { 2284 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities; 2285 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2286 if (!activityChange && hasActivity) { 2287 // The process has activties, so we are only going to allow activity-based 2288 // adjustments move it. It should be kept in the front of the list with other 2289 // processes that have activities, and we don't want those to change their 2290 // order except due to activity operations. 2291 return; 2292 } 2293 2294 mLruSeq++; 2295 final long now = SystemClock.uptimeMillis(); 2296 app.lastActivityTime = now; 2297 2298 // First a quick reject: if the app is already at the position we will 2299 // put it, then there is nothing to do. 2300 if (hasActivity) { 2301 final int N = mLruProcesses.size(); 2302 if (N > 0 && mLruProcesses.get(N-1) == app) { 2303 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2304 return; 2305 } 2306 } else { 2307 if (mLruProcessServiceStart > 0 2308 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2309 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2310 return; 2311 } 2312 } 2313 2314 int lrui = mLruProcesses.lastIndexOf(app); 2315 2316 if (app.persistent && lrui >= 0) { 2317 // We don't care about the position of persistent processes, as long as 2318 // they are in the list. 2319 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2320 return; 2321 } 2322 2323 /* In progress: compute new position first, so we can avoid doing work 2324 if the process is not actually going to move. Not yet working. 2325 int addIndex; 2326 int nextIndex; 2327 boolean inActivity = false, inService = false; 2328 if (hasActivity) { 2329 // Process has activities, put it at the very tipsy-top. 2330 addIndex = mLruProcesses.size(); 2331 nextIndex = mLruProcessServiceStart; 2332 inActivity = true; 2333 } else if (hasService) { 2334 // Process has services, put it at the top of the service list. 2335 addIndex = mLruProcessActivityStart; 2336 nextIndex = mLruProcessServiceStart; 2337 inActivity = true; 2338 inService = true; 2339 } else { 2340 // Process not otherwise of interest, it goes to the top of the non-service area. 2341 addIndex = mLruProcessServiceStart; 2342 if (client != null) { 2343 int clientIndex = mLruProcesses.lastIndexOf(client); 2344 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2345 + app); 2346 if (clientIndex >= 0 && addIndex > clientIndex) { 2347 addIndex = clientIndex; 2348 } 2349 } 2350 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2351 } 2352 2353 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2354 + mLruProcessActivityStart + "): " + app); 2355 */ 2356 2357 if (lrui >= 0) { 2358 if (lrui < mLruProcessActivityStart) { 2359 mLruProcessActivityStart--; 2360 } 2361 if (lrui < mLruProcessServiceStart) { 2362 mLruProcessServiceStart--; 2363 } 2364 /* 2365 if (addIndex > lrui) { 2366 addIndex--; 2367 } 2368 if (nextIndex > lrui) { 2369 nextIndex--; 2370 } 2371 */ 2372 mLruProcesses.remove(lrui); 2373 } 2374 2375 /* 2376 mLruProcesses.add(addIndex, app); 2377 if (inActivity) { 2378 mLruProcessActivityStart++; 2379 } 2380 if (inService) { 2381 mLruProcessActivityStart++; 2382 } 2383 */ 2384 2385 int nextIndex; 2386 if (hasActivity) { 2387 final int N = mLruProcesses.size(); 2388 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2389 // Process doesn't have activities, but has clients with 2390 // activities... move it up, but one below the top (the top 2391 // should always have a real activity). 2392 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2393 mLruProcesses.add(N-1, app); 2394 // To keep it from spamming the LRU list (by making a bunch of clients), 2395 // we will push down any other entries owned by the app. 2396 final int uid = app.info.uid; 2397 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2398 ProcessRecord subProc = mLruProcesses.get(i); 2399 if (subProc.info.uid == uid) { 2400 // We want to push this one down the list. If the process after 2401 // it is for the same uid, however, don't do so, because we don't 2402 // want them internally to be re-ordered. 2403 if (mLruProcesses.get(i-1).info.uid != uid) { 2404 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2405 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2406 ProcessRecord tmp = mLruProcesses.get(i); 2407 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2408 mLruProcesses.set(i-1, tmp); 2409 i--; 2410 } 2411 } else { 2412 // A gap, we can stop here. 2413 break; 2414 } 2415 } 2416 } else { 2417 // Process has activities, put it at the very tipsy-top. 2418 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2419 mLruProcesses.add(app); 2420 } 2421 nextIndex = mLruProcessServiceStart; 2422 } else if (hasService) { 2423 // Process has services, put it at the top of the service list. 2424 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2425 mLruProcesses.add(mLruProcessActivityStart, app); 2426 nextIndex = mLruProcessServiceStart; 2427 mLruProcessActivityStart++; 2428 } else { 2429 // Process not otherwise of interest, it goes to the top of the non-service area. 2430 int index = mLruProcessServiceStart; 2431 if (client != null) { 2432 // If there is a client, don't allow the process to be moved up higher 2433 // in the list than that client. 2434 int clientIndex = mLruProcesses.lastIndexOf(client); 2435 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2436 + " when updating " + app); 2437 if (clientIndex <= lrui) { 2438 // Don't allow the client index restriction to push it down farther in the 2439 // list than it already is. 2440 clientIndex = lrui; 2441 } 2442 if (clientIndex >= 0 && index > clientIndex) { 2443 index = clientIndex; 2444 } 2445 } 2446 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2447 mLruProcesses.add(index, app); 2448 nextIndex = index-1; 2449 mLruProcessActivityStart++; 2450 mLruProcessServiceStart++; 2451 } 2452 2453 // If the app is currently using a content provider or service, 2454 // bump those processes as well. 2455 for (int j=app.connections.size()-1; j>=0; j--) { 2456 ConnectionRecord cr = app.connections.valueAt(j); 2457 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2458 && cr.binding.service.app != null 2459 && cr.binding.service.app.lruSeq != mLruSeq 2460 && !cr.binding.service.app.persistent) { 2461 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2462 "service connection", cr, app); 2463 } 2464 } 2465 for (int j=app.conProviders.size()-1; j>=0; j--) { 2466 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2467 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2468 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2469 "provider reference", cpr, app); 2470 } 2471 } 2472 } 2473 2474 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2475 if (uid == Process.SYSTEM_UID) { 2476 // The system gets to run in any process. If there are multiple 2477 // processes with the same uid, just pick the first (this 2478 // should never happen). 2479 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2480 if (procs == null) return null; 2481 final int N = procs.size(); 2482 for (int i = 0; i < N; i++) { 2483 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2484 } 2485 } 2486 ProcessRecord proc = mProcessNames.get(processName, uid); 2487 if (false && proc != null && !keepIfLarge 2488 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2489 && proc.lastCachedPss >= 4000) { 2490 // Turn this condition on to cause killing to happen regularly, for testing. 2491 if (proc.baseProcessTracker != null) { 2492 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2493 } 2494 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2495 + "k from cached"); 2496 } else if (proc != null && !keepIfLarge 2497 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2498 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2499 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2500 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2501 if (proc.baseProcessTracker != null) { 2502 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2503 } 2504 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2505 + "k from cached"); 2506 } 2507 } 2508 return proc; 2509 } 2510 2511 void ensurePackageDexOpt(String packageName) { 2512 IPackageManager pm = AppGlobals.getPackageManager(); 2513 try { 2514 if (pm.performDexOpt(packageName)) { 2515 mDidDexOpt = true; 2516 } 2517 } catch (RemoteException e) { 2518 } 2519 } 2520 2521 boolean isNextTransitionForward() { 2522 int transit = mWindowManager.getPendingAppTransition(); 2523 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2524 || transit == AppTransition.TRANSIT_TASK_OPEN 2525 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2526 } 2527 2528 final ProcessRecord startProcessLocked(String processName, 2529 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2530 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2531 boolean isolated, boolean keepIfLarge) { 2532 ProcessRecord app; 2533 if (!isolated) { 2534 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2535 } else { 2536 // If this is an isolated process, it can't re-use an existing process. 2537 app = null; 2538 } 2539 // We don't have to do anything more if: 2540 // (1) There is an existing application record; and 2541 // (2) The caller doesn't think it is dead, OR there is no thread 2542 // object attached to it so we know it couldn't have crashed; and 2543 // (3) There is a pid assigned to it, so it is either starting or 2544 // already running. 2545 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2546 + " app=" + app + " knownToBeDead=" + knownToBeDead 2547 + " thread=" + (app != null ? app.thread : null) 2548 + " pid=" + (app != null ? app.pid : -1)); 2549 if (app != null && app.pid > 0) { 2550 if (!knownToBeDead || app.thread == null) { 2551 // We already have the app running, or are waiting for it to 2552 // come up (we have a pid but not yet its thread), so keep it. 2553 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2554 // If this is a new package in the process, add the package to the list 2555 app.addPackage(info.packageName, mProcessStats); 2556 return app; 2557 } 2558 2559 // An application record is attached to a previous process, 2560 // clean it up now. 2561 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2562 handleAppDiedLocked(app, true, true); 2563 } 2564 2565 String hostingNameStr = hostingName != null 2566 ? hostingName.flattenToShortString() : null; 2567 2568 if (!isolated) { 2569 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2570 // If we are in the background, then check to see if this process 2571 // is bad. If so, we will just silently fail. 2572 if (mBadProcesses.get(info.processName, info.uid) != null) { 2573 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2574 + "/" + info.processName); 2575 return null; 2576 } 2577 } else { 2578 // When the user is explicitly starting a process, then clear its 2579 // crash count so that we won't make it bad until they see at 2580 // least one crash dialog again, and make the process good again 2581 // if it had been bad. 2582 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2583 + "/" + info.processName); 2584 mProcessCrashTimes.remove(info.processName, info.uid); 2585 if (mBadProcesses.get(info.processName, info.uid) != null) { 2586 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2587 UserHandle.getUserId(info.uid), info.uid, 2588 info.processName); 2589 mBadProcesses.remove(info.processName, info.uid); 2590 if (app != null) { 2591 app.bad = false; 2592 } 2593 } 2594 } 2595 } 2596 2597 if (app == null) { 2598 app = newProcessRecordLocked(info, processName, isolated); 2599 if (app == null) { 2600 Slog.w(TAG, "Failed making new process record for " 2601 + processName + "/" + info.uid + " isolated=" + isolated); 2602 return null; 2603 } 2604 mProcessNames.put(processName, app.uid, app); 2605 if (isolated) { 2606 mIsolatedProcesses.put(app.uid, app); 2607 } 2608 } else { 2609 // If this is a new package in the process, add the package to the list 2610 app.addPackage(info.packageName, mProcessStats); 2611 } 2612 2613 // If the system is not ready yet, then hold off on starting this 2614 // process until it is. 2615 if (!mProcessesReady 2616 && !isAllowedWhileBooting(info) 2617 && !allowWhileBooting) { 2618 if (!mProcessesOnHold.contains(app)) { 2619 mProcessesOnHold.add(app); 2620 } 2621 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2622 return app; 2623 } 2624 2625 startProcessLocked(app, hostingType, hostingNameStr); 2626 return (app.pid != 0) ? app : null; 2627 } 2628 2629 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2630 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2631 } 2632 2633 private final void startProcessLocked(ProcessRecord app, 2634 String hostingType, String hostingNameStr) { 2635 if (app.pid > 0 && app.pid != MY_PID) { 2636 synchronized (mPidsSelfLocked) { 2637 mPidsSelfLocked.remove(app.pid); 2638 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2639 } 2640 app.setPid(0); 2641 } 2642 2643 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2644 "startProcessLocked removing on hold: " + app); 2645 mProcessesOnHold.remove(app); 2646 2647 updateCpuStats(); 2648 2649 try { 2650 int uid = app.uid; 2651 2652 int[] gids = null; 2653 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2654 if (!app.isolated) { 2655 int[] permGids = null; 2656 try { 2657 final PackageManager pm = mContext.getPackageManager(); 2658 permGids = pm.getPackageGids(app.info.packageName); 2659 2660 if (Environment.isExternalStorageEmulated()) { 2661 if (pm.checkPermission( 2662 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2663 app.info.packageName) == PERMISSION_GRANTED) { 2664 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2665 } else { 2666 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2667 } 2668 } 2669 } catch (PackageManager.NameNotFoundException e) { 2670 Slog.w(TAG, "Unable to retrieve gids", e); 2671 } 2672 2673 /* 2674 * Add shared application GID so applications can share some 2675 * resources like shared libraries 2676 */ 2677 if (permGids == null) { 2678 gids = new int[1]; 2679 } else { 2680 gids = new int[permGids.length + 1]; 2681 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2682 } 2683 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2684 } 2685 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2686 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2687 && mTopComponent != null 2688 && app.processName.equals(mTopComponent.getPackageName())) { 2689 uid = 0; 2690 } 2691 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2692 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2693 uid = 0; 2694 } 2695 } 2696 int debugFlags = 0; 2697 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2698 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2699 // Also turn on CheckJNI for debuggable apps. It's quite 2700 // awkward to turn on otherwise. 2701 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2702 } 2703 // Run the app in safe mode if its manifest requests so or the 2704 // system is booted in safe mode. 2705 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2706 Zygote.systemInSafeMode == true) { 2707 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2708 } 2709 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2710 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2711 } 2712 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2713 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2714 } 2715 if ("1".equals(SystemProperties.get("debug.assert"))) { 2716 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2717 } 2718 2719 // Start the process. It will either succeed and return a result containing 2720 // the PID of the new process, or else throw a RuntimeException. 2721 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2722 app.processName, uid, uid, gids, debugFlags, mountExternal, 2723 app.info.targetSdkVersion, app.info.seinfo, null); 2724 2725 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2726 synchronized (bs) { 2727 if (bs.isOnBattery()) { 2728 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2729 } 2730 } 2731 2732 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2733 UserHandle.getUserId(uid), startResult.pid, uid, 2734 app.processName, hostingType, 2735 hostingNameStr != null ? hostingNameStr : ""); 2736 2737 if (app.persistent) { 2738 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2739 } 2740 2741 StringBuilder buf = mStringBuilder; 2742 buf.setLength(0); 2743 buf.append("Start proc "); 2744 buf.append(app.processName); 2745 buf.append(" for "); 2746 buf.append(hostingType); 2747 if (hostingNameStr != null) { 2748 buf.append(" "); 2749 buf.append(hostingNameStr); 2750 } 2751 buf.append(": pid="); 2752 buf.append(startResult.pid); 2753 buf.append(" uid="); 2754 buf.append(uid); 2755 buf.append(" gids={"); 2756 if (gids != null) { 2757 for (int gi=0; gi<gids.length; gi++) { 2758 if (gi != 0) buf.append(", "); 2759 buf.append(gids[gi]); 2760 2761 } 2762 } 2763 buf.append("}"); 2764 Slog.i(TAG, buf.toString()); 2765 app.setPid(startResult.pid); 2766 app.usingWrapper = startResult.usingWrapper; 2767 app.removed = false; 2768 synchronized (mPidsSelfLocked) { 2769 this.mPidsSelfLocked.put(startResult.pid, app); 2770 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2771 msg.obj = app; 2772 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2773 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2774 } 2775 } catch (RuntimeException e) { 2776 // XXX do better error recovery. 2777 app.setPid(0); 2778 Slog.e(TAG, "Failure starting process " + app.processName, e); 2779 } 2780 } 2781 2782 void updateUsageStats(ActivityRecord component, boolean resumed) { 2783 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2784 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2785 if (resumed) { 2786 mUsageStatsService.noteResumeComponent(component.realActivity); 2787 synchronized (stats) { 2788 stats.noteActivityResumedLocked(component.app.uid); 2789 } 2790 } else { 2791 mUsageStatsService.notePauseComponent(component.realActivity); 2792 synchronized (stats) { 2793 stats.noteActivityPausedLocked(component.app.uid); 2794 } 2795 } 2796 } 2797 2798 Intent getHomeIntent() { 2799 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2800 intent.setComponent(mTopComponent); 2801 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2802 intent.addCategory(Intent.CATEGORY_HOME); 2803 } 2804 return intent; 2805 } 2806 2807 boolean startHomeActivityLocked(int userId) { 2808 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2809 && mTopAction == null) { 2810 // We are running in factory test mode, but unable to find 2811 // the factory test app, so just sit around displaying the 2812 // error message and don't try to start anything. 2813 return false; 2814 } 2815 Intent intent = getHomeIntent(); 2816 ActivityInfo aInfo = 2817 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2818 if (aInfo != null) { 2819 intent.setComponent(new ComponentName( 2820 aInfo.applicationInfo.packageName, aInfo.name)); 2821 // Don't do this if the home app is currently being 2822 // instrumented. 2823 aInfo = new ActivityInfo(aInfo); 2824 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2825 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2826 aInfo.applicationInfo.uid, true); 2827 if (app == null || app.instrumentationClass == null) { 2828 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2829 mStackSupervisor.startHomeActivity(intent, aInfo); 2830 } 2831 } 2832 2833 return true; 2834 } 2835 2836 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2837 ActivityInfo ai = null; 2838 ComponentName comp = intent.getComponent(); 2839 try { 2840 if (comp != null) { 2841 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2842 } else { 2843 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2844 intent, 2845 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2846 flags, userId); 2847 2848 if (info != null) { 2849 ai = info.activityInfo; 2850 } 2851 } 2852 } catch (RemoteException e) { 2853 // ignore 2854 } 2855 2856 return ai; 2857 } 2858 2859 /** 2860 * Starts the "new version setup screen" if appropriate. 2861 */ 2862 void startSetupActivityLocked() { 2863 // Only do this once per boot. 2864 if (mCheckedForSetup) { 2865 return; 2866 } 2867 2868 // We will show this screen if the current one is a different 2869 // version than the last one shown, and we are not running in 2870 // low-level factory test mode. 2871 final ContentResolver resolver = mContext.getContentResolver(); 2872 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2873 Settings.Global.getInt(resolver, 2874 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2875 mCheckedForSetup = true; 2876 2877 // See if we should be showing the platform update setup UI. 2878 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2879 List<ResolveInfo> ris = mContext.getPackageManager() 2880 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2881 2882 // We don't allow third party apps to replace this. 2883 ResolveInfo ri = null; 2884 for (int i=0; ris != null && i<ris.size(); i++) { 2885 if ((ris.get(i).activityInfo.applicationInfo.flags 2886 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2887 ri = ris.get(i); 2888 break; 2889 } 2890 } 2891 2892 if (ri != null) { 2893 String vers = ri.activityInfo.metaData != null 2894 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2895 : null; 2896 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2897 vers = ri.activityInfo.applicationInfo.metaData.getString( 2898 Intent.METADATA_SETUP_VERSION); 2899 } 2900 String lastVers = Settings.Secure.getString( 2901 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2902 if (vers != null && !vers.equals(lastVers)) { 2903 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2904 intent.setComponent(new ComponentName( 2905 ri.activityInfo.packageName, ri.activityInfo.name)); 2906 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2907 null, null, 0, 0, 0, null, 0, null, false, null, null); 2908 } 2909 } 2910 } 2911 } 2912 2913 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2914 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2915 } 2916 2917 void enforceNotIsolatedCaller(String caller) { 2918 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2919 throw new SecurityException("Isolated process not allowed to call " + caller); 2920 } 2921 } 2922 2923 @Override 2924 public int getFrontActivityScreenCompatMode() { 2925 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2926 synchronized (this) { 2927 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2928 } 2929 } 2930 2931 @Override 2932 public void setFrontActivityScreenCompatMode(int mode) { 2933 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2934 "setFrontActivityScreenCompatMode"); 2935 synchronized (this) { 2936 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2937 } 2938 } 2939 2940 @Override 2941 public int getPackageScreenCompatMode(String packageName) { 2942 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2943 synchronized (this) { 2944 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2945 } 2946 } 2947 2948 @Override 2949 public void setPackageScreenCompatMode(String packageName, int mode) { 2950 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2951 "setPackageScreenCompatMode"); 2952 synchronized (this) { 2953 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2954 } 2955 } 2956 2957 @Override 2958 public boolean getPackageAskScreenCompat(String packageName) { 2959 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2960 synchronized (this) { 2961 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2962 } 2963 } 2964 2965 @Override 2966 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2967 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2968 "setPackageAskScreenCompat"); 2969 synchronized (this) { 2970 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2971 } 2972 } 2973 2974 private void dispatchProcessesChanged() { 2975 int N; 2976 synchronized (this) { 2977 N = mPendingProcessChanges.size(); 2978 if (mActiveProcessChanges.length < N) { 2979 mActiveProcessChanges = new ProcessChangeItem[N]; 2980 } 2981 mPendingProcessChanges.toArray(mActiveProcessChanges); 2982 mAvailProcessChanges.addAll(mPendingProcessChanges); 2983 mPendingProcessChanges.clear(); 2984 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2985 } 2986 2987 int i = mProcessObservers.beginBroadcast(); 2988 while (i > 0) { 2989 i--; 2990 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2991 if (observer != null) { 2992 try { 2993 for (int j=0; j<N; j++) { 2994 ProcessChangeItem item = mActiveProcessChanges[j]; 2995 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2996 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2997 + item.pid + " uid=" + item.uid + ": " 2998 + item.foregroundActivities); 2999 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3000 item.foregroundActivities); 3001 } 3002 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3003 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3004 + item.pid + " uid=" + item.uid + ": " + item.importance); 3005 observer.onImportanceChanged(item.pid, item.uid, 3006 item.importance); 3007 } 3008 } 3009 } catch (RemoteException e) { 3010 } 3011 } 3012 } 3013 mProcessObservers.finishBroadcast(); 3014 } 3015 3016 private void dispatchProcessDied(int pid, int uid) { 3017 int i = mProcessObservers.beginBroadcast(); 3018 while (i > 0) { 3019 i--; 3020 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3021 if (observer != null) { 3022 try { 3023 observer.onProcessDied(pid, uid); 3024 } catch (RemoteException e) { 3025 } 3026 } 3027 } 3028 mProcessObservers.finishBroadcast(); 3029 } 3030 3031 final void doPendingActivityLaunchesLocked(boolean doResume) { 3032 final int N = mPendingActivityLaunches.size(); 3033 if (N <= 0) { 3034 return; 3035 } 3036 for (int i=0; i<N; i++) { 3037 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3038 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3039 doResume && i == (N-1), null); 3040 } 3041 mPendingActivityLaunches.clear(); 3042 } 3043 3044 @Override 3045 public final int startActivity(IApplicationThread caller, String callingPackage, 3046 Intent intent, String resolvedType, IBinder resultTo, 3047 String resultWho, int requestCode, int startFlags, 3048 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3049 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3050 resultWho, requestCode, 3051 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3052 } 3053 3054 @Override 3055 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3056 Intent intent, String resolvedType, IBinder resultTo, 3057 String resultWho, int requestCode, int startFlags, 3058 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3059 enforceNotIsolatedCaller("startActivity"); 3060 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3061 false, true, "startActivity", null); 3062 // TODO: Switch to user app stacks here. 3063 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3064 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3065 null, null, options, userId, null); 3066 } 3067 3068 @Override 3069 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3070 Intent intent, String resolvedType, IBinder resultTo, 3071 String resultWho, int requestCode, int startFlags, String profileFile, 3072 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3073 enforceNotIsolatedCaller("startActivityAndWait"); 3074 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3075 false, true, "startActivityAndWait", null); 3076 WaitResult res = new WaitResult(); 3077 // TODO: Switch to user app stacks here. 3078 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3079 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3080 res, null, options, UserHandle.getCallingUserId(), null); 3081 return res; 3082 } 3083 3084 @Override 3085 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3086 Intent intent, String resolvedType, IBinder resultTo, 3087 String resultWho, int requestCode, int startFlags, Configuration config, 3088 Bundle options, int userId) { 3089 enforceNotIsolatedCaller("startActivityWithConfig"); 3090 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3091 false, true, "startActivityWithConfig", null); 3092 // TODO: Switch to user app stacks here. 3093 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3094 resolvedType, resultTo, resultWho, requestCode, startFlags, 3095 null, null, null, config, options, userId, null); 3096 return ret; 3097 } 3098 3099 @Override 3100 public int startActivityIntentSender(IApplicationThread caller, 3101 IntentSender intent, Intent fillInIntent, String resolvedType, 3102 IBinder resultTo, String resultWho, int requestCode, 3103 int flagsMask, int flagsValues, Bundle options) { 3104 enforceNotIsolatedCaller("startActivityIntentSender"); 3105 // Refuse possible leaked file descriptors 3106 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3107 throw new IllegalArgumentException("File descriptors passed in Intent"); 3108 } 3109 3110 IIntentSender sender = intent.getTarget(); 3111 if (!(sender instanceof PendingIntentRecord)) { 3112 throw new IllegalArgumentException("Bad PendingIntent object"); 3113 } 3114 3115 PendingIntentRecord pir = (PendingIntentRecord)sender; 3116 3117 synchronized (this) { 3118 // If this is coming from the currently resumed activity, it is 3119 // effectively saying that app switches are allowed at this point. 3120 final ActivityStack stack = getFocusedStack(); 3121 if (stack.mResumedActivity != null && 3122 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3123 mAppSwitchesAllowedTime = 0; 3124 } 3125 } 3126 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3127 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3128 return ret; 3129 } 3130 3131 @Override 3132 public boolean startNextMatchingActivity(IBinder callingActivity, 3133 Intent intent, Bundle options) { 3134 // Refuse possible leaked file descriptors 3135 if (intent != null && intent.hasFileDescriptors() == true) { 3136 throw new IllegalArgumentException("File descriptors passed in Intent"); 3137 } 3138 3139 synchronized (this) { 3140 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3141 if (r == null) { 3142 ActivityOptions.abort(options); 3143 return false; 3144 } 3145 if (r.app == null || r.app.thread == null) { 3146 // The caller is not running... d'oh! 3147 ActivityOptions.abort(options); 3148 return false; 3149 } 3150 intent = new Intent(intent); 3151 // The caller is not allowed to change the data. 3152 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3153 // And we are resetting to find the next component... 3154 intent.setComponent(null); 3155 3156 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3157 3158 ActivityInfo aInfo = null; 3159 try { 3160 List<ResolveInfo> resolves = 3161 AppGlobals.getPackageManager().queryIntentActivities( 3162 intent, r.resolvedType, 3163 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3164 UserHandle.getCallingUserId()); 3165 3166 // Look for the original activity in the list... 3167 final int N = resolves != null ? resolves.size() : 0; 3168 for (int i=0; i<N; i++) { 3169 ResolveInfo rInfo = resolves.get(i); 3170 if (rInfo.activityInfo.packageName.equals(r.packageName) 3171 && rInfo.activityInfo.name.equals(r.info.name)) { 3172 // We found the current one... the next matching is 3173 // after it. 3174 i++; 3175 if (i<N) { 3176 aInfo = resolves.get(i).activityInfo; 3177 } 3178 if (debug) { 3179 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3180 + "/" + r.info.name); 3181 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3182 + "/" + aInfo.name); 3183 } 3184 break; 3185 } 3186 } 3187 } catch (RemoteException e) { 3188 } 3189 3190 if (aInfo == null) { 3191 // Nobody who is next! 3192 ActivityOptions.abort(options); 3193 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3194 return false; 3195 } 3196 3197 intent.setComponent(new ComponentName( 3198 aInfo.applicationInfo.packageName, aInfo.name)); 3199 intent.setFlags(intent.getFlags()&~( 3200 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3201 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3202 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3203 Intent.FLAG_ACTIVITY_NEW_TASK)); 3204 3205 // Okay now we need to start the new activity, replacing the 3206 // currently running activity. This is a little tricky because 3207 // we want to start the new one as if the current one is finished, 3208 // but not finish the current one first so that there is no flicker. 3209 // And thus... 3210 final boolean wasFinishing = r.finishing; 3211 r.finishing = true; 3212 3213 // Propagate reply information over to the new activity. 3214 final ActivityRecord resultTo = r.resultTo; 3215 final String resultWho = r.resultWho; 3216 final int requestCode = r.requestCode; 3217 r.resultTo = null; 3218 if (resultTo != null) { 3219 resultTo.removeResultsLocked(r, resultWho, requestCode); 3220 } 3221 3222 final long origId = Binder.clearCallingIdentity(); 3223 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3224 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3225 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3226 options, false, null, null); 3227 Binder.restoreCallingIdentity(origId); 3228 3229 r.finishing = wasFinishing; 3230 if (res != ActivityManager.START_SUCCESS) { 3231 return false; 3232 } 3233 return true; 3234 } 3235 } 3236 3237 final int startActivityInPackage(int uid, String callingPackage, 3238 Intent intent, String resolvedType, IBinder resultTo, 3239 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3240 IActivityContainer container) { 3241 3242 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3243 false, true, "startActivityInPackage", null); 3244 3245 // TODO: Switch to user app stacks here. 3246 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3247 resultTo, resultWho, requestCode, startFlags, 3248 null, null, null, null, options, userId, container); 3249 return ret; 3250 } 3251 3252 @Override 3253 public final int startActivities(IApplicationThread caller, String callingPackage, 3254 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3255 int userId) { 3256 enforceNotIsolatedCaller("startActivities"); 3257 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3258 false, true, "startActivity", null); 3259 // TODO: Switch to user app stacks here. 3260 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3261 resolvedTypes, resultTo, options, userId); 3262 return ret; 3263 } 3264 3265 final int startActivitiesInPackage(int uid, String callingPackage, 3266 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3267 Bundle options, int userId) { 3268 3269 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3270 false, true, "startActivityInPackage", null); 3271 // TODO: Switch to user app stacks here. 3272 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3273 resultTo, options, userId); 3274 return ret; 3275 } 3276 3277 final void addRecentTaskLocked(TaskRecord task) { 3278 int N = mRecentTasks.size(); 3279 // Quick case: check if the top-most recent task is the same. 3280 if (N > 0 && mRecentTasks.get(0) == task) { 3281 return; 3282 } 3283 // Remove any existing entries that are the same kind of task. 3284 for (int i=0; i<N; i++) { 3285 TaskRecord tr = mRecentTasks.get(i); 3286 if (task.userId == tr.userId 3287 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 3288 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 3289 tr.disposeThumbnail(); 3290 mRecentTasks.remove(i); 3291 i--; 3292 N--; 3293 if (task.intent == null) { 3294 // If the new recent task we are adding is not fully 3295 // specified, then replace it with the existing recent task. 3296 task = tr; 3297 } 3298 } 3299 } 3300 if (N >= MAX_RECENT_TASKS) { 3301 mRecentTasks.remove(N-1).disposeThumbnail(); 3302 } 3303 mRecentTasks.add(0, task); 3304 } 3305 3306 @Override 3307 public void reportActivityFullyDrawn(IBinder token) { 3308 synchronized (this) { 3309 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3310 if (r == null) { 3311 return; 3312 } 3313 r.reportFullyDrawnLocked(); 3314 } 3315 } 3316 3317 @Override 3318 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3319 synchronized (this) { 3320 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3321 if (r == null) { 3322 return; 3323 } 3324 final long origId = Binder.clearCallingIdentity(); 3325 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3326 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3327 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3328 if (config != null) { 3329 r.frozenBeforeDestroy = true; 3330 if (!updateConfigurationLocked(config, r, false, false)) { 3331 mStackSupervisor.resumeTopActivitiesLocked(); 3332 } 3333 } 3334 Binder.restoreCallingIdentity(origId); 3335 } 3336 } 3337 3338 @Override 3339 public int getRequestedOrientation(IBinder token) { 3340 synchronized (this) { 3341 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3342 if (r == null) { 3343 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3344 } 3345 return mWindowManager.getAppOrientation(r.appToken); 3346 } 3347 } 3348 3349 /** 3350 * This is the internal entry point for handling Activity.finish(). 3351 * 3352 * @param token The Binder token referencing the Activity we want to finish. 3353 * @param resultCode Result code, if any, from this Activity. 3354 * @param resultData Result data (Intent), if any, from this Activity. 3355 * 3356 * @return Returns true if the activity successfully finished, or false if it is still running. 3357 */ 3358 @Override 3359 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3360 // Refuse possible leaked file descriptors 3361 if (resultData != null && resultData.hasFileDescriptors() == true) { 3362 throw new IllegalArgumentException("File descriptors passed in Intent"); 3363 } 3364 3365 synchronized(this) { 3366 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3367 if (r == null) { 3368 return true; 3369 } 3370 if (mController != null) { 3371 // Find the first activity that is not finishing. 3372 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3373 if (next != null) { 3374 // ask watcher if this is allowed 3375 boolean resumeOK = true; 3376 try { 3377 resumeOK = mController.activityResuming(next.packageName); 3378 } catch (RemoteException e) { 3379 mController = null; 3380 Watchdog.getInstance().setActivityController(null); 3381 } 3382 3383 if (!resumeOK) { 3384 return false; 3385 } 3386 } 3387 } 3388 final long origId = Binder.clearCallingIdentity(); 3389 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3390 resultData, "app-request", true); 3391 Binder.restoreCallingIdentity(origId); 3392 return res; 3393 } 3394 } 3395 3396 @Override 3397 public final void finishHeavyWeightApp() { 3398 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3399 != PackageManager.PERMISSION_GRANTED) { 3400 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3401 + Binder.getCallingPid() 3402 + ", uid=" + Binder.getCallingUid() 3403 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3404 Slog.w(TAG, msg); 3405 throw new SecurityException(msg); 3406 } 3407 3408 synchronized(this) { 3409 if (mHeavyWeightProcess == null) { 3410 return; 3411 } 3412 3413 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3414 mHeavyWeightProcess.activities); 3415 for (int i=0; i<activities.size(); i++) { 3416 ActivityRecord r = activities.get(i); 3417 if (!r.finishing) { 3418 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3419 null, "finish-heavy", true); 3420 } 3421 } 3422 3423 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3424 mHeavyWeightProcess.userId, 0)); 3425 mHeavyWeightProcess = null; 3426 } 3427 } 3428 3429 @Override 3430 public void crashApplication(int uid, int initialPid, String packageName, 3431 String message) { 3432 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3433 != PackageManager.PERMISSION_GRANTED) { 3434 String msg = "Permission Denial: crashApplication() from pid=" 3435 + Binder.getCallingPid() 3436 + ", uid=" + Binder.getCallingUid() 3437 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3438 Slog.w(TAG, msg); 3439 throw new SecurityException(msg); 3440 } 3441 3442 synchronized(this) { 3443 ProcessRecord proc = null; 3444 3445 // Figure out which process to kill. We don't trust that initialPid 3446 // still has any relation to current pids, so must scan through the 3447 // list. 3448 synchronized (mPidsSelfLocked) { 3449 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3450 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3451 if (p.uid != uid) { 3452 continue; 3453 } 3454 if (p.pid == initialPid) { 3455 proc = p; 3456 break; 3457 } 3458 if (p.pkgList.containsKey(packageName)) { 3459 proc = p; 3460 } 3461 } 3462 } 3463 3464 if (proc == null) { 3465 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3466 + " initialPid=" + initialPid 3467 + " packageName=" + packageName); 3468 return; 3469 } 3470 3471 if (proc.thread != null) { 3472 if (proc.pid == Process.myPid()) { 3473 Log.w(TAG, "crashApplication: trying to crash self!"); 3474 return; 3475 } 3476 long ident = Binder.clearCallingIdentity(); 3477 try { 3478 proc.thread.scheduleCrash(message); 3479 } catch (RemoteException e) { 3480 } 3481 Binder.restoreCallingIdentity(ident); 3482 } 3483 } 3484 } 3485 3486 @Override 3487 public final void finishSubActivity(IBinder token, String resultWho, 3488 int requestCode) { 3489 synchronized(this) { 3490 final long origId = Binder.clearCallingIdentity(); 3491 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3492 if (r != null) { 3493 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3494 } 3495 Binder.restoreCallingIdentity(origId); 3496 } 3497 } 3498 3499 @Override 3500 public boolean finishActivityAffinity(IBinder token) { 3501 synchronized(this) { 3502 final long origId = Binder.clearCallingIdentity(); 3503 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3504 boolean res = false; 3505 if (r != null) { 3506 res = r.task.stack.finishActivityAffinityLocked(r); 3507 } 3508 Binder.restoreCallingIdentity(origId); 3509 return res; 3510 } 3511 } 3512 3513 @Override 3514 public boolean willActivityBeVisible(IBinder token) { 3515 synchronized(this) { 3516 ActivityStack stack = ActivityRecord.getStackLocked(token); 3517 if (stack != null) { 3518 return stack.willActivityBeVisibleLocked(token); 3519 } 3520 return false; 3521 } 3522 } 3523 3524 @Override 3525 public void overridePendingTransition(IBinder token, String packageName, 3526 int enterAnim, int exitAnim) { 3527 synchronized(this) { 3528 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3529 if (self == null) { 3530 return; 3531 } 3532 3533 final long origId = Binder.clearCallingIdentity(); 3534 3535 if (self.state == ActivityState.RESUMED 3536 || self.state == ActivityState.PAUSING) { 3537 mWindowManager.overridePendingAppTransition(packageName, 3538 enterAnim, exitAnim, null); 3539 } 3540 3541 Binder.restoreCallingIdentity(origId); 3542 } 3543 } 3544 3545 /** 3546 * Main function for removing an existing process from the activity manager 3547 * as a result of that process going away. Clears out all connections 3548 * to the process. 3549 */ 3550 private final void handleAppDiedLocked(ProcessRecord app, 3551 boolean restarting, boolean allowRestart) { 3552 int pid = app.pid; 3553 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3554 if (!restarting) { 3555 removeLruProcessLocked(app); 3556 if (pid > 0) { 3557 ProcessList.remove(pid); 3558 } 3559 } 3560 3561 if (mProfileProc == app) { 3562 clearProfilerLocked(); 3563 } 3564 3565 // Remove this application's activities from active lists. 3566 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3567 3568 app.activities.clear(); 3569 3570 if (app.instrumentationClass != null) { 3571 Slog.w(TAG, "Crash of app " + app.processName 3572 + " running instrumentation " + app.instrumentationClass); 3573 Bundle info = new Bundle(); 3574 info.putString("shortMsg", "Process crashed."); 3575 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3576 } 3577 3578 if (!restarting) { 3579 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3580 // If there was nothing to resume, and we are not already 3581 // restarting this process, but there is a visible activity that 3582 // is hosted by the process... then make sure all visible 3583 // activities are running, taking care of restarting this 3584 // process. 3585 if (hasVisibleActivities) { 3586 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3587 } 3588 } 3589 } 3590 } 3591 3592 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3593 IBinder threadBinder = thread.asBinder(); 3594 // Find the application record. 3595 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3596 ProcessRecord rec = mLruProcesses.get(i); 3597 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3598 return i; 3599 } 3600 } 3601 return -1; 3602 } 3603 3604 final ProcessRecord getRecordForAppLocked( 3605 IApplicationThread thread) { 3606 if (thread == null) { 3607 return null; 3608 } 3609 3610 int appIndex = getLRURecordIndexForAppLocked(thread); 3611 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3612 } 3613 3614 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3615 // If there are no longer any background processes running, 3616 // and the app that died was not running instrumentation, 3617 // then tell everyone we are now low on memory. 3618 boolean haveBg = false; 3619 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3620 ProcessRecord rec = mLruProcesses.get(i); 3621 if (rec.thread != null 3622 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3623 haveBg = true; 3624 break; 3625 } 3626 } 3627 3628 if (!haveBg) { 3629 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3630 if (doReport) { 3631 long now = SystemClock.uptimeMillis(); 3632 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3633 doReport = false; 3634 } else { 3635 mLastMemUsageReportTime = now; 3636 } 3637 } 3638 final ArrayList<ProcessMemInfo> memInfos 3639 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3640 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3641 long now = SystemClock.uptimeMillis(); 3642 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3643 ProcessRecord rec = mLruProcesses.get(i); 3644 if (rec == dyingProc || rec.thread == null) { 3645 continue; 3646 } 3647 if (doReport) { 3648 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3649 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3650 } 3651 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3652 // The low memory report is overriding any current 3653 // state for a GC request. Make sure to do 3654 // heavy/important/visible/foreground processes first. 3655 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3656 rec.lastRequestedGc = 0; 3657 } else { 3658 rec.lastRequestedGc = rec.lastLowMemory; 3659 } 3660 rec.reportLowMemory = true; 3661 rec.lastLowMemory = now; 3662 mProcessesToGc.remove(rec); 3663 addProcessToGcListLocked(rec); 3664 } 3665 } 3666 if (doReport) { 3667 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3668 mHandler.sendMessage(msg); 3669 } 3670 scheduleAppGcsLocked(); 3671 } 3672 } 3673 3674 final void appDiedLocked(ProcessRecord app, int pid, 3675 IApplicationThread thread) { 3676 3677 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3678 synchronized (stats) { 3679 stats.noteProcessDiedLocked(app.info.uid, pid); 3680 } 3681 3682 // Clean up already done if the process has been re-started. 3683 if (app.pid == pid && app.thread != null && 3684 app.thread.asBinder() == thread.asBinder()) { 3685 boolean doLowMem = app.instrumentationClass == null; 3686 boolean doOomAdj = doLowMem; 3687 if (!app.killedByAm) { 3688 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3689 + ") has died."); 3690 mAllowLowerMemLevel = true; 3691 } else { 3692 // Note that we always want to do oom adj to update our state with the 3693 // new number of procs. 3694 mAllowLowerMemLevel = false; 3695 doLowMem = false; 3696 } 3697 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3698 if (DEBUG_CLEANUP) Slog.v( 3699 TAG, "Dying app: " + app + ", pid: " + pid 3700 + ", thread: " + thread.asBinder()); 3701 handleAppDiedLocked(app, false, true); 3702 3703 if (doOomAdj) { 3704 updateOomAdjLocked(); 3705 } 3706 if (doLowMem) { 3707 doLowMemReportIfNeededLocked(app); 3708 } 3709 } else if (app.pid != pid) { 3710 // A new process has already been started. 3711 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3712 + ") has died and restarted (pid " + app.pid + ")."); 3713 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3714 } else if (DEBUG_PROCESSES) { 3715 Slog.d(TAG, "Received spurious death notification for thread " 3716 + thread.asBinder()); 3717 } 3718 } 3719 3720 /** 3721 * If a stack trace dump file is configured, dump process stack traces. 3722 * @param clearTraces causes the dump file to be erased prior to the new 3723 * traces being written, if true; when false, the new traces will be 3724 * appended to any existing file content. 3725 * @param firstPids of dalvik VM processes to dump stack traces for first 3726 * @param lastPids of dalvik VM processes to dump stack traces for last 3727 * @param nativeProcs optional list of native process names to dump stack crawls 3728 * @return file containing stack traces, or null if no dump file is configured 3729 */ 3730 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3731 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3732 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3733 if (tracesPath == null || tracesPath.length() == 0) { 3734 return null; 3735 } 3736 3737 File tracesFile = new File(tracesPath); 3738 try { 3739 File tracesDir = tracesFile.getParentFile(); 3740 if (!tracesDir.exists()) { 3741 tracesFile.mkdirs(); 3742 if (!SELinux.restorecon(tracesDir)) { 3743 return null; 3744 } 3745 } 3746 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3747 3748 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3749 tracesFile.createNewFile(); 3750 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3751 } catch (IOException e) { 3752 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3753 return null; 3754 } 3755 3756 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3757 return tracesFile; 3758 } 3759 3760 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3761 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3762 // Use a FileObserver to detect when traces finish writing. 3763 // The order of traces is considered important to maintain for legibility. 3764 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3765 @Override 3766 public synchronized void onEvent(int event, String path) { notify(); } 3767 }; 3768 3769 try { 3770 observer.startWatching(); 3771 3772 // First collect all of the stacks of the most important pids. 3773 if (firstPids != null) { 3774 try { 3775 int num = firstPids.size(); 3776 for (int i = 0; i < num; i++) { 3777 synchronized (observer) { 3778 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3779 observer.wait(200); // Wait for write-close, give up after 200msec 3780 } 3781 } 3782 } catch (InterruptedException e) { 3783 Log.wtf(TAG, e); 3784 } 3785 } 3786 3787 // Next collect the stacks of the native pids 3788 if (nativeProcs != null) { 3789 int[] pids = Process.getPidsForCommands(nativeProcs); 3790 if (pids != null) { 3791 for (int pid : pids) { 3792 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3793 } 3794 } 3795 } 3796 3797 // Lastly, measure CPU usage. 3798 if (processCpuTracker != null) { 3799 processCpuTracker.init(); 3800 System.gc(); 3801 processCpuTracker.update(); 3802 try { 3803 synchronized (processCpuTracker) { 3804 processCpuTracker.wait(500); // measure over 1/2 second. 3805 } 3806 } catch (InterruptedException e) { 3807 } 3808 processCpuTracker.update(); 3809 3810 // We'll take the stack crawls of just the top apps using CPU. 3811 final int N = processCpuTracker.countWorkingStats(); 3812 int numProcs = 0; 3813 for (int i=0; i<N && numProcs<5; i++) { 3814 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3815 if (lastPids.indexOfKey(stats.pid) >= 0) { 3816 numProcs++; 3817 try { 3818 synchronized (observer) { 3819 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3820 observer.wait(200); // Wait for write-close, give up after 200msec 3821 } 3822 } catch (InterruptedException e) { 3823 Log.wtf(TAG, e); 3824 } 3825 3826 } 3827 } 3828 } 3829 } finally { 3830 observer.stopWatching(); 3831 } 3832 } 3833 3834 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3835 if (true || IS_USER_BUILD) { 3836 return; 3837 } 3838 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3839 if (tracesPath == null || tracesPath.length() == 0) { 3840 return; 3841 } 3842 3843 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3844 StrictMode.allowThreadDiskWrites(); 3845 try { 3846 final File tracesFile = new File(tracesPath); 3847 final File tracesDir = tracesFile.getParentFile(); 3848 final File tracesTmp = new File(tracesDir, "__tmp__"); 3849 try { 3850 if (!tracesDir.exists()) { 3851 tracesFile.mkdirs(); 3852 if (!SELinux.restorecon(tracesDir.getPath())) { 3853 return; 3854 } 3855 } 3856 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3857 3858 if (tracesFile.exists()) { 3859 tracesTmp.delete(); 3860 tracesFile.renameTo(tracesTmp); 3861 } 3862 StringBuilder sb = new StringBuilder(); 3863 Time tobj = new Time(); 3864 tobj.set(System.currentTimeMillis()); 3865 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3866 sb.append(": "); 3867 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3868 sb.append(" since "); 3869 sb.append(msg); 3870 FileOutputStream fos = new FileOutputStream(tracesFile); 3871 fos.write(sb.toString().getBytes()); 3872 if (app == null) { 3873 fos.write("\n*** No application process!".getBytes()); 3874 } 3875 fos.close(); 3876 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3877 } catch (IOException e) { 3878 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3879 return; 3880 } 3881 3882 if (app != null) { 3883 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3884 firstPids.add(app.pid); 3885 dumpStackTraces(tracesPath, firstPids, null, null, null); 3886 } 3887 3888 File lastTracesFile = null; 3889 File curTracesFile = null; 3890 for (int i=9; i>=0; i--) { 3891 String name = String.format(Locale.US, "slow%02d.txt", i); 3892 curTracesFile = new File(tracesDir, name); 3893 if (curTracesFile.exists()) { 3894 if (lastTracesFile != null) { 3895 curTracesFile.renameTo(lastTracesFile); 3896 } else { 3897 curTracesFile.delete(); 3898 } 3899 } 3900 lastTracesFile = curTracesFile; 3901 } 3902 tracesFile.renameTo(curTracesFile); 3903 if (tracesTmp.exists()) { 3904 tracesTmp.renameTo(tracesFile); 3905 } 3906 } finally { 3907 StrictMode.setThreadPolicy(oldPolicy); 3908 } 3909 } 3910 3911 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3912 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3913 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3914 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3915 3916 if (mController != null) { 3917 try { 3918 // 0 == continue, -1 = kill process immediately 3919 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3920 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3921 } catch (RemoteException e) { 3922 mController = null; 3923 Watchdog.getInstance().setActivityController(null); 3924 } 3925 } 3926 3927 long anrTime = SystemClock.uptimeMillis(); 3928 if (MONITOR_CPU_USAGE) { 3929 updateCpuStatsNow(); 3930 } 3931 3932 synchronized (this) { 3933 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3934 if (mShuttingDown) { 3935 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3936 return; 3937 } else if (app.notResponding) { 3938 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3939 return; 3940 } else if (app.crashing) { 3941 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3942 return; 3943 } 3944 3945 // In case we come through here for the same app before completing 3946 // this one, mark as anring now so we will bail out. 3947 app.notResponding = true; 3948 3949 // Log the ANR to the event log. 3950 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3951 app.processName, app.info.flags, annotation); 3952 3953 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3954 firstPids.add(app.pid); 3955 3956 int parentPid = app.pid; 3957 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3958 if (parentPid != app.pid) firstPids.add(parentPid); 3959 3960 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3961 3962 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3963 ProcessRecord r = mLruProcesses.get(i); 3964 if (r != null && r.thread != null) { 3965 int pid = r.pid; 3966 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3967 if (r.persistent) { 3968 firstPids.add(pid); 3969 } else { 3970 lastPids.put(pid, Boolean.TRUE); 3971 } 3972 } 3973 } 3974 } 3975 } 3976 3977 // Log the ANR to the main log. 3978 StringBuilder info = new StringBuilder(); 3979 info.setLength(0); 3980 info.append("ANR in ").append(app.processName); 3981 if (activity != null && activity.shortComponentName != null) { 3982 info.append(" (").append(activity.shortComponentName).append(")"); 3983 } 3984 info.append("\n"); 3985 info.append("PID: ").append(app.pid).append("\n"); 3986 if (annotation != null) { 3987 info.append("Reason: ").append(annotation).append("\n"); 3988 } 3989 if (parent != null && parent != activity) { 3990 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3991 } 3992 3993 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 3994 3995 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 3996 NATIVE_STACKS_OF_INTEREST); 3997 3998 String cpuInfo = null; 3999 if (MONITOR_CPU_USAGE) { 4000 updateCpuStatsNow(); 4001 synchronized (mProcessCpuThread) { 4002 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4003 } 4004 info.append(processCpuTracker.printCurrentLoad()); 4005 info.append(cpuInfo); 4006 } 4007 4008 info.append(processCpuTracker.printCurrentState(anrTime)); 4009 4010 Slog.e(TAG, info.toString()); 4011 if (tracesFile == null) { 4012 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4013 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4014 } 4015 4016 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4017 cpuInfo, tracesFile, null); 4018 4019 if (mController != null) { 4020 try { 4021 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4022 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4023 if (res != 0) { 4024 if (res < 0 && app.pid != MY_PID) { 4025 Process.killProcess(app.pid); 4026 } else { 4027 synchronized (this) { 4028 mServices.scheduleServiceTimeoutLocked(app); 4029 } 4030 } 4031 return; 4032 } 4033 } catch (RemoteException e) { 4034 mController = null; 4035 Watchdog.getInstance().setActivityController(null); 4036 } 4037 } 4038 4039 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4040 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4041 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4042 4043 synchronized (this) { 4044 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4045 killUnneededProcessLocked(app, "background ANR"); 4046 return; 4047 } 4048 4049 // Set the app's notResponding state, and look up the errorReportReceiver 4050 makeAppNotRespondingLocked(app, 4051 activity != null ? activity.shortComponentName : null, 4052 annotation != null ? "ANR " + annotation : "ANR", 4053 info.toString()); 4054 4055 // Bring up the infamous App Not Responding dialog 4056 Message msg = Message.obtain(); 4057 HashMap<String, Object> map = new HashMap<String, Object>(); 4058 msg.what = SHOW_NOT_RESPONDING_MSG; 4059 msg.obj = map; 4060 msg.arg1 = aboveSystem ? 1 : 0; 4061 map.put("app", app); 4062 if (activity != null) { 4063 map.put("activity", activity); 4064 } 4065 4066 mHandler.sendMessage(msg); 4067 } 4068 } 4069 4070 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4071 if (!mLaunchWarningShown) { 4072 mLaunchWarningShown = true; 4073 mHandler.post(new Runnable() { 4074 @Override 4075 public void run() { 4076 synchronized (ActivityManagerService.this) { 4077 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4078 d.show(); 4079 mHandler.postDelayed(new Runnable() { 4080 @Override 4081 public void run() { 4082 synchronized (ActivityManagerService.this) { 4083 d.dismiss(); 4084 mLaunchWarningShown = false; 4085 } 4086 } 4087 }, 4000); 4088 } 4089 } 4090 }); 4091 } 4092 } 4093 4094 @Override 4095 public boolean clearApplicationUserData(final String packageName, 4096 final IPackageDataObserver observer, int userId) { 4097 enforceNotIsolatedCaller("clearApplicationUserData"); 4098 int uid = Binder.getCallingUid(); 4099 int pid = Binder.getCallingPid(); 4100 userId = handleIncomingUser(pid, uid, 4101 userId, false, true, "clearApplicationUserData", null); 4102 long callingId = Binder.clearCallingIdentity(); 4103 try { 4104 IPackageManager pm = AppGlobals.getPackageManager(); 4105 int pkgUid = -1; 4106 synchronized(this) { 4107 try { 4108 pkgUid = pm.getPackageUid(packageName, userId); 4109 } catch (RemoteException e) { 4110 } 4111 if (pkgUid == -1) { 4112 Slog.w(TAG, "Invalid packageName: " + packageName); 4113 if (observer != null) { 4114 try { 4115 observer.onRemoveCompleted(packageName, false); 4116 } catch (RemoteException e) { 4117 Slog.i(TAG, "Observer no longer exists."); 4118 } 4119 } 4120 return false; 4121 } 4122 if (uid == pkgUid || checkComponentPermission( 4123 android.Manifest.permission.CLEAR_APP_USER_DATA, 4124 pid, uid, -1, true) 4125 == PackageManager.PERMISSION_GRANTED) { 4126 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4127 } else { 4128 throw new SecurityException("PID " + pid + " does not have permission " 4129 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4130 + " of package " + packageName); 4131 } 4132 } 4133 4134 try { 4135 // Clear application user data 4136 pm.clearApplicationUserData(packageName, observer, userId); 4137 4138 // Remove all permissions granted from/to this package 4139 removeUriPermissionsForPackageLocked(packageName, userId, true); 4140 4141 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4142 Uri.fromParts("package", packageName, null)); 4143 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4144 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4145 null, null, 0, null, null, null, false, false, userId); 4146 } catch (RemoteException e) { 4147 } 4148 } finally { 4149 Binder.restoreCallingIdentity(callingId); 4150 } 4151 return true; 4152 } 4153 4154 @Override 4155 public void killBackgroundProcesses(final String packageName, int userId) { 4156 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4157 != PackageManager.PERMISSION_GRANTED && 4158 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4159 != PackageManager.PERMISSION_GRANTED) { 4160 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4161 + Binder.getCallingPid() 4162 + ", uid=" + Binder.getCallingUid() 4163 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4164 Slog.w(TAG, msg); 4165 throw new SecurityException(msg); 4166 } 4167 4168 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4169 userId, true, true, "killBackgroundProcesses", null); 4170 long callingId = Binder.clearCallingIdentity(); 4171 try { 4172 IPackageManager pm = AppGlobals.getPackageManager(); 4173 synchronized(this) { 4174 int appId = -1; 4175 try { 4176 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4177 } catch (RemoteException e) { 4178 } 4179 if (appId == -1) { 4180 Slog.w(TAG, "Invalid packageName: " + packageName); 4181 return; 4182 } 4183 killPackageProcessesLocked(packageName, appId, userId, 4184 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4185 } 4186 } finally { 4187 Binder.restoreCallingIdentity(callingId); 4188 } 4189 } 4190 4191 @Override 4192 public void killAllBackgroundProcesses() { 4193 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4194 != PackageManager.PERMISSION_GRANTED) { 4195 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4196 + Binder.getCallingPid() 4197 + ", uid=" + Binder.getCallingUid() 4198 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4199 Slog.w(TAG, msg); 4200 throw new SecurityException(msg); 4201 } 4202 4203 long callingId = Binder.clearCallingIdentity(); 4204 try { 4205 synchronized(this) { 4206 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4207 final int NP = mProcessNames.getMap().size(); 4208 for (int ip=0; ip<NP; ip++) { 4209 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4210 final int NA = apps.size(); 4211 for (int ia=0; ia<NA; ia++) { 4212 ProcessRecord app = apps.valueAt(ia); 4213 if (app.persistent) { 4214 // we don't kill persistent processes 4215 continue; 4216 } 4217 if (app.removed) { 4218 procs.add(app); 4219 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4220 app.removed = true; 4221 procs.add(app); 4222 } 4223 } 4224 } 4225 4226 int N = procs.size(); 4227 for (int i=0; i<N; i++) { 4228 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4229 } 4230 mAllowLowerMemLevel = true; 4231 updateOomAdjLocked(); 4232 doLowMemReportIfNeededLocked(null); 4233 } 4234 } finally { 4235 Binder.restoreCallingIdentity(callingId); 4236 } 4237 } 4238 4239 @Override 4240 public void forceStopPackage(final String packageName, int userId) { 4241 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4242 != PackageManager.PERMISSION_GRANTED) { 4243 String msg = "Permission Denial: forceStopPackage() from pid=" 4244 + Binder.getCallingPid() 4245 + ", uid=" + Binder.getCallingUid() 4246 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4247 Slog.w(TAG, msg); 4248 throw new SecurityException(msg); 4249 } 4250 final int callingPid = Binder.getCallingPid(); 4251 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4252 userId, true, true, "forceStopPackage", null); 4253 long callingId = Binder.clearCallingIdentity(); 4254 try { 4255 IPackageManager pm = AppGlobals.getPackageManager(); 4256 synchronized(this) { 4257 int[] users = userId == UserHandle.USER_ALL 4258 ? getUsersLocked() : new int[] { userId }; 4259 for (int user : users) { 4260 int pkgUid = -1; 4261 try { 4262 pkgUid = pm.getPackageUid(packageName, user); 4263 } catch (RemoteException e) { 4264 } 4265 if (pkgUid == -1) { 4266 Slog.w(TAG, "Invalid packageName: " + packageName); 4267 continue; 4268 } 4269 try { 4270 pm.setPackageStoppedState(packageName, true, user); 4271 } catch (RemoteException e) { 4272 } catch (IllegalArgumentException e) { 4273 Slog.w(TAG, "Failed trying to unstop package " 4274 + packageName + ": " + e); 4275 } 4276 if (isUserRunningLocked(user, false)) { 4277 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4278 } 4279 } 4280 } 4281 } finally { 4282 Binder.restoreCallingIdentity(callingId); 4283 } 4284 } 4285 4286 /* 4287 * The pkg name and app id have to be specified. 4288 */ 4289 @Override 4290 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4291 if (pkg == null) { 4292 return; 4293 } 4294 // Make sure the uid is valid. 4295 if (appid < 0) { 4296 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4297 return; 4298 } 4299 int callerUid = Binder.getCallingUid(); 4300 // Only the system server can kill an application 4301 if (callerUid == Process.SYSTEM_UID) { 4302 // Post an aysnc message to kill the application 4303 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4304 msg.arg1 = appid; 4305 msg.arg2 = 0; 4306 Bundle bundle = new Bundle(); 4307 bundle.putString("pkg", pkg); 4308 bundle.putString("reason", reason); 4309 msg.obj = bundle; 4310 mHandler.sendMessage(msg); 4311 } else { 4312 throw new SecurityException(callerUid + " cannot kill pkg: " + 4313 pkg); 4314 } 4315 } 4316 4317 @Override 4318 public void closeSystemDialogs(String reason) { 4319 enforceNotIsolatedCaller("closeSystemDialogs"); 4320 4321 final int pid = Binder.getCallingPid(); 4322 final int uid = Binder.getCallingUid(); 4323 final long origId = Binder.clearCallingIdentity(); 4324 try { 4325 synchronized (this) { 4326 // Only allow this from foreground processes, so that background 4327 // applications can't abuse it to prevent system UI from being shown. 4328 if (uid >= Process.FIRST_APPLICATION_UID) { 4329 ProcessRecord proc; 4330 synchronized (mPidsSelfLocked) { 4331 proc = mPidsSelfLocked.get(pid); 4332 } 4333 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4334 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4335 + " from background process " + proc); 4336 return; 4337 } 4338 } 4339 closeSystemDialogsLocked(reason); 4340 } 4341 } finally { 4342 Binder.restoreCallingIdentity(origId); 4343 } 4344 } 4345 4346 void closeSystemDialogsLocked(String reason) { 4347 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4348 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4349 | Intent.FLAG_RECEIVER_FOREGROUND); 4350 if (reason != null) { 4351 intent.putExtra("reason", reason); 4352 } 4353 mWindowManager.closeSystemDialogs(reason); 4354 4355 mStackSupervisor.closeSystemDialogsLocked(); 4356 4357 broadcastIntentLocked(null, null, intent, null, 4358 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4359 Process.SYSTEM_UID, UserHandle.USER_ALL); 4360 } 4361 4362 @Override 4363 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4364 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4365 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4366 for (int i=pids.length-1; i>=0; i--) { 4367 ProcessRecord proc; 4368 int oomAdj; 4369 synchronized (this) { 4370 synchronized (mPidsSelfLocked) { 4371 proc = mPidsSelfLocked.get(pids[i]); 4372 oomAdj = proc != null ? proc.setAdj : 0; 4373 } 4374 } 4375 infos[i] = new Debug.MemoryInfo(); 4376 Debug.getMemoryInfo(pids[i], infos[i]); 4377 if (proc != null) { 4378 synchronized (this) { 4379 if (proc.thread != null && proc.setAdj == oomAdj) { 4380 // Record this for posterity if the process has been stable. 4381 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4382 infos[i].getTotalUss(), false, proc.pkgList); 4383 } 4384 } 4385 } 4386 } 4387 return infos; 4388 } 4389 4390 @Override 4391 public long[] getProcessPss(int[] pids) { 4392 enforceNotIsolatedCaller("getProcessPss"); 4393 long[] pss = new long[pids.length]; 4394 for (int i=pids.length-1; i>=0; i--) { 4395 ProcessRecord proc; 4396 int oomAdj; 4397 synchronized (this) { 4398 synchronized (mPidsSelfLocked) { 4399 proc = mPidsSelfLocked.get(pids[i]); 4400 oomAdj = proc != null ? proc.setAdj : 0; 4401 } 4402 } 4403 long[] tmpUss = new long[1]; 4404 pss[i] = Debug.getPss(pids[i], tmpUss); 4405 if (proc != null) { 4406 synchronized (this) { 4407 if (proc.thread != null && proc.setAdj == oomAdj) { 4408 // Record this for posterity if the process has been stable. 4409 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4410 } 4411 } 4412 } 4413 } 4414 return pss; 4415 } 4416 4417 @Override 4418 public void killApplicationProcess(String processName, int uid) { 4419 if (processName == null) { 4420 return; 4421 } 4422 4423 int callerUid = Binder.getCallingUid(); 4424 // Only the system server can kill an application 4425 if (callerUid == Process.SYSTEM_UID) { 4426 synchronized (this) { 4427 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4428 if (app != null && app.thread != null) { 4429 try { 4430 app.thread.scheduleSuicide(); 4431 } catch (RemoteException e) { 4432 // If the other end already died, then our work here is done. 4433 } 4434 } else { 4435 Slog.w(TAG, "Process/uid not found attempting kill of " 4436 + processName + " / " + uid); 4437 } 4438 } 4439 } else { 4440 throw new SecurityException(callerUid + " cannot kill app process: " + 4441 processName); 4442 } 4443 } 4444 4445 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4446 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4447 false, true, false, UserHandle.getUserId(uid), reason); 4448 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4449 Uri.fromParts("package", packageName, null)); 4450 if (!mProcessesReady) { 4451 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4452 | Intent.FLAG_RECEIVER_FOREGROUND); 4453 } 4454 intent.putExtra(Intent.EXTRA_UID, uid); 4455 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4456 broadcastIntentLocked(null, null, intent, 4457 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4458 false, false, 4459 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4460 } 4461 4462 private void forceStopUserLocked(int userId, String reason) { 4463 forceStopPackageLocked(null, -1, false, false, true, false, userId, reason); 4464 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4465 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4466 | Intent.FLAG_RECEIVER_FOREGROUND); 4467 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4468 broadcastIntentLocked(null, null, intent, 4469 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4470 false, false, 4471 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4472 } 4473 4474 private final boolean killPackageProcessesLocked(String packageName, int appId, 4475 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4476 boolean doit, boolean evenPersistent, String reason) { 4477 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4478 4479 // Remove all processes this package may have touched: all with the 4480 // same UID (except for the system or root user), and all whose name 4481 // matches the package name. 4482 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4483 final int NP = mProcessNames.getMap().size(); 4484 for (int ip=0; ip<NP; ip++) { 4485 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4486 final int NA = apps.size(); 4487 for (int ia=0; ia<NA; ia++) { 4488 ProcessRecord app = apps.valueAt(ia); 4489 if (app.persistent && !evenPersistent) { 4490 // we don't kill persistent processes 4491 continue; 4492 } 4493 if (app.removed) { 4494 if (doit) { 4495 procs.add(app); 4496 } 4497 continue; 4498 } 4499 4500 // Skip process if it doesn't meet our oom adj requirement. 4501 if (app.setAdj < minOomAdj) { 4502 continue; 4503 } 4504 4505 // If no package is specified, we call all processes under the 4506 // give user id. 4507 if (packageName == null) { 4508 if (app.userId != userId) { 4509 continue; 4510 } 4511 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4512 continue; 4513 } 4514 // Package has been specified, we want to hit all processes 4515 // that match it. We need to qualify this by the processes 4516 // that are running under the specified app and user ID. 4517 } else { 4518 if (UserHandle.getAppId(app.uid) != appId) { 4519 continue; 4520 } 4521 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4522 continue; 4523 } 4524 if (!app.pkgList.containsKey(packageName)) { 4525 continue; 4526 } 4527 } 4528 4529 // Process has passed all conditions, kill it! 4530 if (!doit) { 4531 return true; 4532 } 4533 app.removed = true; 4534 procs.add(app); 4535 } 4536 } 4537 4538 int N = procs.size(); 4539 for (int i=0; i<N; i++) { 4540 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4541 } 4542 updateOomAdjLocked(); 4543 return N > 0; 4544 } 4545 4546 private final boolean forceStopPackageLocked(String name, int appId, 4547 boolean callerWillRestart, boolean purgeCache, boolean doit, 4548 boolean evenPersistent, int userId, String reason) { 4549 int i; 4550 int N; 4551 4552 if (userId == UserHandle.USER_ALL && name == null) { 4553 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4554 } 4555 4556 if (appId < 0 && name != null) { 4557 try { 4558 appId = UserHandle.getAppId( 4559 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4560 } catch (RemoteException e) { 4561 } 4562 } 4563 4564 if (doit) { 4565 if (name != null) { 4566 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4567 + " user=" + userId + ": " + reason); 4568 } else { 4569 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4570 } 4571 4572 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4573 for (int ip=pmap.size()-1; ip>=0; ip--) { 4574 SparseArray<Long> ba = pmap.valueAt(ip); 4575 for (i=ba.size()-1; i>=0; i--) { 4576 boolean remove = false; 4577 final int entUid = ba.keyAt(i); 4578 if (name != null) { 4579 if (userId == UserHandle.USER_ALL) { 4580 if (UserHandle.getAppId(entUid) == appId) { 4581 remove = true; 4582 } 4583 } else { 4584 if (entUid == UserHandle.getUid(userId, appId)) { 4585 remove = true; 4586 } 4587 } 4588 } else if (UserHandle.getUserId(entUid) == userId) { 4589 remove = true; 4590 } 4591 if (remove) { 4592 ba.removeAt(i); 4593 } 4594 } 4595 if (ba.size() == 0) { 4596 pmap.removeAt(ip); 4597 } 4598 } 4599 } 4600 4601 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4602 -100, callerWillRestart, true, doit, evenPersistent, 4603 name == null ? ("stop user " + userId) : ("stop " + name)); 4604 4605 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4606 if (!doit) { 4607 return true; 4608 } 4609 didSomething = true; 4610 } 4611 4612 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4613 if (!doit) { 4614 return true; 4615 } 4616 didSomething = true; 4617 } 4618 4619 if (name == null) { 4620 // Remove all sticky broadcasts from this user. 4621 mStickyBroadcasts.remove(userId); 4622 } 4623 4624 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4625 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4626 userId, providers)) { 4627 if (!doit) { 4628 return true; 4629 } 4630 didSomething = true; 4631 } 4632 N = providers.size(); 4633 for (i=0; i<N; i++) { 4634 removeDyingProviderLocked(null, providers.get(i), true); 4635 } 4636 4637 // Remove transient permissions granted from/to this package/user 4638 removeUriPermissionsForPackageLocked(name, userId, false); 4639 4640 if (name == null) { 4641 // Remove pending intents. For now we only do this when force 4642 // stopping users, because we have some problems when doing this 4643 // for packages -- app widgets are not currently cleaned up for 4644 // such packages, so they can be left with bad pending intents. 4645 if (mIntentSenderRecords.size() > 0) { 4646 Iterator<WeakReference<PendingIntentRecord>> it 4647 = mIntentSenderRecords.values().iterator(); 4648 while (it.hasNext()) { 4649 WeakReference<PendingIntentRecord> wpir = it.next(); 4650 if (wpir == null) { 4651 it.remove(); 4652 continue; 4653 } 4654 PendingIntentRecord pir = wpir.get(); 4655 if (pir == null) { 4656 it.remove(); 4657 continue; 4658 } 4659 if (name == null) { 4660 // Stopping user, remove all objects for the user. 4661 if (pir.key.userId != userId) { 4662 // Not the same user, skip it. 4663 continue; 4664 } 4665 } else { 4666 if (UserHandle.getAppId(pir.uid) != appId) { 4667 // Different app id, skip it. 4668 continue; 4669 } 4670 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4671 // Different user, skip it. 4672 continue; 4673 } 4674 if (!pir.key.packageName.equals(name)) { 4675 // Different package, skip it. 4676 continue; 4677 } 4678 } 4679 if (!doit) { 4680 return true; 4681 } 4682 didSomething = true; 4683 it.remove(); 4684 pir.canceled = true; 4685 if (pir.key.activity != null) { 4686 pir.key.activity.pendingResults.remove(pir.ref); 4687 } 4688 } 4689 } 4690 } 4691 4692 if (doit) { 4693 if (purgeCache && name != null) { 4694 AttributeCache ac = AttributeCache.instance(); 4695 if (ac != null) { 4696 ac.removePackage(name); 4697 } 4698 } 4699 if (mBooted) { 4700 mStackSupervisor.resumeTopActivitiesLocked(); 4701 mStackSupervisor.scheduleIdleLocked(); 4702 } 4703 } 4704 4705 return didSomething; 4706 } 4707 4708 private final boolean removeProcessLocked(ProcessRecord app, 4709 boolean callerWillRestart, boolean allowRestart, String reason) { 4710 final String name = app.processName; 4711 final int uid = app.uid; 4712 if (DEBUG_PROCESSES) Slog.d( 4713 TAG, "Force removing proc " + app.toShortString() + " (" + name 4714 + "/" + uid + ")"); 4715 4716 mProcessNames.remove(name, uid); 4717 mIsolatedProcesses.remove(app.uid); 4718 if (mHeavyWeightProcess == app) { 4719 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4720 mHeavyWeightProcess.userId, 0)); 4721 mHeavyWeightProcess = null; 4722 } 4723 boolean needRestart = false; 4724 if (app.pid > 0 && app.pid != MY_PID) { 4725 int pid = app.pid; 4726 synchronized (mPidsSelfLocked) { 4727 mPidsSelfLocked.remove(pid); 4728 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4729 } 4730 killUnneededProcessLocked(app, reason); 4731 handleAppDiedLocked(app, true, allowRestart); 4732 removeLruProcessLocked(app); 4733 4734 if (app.persistent && !app.isolated) { 4735 if (!callerWillRestart) { 4736 addAppLocked(app.info, false); 4737 } else { 4738 needRestart = true; 4739 } 4740 } 4741 } else { 4742 mRemovedProcesses.add(app); 4743 } 4744 4745 return needRestart; 4746 } 4747 4748 private final void processStartTimedOutLocked(ProcessRecord app) { 4749 final int pid = app.pid; 4750 boolean gone = false; 4751 synchronized (mPidsSelfLocked) { 4752 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4753 if (knownApp != null && knownApp.thread == null) { 4754 mPidsSelfLocked.remove(pid); 4755 gone = true; 4756 } 4757 } 4758 4759 if (gone) { 4760 Slog.w(TAG, "Process " + app + " failed to attach"); 4761 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4762 pid, app.uid, app.processName); 4763 mProcessNames.remove(app.processName, app.uid); 4764 mIsolatedProcesses.remove(app.uid); 4765 if (mHeavyWeightProcess == app) { 4766 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4767 mHeavyWeightProcess.userId, 0)); 4768 mHeavyWeightProcess = null; 4769 } 4770 // Take care of any launching providers waiting for this process. 4771 checkAppInLaunchingProvidersLocked(app, true); 4772 // Take care of any services that are waiting for the process. 4773 mServices.processStartTimedOutLocked(app); 4774 killUnneededProcessLocked(app, "start timeout"); 4775 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4776 Slog.w(TAG, "Unattached app died before backup, skipping"); 4777 try { 4778 IBackupManager bm = IBackupManager.Stub.asInterface( 4779 ServiceManager.getService(Context.BACKUP_SERVICE)); 4780 bm.agentDisconnected(app.info.packageName); 4781 } catch (RemoteException e) { 4782 // Can't happen; the backup manager is local 4783 } 4784 } 4785 if (isPendingBroadcastProcessLocked(pid)) { 4786 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4787 skipPendingBroadcastLocked(pid); 4788 } 4789 } else { 4790 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4791 } 4792 } 4793 4794 private final boolean attachApplicationLocked(IApplicationThread thread, 4795 int pid) { 4796 4797 // Find the application record that is being attached... either via 4798 // the pid if we are running in multiple processes, or just pull the 4799 // next app record if we are emulating process with anonymous threads. 4800 ProcessRecord app; 4801 if (pid != MY_PID && pid >= 0) { 4802 synchronized (mPidsSelfLocked) { 4803 app = mPidsSelfLocked.get(pid); 4804 } 4805 } else { 4806 app = null; 4807 } 4808 4809 if (app == null) { 4810 Slog.w(TAG, "No pending application record for pid " + pid 4811 + " (IApplicationThread " + thread + "); dropping process"); 4812 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4813 if (pid > 0 && pid != MY_PID) { 4814 Process.killProcessQuiet(pid); 4815 } else { 4816 try { 4817 thread.scheduleExit(); 4818 } catch (Exception e) { 4819 // Ignore exceptions. 4820 } 4821 } 4822 return false; 4823 } 4824 4825 // If this application record is still attached to a previous 4826 // process, clean it up now. 4827 if (app.thread != null) { 4828 handleAppDiedLocked(app, true, true); 4829 } 4830 4831 // Tell the process all about itself. 4832 4833 if (localLOGV) Slog.v( 4834 TAG, "Binding process pid " + pid + " to record " + app); 4835 4836 final String processName = app.processName; 4837 try { 4838 AppDeathRecipient adr = new AppDeathRecipient( 4839 app, pid, thread); 4840 thread.asBinder().linkToDeath(adr, 0); 4841 app.deathRecipient = adr; 4842 } catch (RemoteException e) { 4843 app.resetPackageList(mProcessStats); 4844 startProcessLocked(app, "link fail", processName); 4845 return false; 4846 } 4847 4848 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4849 4850 app.makeActive(thread, mProcessStats); 4851 app.curAdj = app.setAdj = -100; 4852 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4853 app.forcingToForeground = null; 4854 app.foregroundServices = false; 4855 app.hasShownUi = false; 4856 app.debugging = false; 4857 app.cached = false; 4858 4859 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4860 4861 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4862 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4863 4864 if (!normalMode) { 4865 Slog.i(TAG, "Launching preboot mode app: " + app); 4866 } 4867 4868 if (localLOGV) Slog.v( 4869 TAG, "New app record " + app 4870 + " thread=" + thread.asBinder() + " pid=" + pid); 4871 try { 4872 int testMode = IApplicationThread.DEBUG_OFF; 4873 if (mDebugApp != null && mDebugApp.equals(processName)) { 4874 testMode = mWaitForDebugger 4875 ? IApplicationThread.DEBUG_WAIT 4876 : IApplicationThread.DEBUG_ON; 4877 app.debugging = true; 4878 if (mDebugTransient) { 4879 mDebugApp = mOrigDebugApp; 4880 mWaitForDebugger = mOrigWaitForDebugger; 4881 } 4882 } 4883 String profileFile = app.instrumentationProfileFile; 4884 ParcelFileDescriptor profileFd = null; 4885 boolean profileAutoStop = false; 4886 if (mProfileApp != null && mProfileApp.equals(processName)) { 4887 mProfileProc = app; 4888 profileFile = mProfileFile; 4889 profileFd = mProfileFd; 4890 profileAutoStop = mAutoStopProfiler; 4891 } 4892 boolean enableOpenGlTrace = false; 4893 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4894 enableOpenGlTrace = true; 4895 mOpenGlTraceApp = null; 4896 } 4897 4898 // If the app is being launched for restore or full backup, set it up specially 4899 boolean isRestrictedBackupMode = false; 4900 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4901 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4902 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4903 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4904 } 4905 4906 ensurePackageDexOpt(app.instrumentationInfo != null 4907 ? app.instrumentationInfo.packageName 4908 : app.info.packageName); 4909 if (app.instrumentationClass != null) { 4910 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4911 } 4912 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4913 + processName + " with config " + mConfiguration); 4914 ApplicationInfo appInfo = app.instrumentationInfo != null 4915 ? app.instrumentationInfo : app.info; 4916 app.compat = compatibilityInfoForPackageLocked(appInfo); 4917 if (profileFd != null) { 4918 profileFd = profileFd.dup(); 4919 } 4920 thread.bindApplication(processName, appInfo, providers, 4921 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4922 app.instrumentationArguments, app.instrumentationWatcher, 4923 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4924 isRestrictedBackupMode || !normalMode, app.persistent, 4925 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4926 mCoreSettingsObserver.getCoreSettingsLocked()); 4927 updateLruProcessLocked(app, false, null); 4928 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4929 } catch (Exception e) { 4930 // todo: Yikes! What should we do? For now we will try to 4931 // start another process, but that could easily get us in 4932 // an infinite loop of restarting processes... 4933 Slog.w(TAG, "Exception thrown during bind!", e); 4934 4935 app.resetPackageList(mProcessStats); 4936 app.unlinkDeathRecipient(); 4937 startProcessLocked(app, "bind fail", processName); 4938 return false; 4939 } 4940 4941 // Remove this record from the list of starting applications. 4942 mPersistentStartingProcesses.remove(app); 4943 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4944 "Attach application locked removing on hold: " + app); 4945 mProcessesOnHold.remove(app); 4946 4947 boolean badApp = false; 4948 boolean didSomething = false; 4949 4950 // See if the top visible activity is waiting to run in this process... 4951 if (normalMode) { 4952 try { 4953 if (mStackSupervisor.attachApplicationLocked(app)) { 4954 didSomething = true; 4955 } 4956 } catch (Exception e) { 4957 badApp = true; 4958 } 4959 } 4960 4961 // Find any services that should be running in this process... 4962 if (!badApp) { 4963 try { 4964 didSomething |= mServices.attachApplicationLocked(app, processName); 4965 } catch (Exception e) { 4966 badApp = true; 4967 } 4968 } 4969 4970 // Check if a next-broadcast receiver is in this process... 4971 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4972 try { 4973 didSomething |= sendPendingBroadcastsLocked(app); 4974 } catch (Exception e) { 4975 // If the app died trying to launch the receiver we declare it 'bad' 4976 badApp = true; 4977 } 4978 } 4979 4980 // Check whether the next backup agent is in this process... 4981 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4982 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4983 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4984 try { 4985 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4986 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4987 mBackupTarget.backupMode); 4988 } catch (Exception e) { 4989 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4990 e.printStackTrace(); 4991 } 4992 } 4993 4994 if (badApp) { 4995 // todo: Also need to kill application to deal with all 4996 // kinds of exceptions. 4997 handleAppDiedLocked(app, false, true); 4998 return false; 4999 } 5000 5001 if (!didSomething) { 5002 updateOomAdjLocked(); 5003 } 5004 5005 return true; 5006 } 5007 5008 @Override 5009 public final void attachApplication(IApplicationThread thread) { 5010 synchronized (this) { 5011 int callingPid = Binder.getCallingPid(); 5012 final long origId = Binder.clearCallingIdentity(); 5013 attachApplicationLocked(thread, callingPid); 5014 Binder.restoreCallingIdentity(origId); 5015 } 5016 } 5017 5018 @Override 5019 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5020 final long origId = Binder.clearCallingIdentity(); 5021 synchronized (this) { 5022 ActivityStack stack = ActivityRecord.getStackLocked(token); 5023 if (stack != null) { 5024 ActivityRecord r = 5025 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5026 if (stopProfiling) { 5027 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5028 try { 5029 mProfileFd.close(); 5030 } catch (IOException e) { 5031 } 5032 clearProfilerLocked(); 5033 } 5034 } 5035 } 5036 } 5037 Binder.restoreCallingIdentity(origId); 5038 } 5039 5040 void enableScreenAfterBoot() { 5041 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5042 SystemClock.uptimeMillis()); 5043 mWindowManager.enableScreenAfterBoot(); 5044 5045 synchronized (this) { 5046 updateEventDispatchingLocked(); 5047 } 5048 } 5049 5050 @Override 5051 public void showBootMessage(final CharSequence msg, final boolean always) { 5052 enforceNotIsolatedCaller("showBootMessage"); 5053 mWindowManager.showBootMessage(msg, always); 5054 } 5055 5056 @Override 5057 public void dismissKeyguardOnNextActivity() { 5058 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5059 final long token = Binder.clearCallingIdentity(); 5060 try { 5061 synchronized (this) { 5062 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5063 if (mLockScreenShown) { 5064 mLockScreenShown = false; 5065 comeOutOfSleepIfNeededLocked(); 5066 } 5067 mStackSupervisor.setDismissKeyguard(true); 5068 } 5069 } finally { 5070 Binder.restoreCallingIdentity(token); 5071 } 5072 } 5073 5074 final void finishBooting() { 5075 IntentFilter pkgFilter = new IntentFilter(); 5076 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5077 pkgFilter.addDataScheme("package"); 5078 mContext.registerReceiver(new BroadcastReceiver() { 5079 @Override 5080 public void onReceive(Context context, Intent intent) { 5081 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5082 if (pkgs != null) { 5083 for (String pkg : pkgs) { 5084 synchronized (ActivityManagerService.this) { 5085 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0, 5086 "finished booting")) { 5087 setResultCode(Activity.RESULT_OK); 5088 return; 5089 } 5090 } 5091 } 5092 } 5093 } 5094 }, pkgFilter); 5095 5096 synchronized (this) { 5097 // Ensure that any processes we had put on hold are now started 5098 // up. 5099 final int NP = mProcessesOnHold.size(); 5100 if (NP > 0) { 5101 ArrayList<ProcessRecord> procs = 5102 new ArrayList<ProcessRecord>(mProcessesOnHold); 5103 for (int ip=0; ip<NP; ip++) { 5104 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5105 + procs.get(ip)); 5106 startProcessLocked(procs.get(ip), "on-hold", null); 5107 } 5108 } 5109 5110 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5111 // Start looking for apps that are abusing wake locks. 5112 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5113 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5114 // Tell anyone interested that we are done booting! 5115 SystemProperties.set("sys.boot_completed", "1"); 5116 SystemProperties.set("dev.bootcomplete", "1"); 5117 for (int i=0; i<mStartedUsers.size(); i++) { 5118 UserStartedState uss = mStartedUsers.valueAt(i); 5119 if (uss.mState == UserStartedState.STATE_BOOTING) { 5120 uss.mState = UserStartedState.STATE_RUNNING; 5121 final int userId = mStartedUsers.keyAt(i); 5122 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5123 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5124 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5125 broadcastIntentLocked(null, null, intent, null, 5126 new IIntentReceiver.Stub() { 5127 @Override 5128 public void performReceive(Intent intent, int resultCode, 5129 String data, Bundle extras, boolean ordered, 5130 boolean sticky, int sendingUser) { 5131 synchronized (ActivityManagerService.this) { 5132 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5133 true, false); 5134 } 5135 } 5136 }, 5137 0, null, null, 5138 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5139 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5140 userId); 5141 } 5142 } 5143 } 5144 } 5145 } 5146 5147 final void ensureBootCompleted() { 5148 boolean booting; 5149 boolean enableScreen; 5150 synchronized (this) { 5151 booting = mBooting; 5152 mBooting = false; 5153 enableScreen = !mBooted; 5154 mBooted = true; 5155 } 5156 5157 if (booting) { 5158 finishBooting(); 5159 } 5160 5161 if (enableScreen) { 5162 enableScreenAfterBoot(); 5163 } 5164 } 5165 5166 @Override 5167 public final void activityResumed(IBinder token) { 5168 final long origId = Binder.clearCallingIdentity(); 5169 synchronized(this) { 5170 ActivityStack stack = ActivityRecord.getStackLocked(token); 5171 if (stack != null) { 5172 ActivityRecord.activityResumedLocked(token); 5173 } 5174 } 5175 Binder.restoreCallingIdentity(origId); 5176 } 5177 5178 @Override 5179 public final void activityPaused(IBinder token) { 5180 final long origId = Binder.clearCallingIdentity(); 5181 synchronized(this) { 5182 ActivityStack stack = ActivityRecord.getStackLocked(token); 5183 if (stack != null) { 5184 stack.activityPausedLocked(token, false); 5185 } 5186 } 5187 Binder.restoreCallingIdentity(origId); 5188 } 5189 5190 @Override 5191 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5192 CharSequence description) { 5193 if (localLOGV) Slog.v( 5194 TAG, "Activity stopped: token=" + token); 5195 5196 // Refuse possible leaked file descriptors 5197 if (icicle != null && icicle.hasFileDescriptors()) { 5198 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5199 } 5200 5201 ActivityRecord r = null; 5202 5203 final long origId = Binder.clearCallingIdentity(); 5204 5205 synchronized (this) { 5206 r = ActivityRecord.isInStackLocked(token); 5207 if (r != null) { 5208 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5209 } 5210 } 5211 5212 if (r != null) { 5213 sendPendingThumbnail(r, null, null, null, false); 5214 } 5215 5216 trimApplications(); 5217 5218 Binder.restoreCallingIdentity(origId); 5219 } 5220 5221 @Override 5222 public final void activityDestroyed(IBinder token) { 5223 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5224 synchronized (this) { 5225 ActivityStack stack = ActivityRecord.getStackLocked(token); 5226 if (stack != null) { 5227 stack.activityDestroyedLocked(token); 5228 } 5229 } 5230 } 5231 5232 @Override 5233 public String getCallingPackage(IBinder token) { 5234 synchronized (this) { 5235 ActivityRecord r = getCallingRecordLocked(token); 5236 return r != null ? r.info.packageName : null; 5237 } 5238 } 5239 5240 @Override 5241 public ComponentName getCallingActivity(IBinder token) { 5242 synchronized (this) { 5243 ActivityRecord r = getCallingRecordLocked(token); 5244 return r != null ? r.intent.getComponent() : null; 5245 } 5246 } 5247 5248 private ActivityRecord getCallingRecordLocked(IBinder token) { 5249 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5250 if (r == null) { 5251 return null; 5252 } 5253 return r.resultTo; 5254 } 5255 5256 @Override 5257 public ComponentName getActivityClassForToken(IBinder token) { 5258 synchronized(this) { 5259 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5260 if (r == null) { 5261 return null; 5262 } 5263 return r.intent.getComponent(); 5264 } 5265 } 5266 5267 @Override 5268 public String getPackageForToken(IBinder token) { 5269 synchronized(this) { 5270 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5271 if (r == null) { 5272 return null; 5273 } 5274 return r.packageName; 5275 } 5276 } 5277 5278 @Override 5279 public IIntentSender getIntentSender(int type, 5280 String packageName, IBinder token, String resultWho, 5281 int requestCode, Intent[] intents, String[] resolvedTypes, 5282 int flags, Bundle options, int userId) { 5283 enforceNotIsolatedCaller("getIntentSender"); 5284 // Refuse possible leaked file descriptors 5285 if (intents != null) { 5286 if (intents.length < 1) { 5287 throw new IllegalArgumentException("Intents array length must be >= 1"); 5288 } 5289 for (int i=0; i<intents.length; i++) { 5290 Intent intent = intents[i]; 5291 if (intent != null) { 5292 if (intent.hasFileDescriptors()) { 5293 throw new IllegalArgumentException("File descriptors passed in Intent"); 5294 } 5295 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5296 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5297 throw new IllegalArgumentException( 5298 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5299 } 5300 intents[i] = new Intent(intent); 5301 } 5302 } 5303 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5304 throw new IllegalArgumentException( 5305 "Intent array length does not match resolvedTypes length"); 5306 } 5307 } 5308 if (options != null) { 5309 if (options.hasFileDescriptors()) { 5310 throw new IllegalArgumentException("File descriptors passed in options"); 5311 } 5312 } 5313 5314 synchronized(this) { 5315 int callingUid = Binder.getCallingUid(); 5316 int origUserId = userId; 5317 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5318 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5319 "getIntentSender", null); 5320 if (origUserId == UserHandle.USER_CURRENT) { 5321 // We don't want to evaluate this until the pending intent is 5322 // actually executed. However, we do want to always do the 5323 // security checking for it above. 5324 userId = UserHandle.USER_CURRENT; 5325 } 5326 try { 5327 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5328 int uid = AppGlobals.getPackageManager() 5329 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5330 if (!UserHandle.isSameApp(callingUid, uid)) { 5331 String msg = "Permission Denial: getIntentSender() from pid=" 5332 + Binder.getCallingPid() 5333 + ", uid=" + Binder.getCallingUid() 5334 + ", (need uid=" + uid + ")" 5335 + " is not allowed to send as package " + packageName; 5336 Slog.w(TAG, msg); 5337 throw new SecurityException(msg); 5338 } 5339 } 5340 5341 return getIntentSenderLocked(type, packageName, callingUid, userId, 5342 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5343 5344 } catch (RemoteException e) { 5345 throw new SecurityException(e); 5346 } 5347 } 5348 } 5349 5350 IIntentSender getIntentSenderLocked(int type, String packageName, 5351 int callingUid, int userId, IBinder token, String resultWho, 5352 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5353 Bundle options) { 5354 if (DEBUG_MU) 5355 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5356 ActivityRecord activity = null; 5357 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5358 activity = ActivityRecord.isInStackLocked(token); 5359 if (activity == null) { 5360 return null; 5361 } 5362 if (activity.finishing) { 5363 return null; 5364 } 5365 } 5366 5367 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5368 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5369 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5370 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5371 |PendingIntent.FLAG_UPDATE_CURRENT); 5372 5373 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5374 type, packageName, activity, resultWho, 5375 requestCode, intents, resolvedTypes, flags, options, userId); 5376 WeakReference<PendingIntentRecord> ref; 5377 ref = mIntentSenderRecords.get(key); 5378 PendingIntentRecord rec = ref != null ? ref.get() : null; 5379 if (rec != null) { 5380 if (!cancelCurrent) { 5381 if (updateCurrent) { 5382 if (rec.key.requestIntent != null) { 5383 rec.key.requestIntent.replaceExtras(intents != null ? 5384 intents[intents.length - 1] : null); 5385 } 5386 if (intents != null) { 5387 intents[intents.length-1] = rec.key.requestIntent; 5388 rec.key.allIntents = intents; 5389 rec.key.allResolvedTypes = resolvedTypes; 5390 } else { 5391 rec.key.allIntents = null; 5392 rec.key.allResolvedTypes = null; 5393 } 5394 } 5395 return rec; 5396 } 5397 rec.canceled = true; 5398 mIntentSenderRecords.remove(key); 5399 } 5400 if (noCreate) { 5401 return rec; 5402 } 5403 rec = new PendingIntentRecord(this, key, callingUid); 5404 mIntentSenderRecords.put(key, rec.ref); 5405 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5406 if (activity.pendingResults == null) { 5407 activity.pendingResults 5408 = new HashSet<WeakReference<PendingIntentRecord>>(); 5409 } 5410 activity.pendingResults.add(rec.ref); 5411 } 5412 return rec; 5413 } 5414 5415 @Override 5416 public void cancelIntentSender(IIntentSender sender) { 5417 if (!(sender instanceof PendingIntentRecord)) { 5418 return; 5419 } 5420 synchronized(this) { 5421 PendingIntentRecord rec = (PendingIntentRecord)sender; 5422 try { 5423 int uid = AppGlobals.getPackageManager() 5424 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5425 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5426 String msg = "Permission Denial: cancelIntentSender() from pid=" 5427 + Binder.getCallingPid() 5428 + ", uid=" + Binder.getCallingUid() 5429 + " is not allowed to cancel packges " 5430 + rec.key.packageName; 5431 Slog.w(TAG, msg); 5432 throw new SecurityException(msg); 5433 } 5434 } catch (RemoteException e) { 5435 throw new SecurityException(e); 5436 } 5437 cancelIntentSenderLocked(rec, true); 5438 } 5439 } 5440 5441 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5442 rec.canceled = true; 5443 mIntentSenderRecords.remove(rec.key); 5444 if (cleanActivity && rec.key.activity != null) { 5445 rec.key.activity.pendingResults.remove(rec.ref); 5446 } 5447 } 5448 5449 @Override 5450 public String getPackageForIntentSender(IIntentSender pendingResult) { 5451 if (!(pendingResult instanceof PendingIntentRecord)) { 5452 return null; 5453 } 5454 try { 5455 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5456 return res.key.packageName; 5457 } catch (ClassCastException e) { 5458 } 5459 return null; 5460 } 5461 5462 @Override 5463 public int getUidForIntentSender(IIntentSender sender) { 5464 if (sender instanceof PendingIntentRecord) { 5465 try { 5466 PendingIntentRecord res = (PendingIntentRecord)sender; 5467 return res.uid; 5468 } catch (ClassCastException e) { 5469 } 5470 } 5471 return -1; 5472 } 5473 5474 @Override 5475 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5476 if (!(pendingResult instanceof PendingIntentRecord)) { 5477 return false; 5478 } 5479 try { 5480 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5481 if (res.key.allIntents == null) { 5482 return false; 5483 } 5484 for (int i=0; i<res.key.allIntents.length; i++) { 5485 Intent intent = res.key.allIntents[i]; 5486 if (intent.getPackage() != null && intent.getComponent() != null) { 5487 return false; 5488 } 5489 } 5490 return true; 5491 } catch (ClassCastException e) { 5492 } 5493 return false; 5494 } 5495 5496 @Override 5497 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5498 if (!(pendingResult instanceof PendingIntentRecord)) { 5499 return false; 5500 } 5501 try { 5502 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5503 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5504 return true; 5505 } 5506 return false; 5507 } catch (ClassCastException e) { 5508 } 5509 return false; 5510 } 5511 5512 @Override 5513 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5514 if (!(pendingResult instanceof PendingIntentRecord)) { 5515 return null; 5516 } 5517 try { 5518 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5519 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5520 } catch (ClassCastException e) { 5521 } 5522 return null; 5523 } 5524 5525 @Override 5526 public void setProcessLimit(int max) { 5527 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5528 "setProcessLimit()"); 5529 synchronized (this) { 5530 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5531 mProcessLimitOverride = max; 5532 } 5533 trimApplications(); 5534 } 5535 5536 @Override 5537 public int getProcessLimit() { 5538 synchronized (this) { 5539 return mProcessLimitOverride; 5540 } 5541 } 5542 5543 void foregroundTokenDied(ForegroundToken token) { 5544 synchronized (ActivityManagerService.this) { 5545 synchronized (mPidsSelfLocked) { 5546 ForegroundToken cur 5547 = mForegroundProcesses.get(token.pid); 5548 if (cur != token) { 5549 return; 5550 } 5551 mForegroundProcesses.remove(token.pid); 5552 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5553 if (pr == null) { 5554 return; 5555 } 5556 pr.forcingToForeground = null; 5557 pr.foregroundServices = false; 5558 } 5559 updateOomAdjLocked(); 5560 } 5561 } 5562 5563 @Override 5564 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5565 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5566 "setProcessForeground()"); 5567 synchronized(this) { 5568 boolean changed = false; 5569 5570 synchronized (mPidsSelfLocked) { 5571 ProcessRecord pr = mPidsSelfLocked.get(pid); 5572 if (pr == null && isForeground) { 5573 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5574 return; 5575 } 5576 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5577 if (oldToken != null) { 5578 oldToken.token.unlinkToDeath(oldToken, 0); 5579 mForegroundProcesses.remove(pid); 5580 if (pr != null) { 5581 pr.forcingToForeground = null; 5582 } 5583 changed = true; 5584 } 5585 if (isForeground && token != null) { 5586 ForegroundToken newToken = new ForegroundToken() { 5587 @Override 5588 public void binderDied() { 5589 foregroundTokenDied(this); 5590 } 5591 }; 5592 newToken.pid = pid; 5593 newToken.token = token; 5594 try { 5595 token.linkToDeath(newToken, 0); 5596 mForegroundProcesses.put(pid, newToken); 5597 pr.forcingToForeground = token; 5598 changed = true; 5599 } catch (RemoteException e) { 5600 // If the process died while doing this, we will later 5601 // do the cleanup with the process death link. 5602 } 5603 } 5604 } 5605 5606 if (changed) { 5607 updateOomAdjLocked(); 5608 } 5609 } 5610 } 5611 5612 // ========================================================= 5613 // PERMISSIONS 5614 // ========================================================= 5615 5616 static class PermissionController extends IPermissionController.Stub { 5617 ActivityManagerService mActivityManagerService; 5618 PermissionController(ActivityManagerService activityManagerService) { 5619 mActivityManagerService = activityManagerService; 5620 } 5621 5622 @Override 5623 public boolean checkPermission(String permission, int pid, int uid) { 5624 return mActivityManagerService.checkPermission(permission, pid, 5625 uid) == PackageManager.PERMISSION_GRANTED; 5626 } 5627 } 5628 5629 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5630 @Override 5631 public int checkComponentPermission(String permission, int pid, int uid, 5632 int owningUid, boolean exported) { 5633 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5634 owningUid, exported); 5635 } 5636 5637 @Override 5638 public Object getAMSLock() { 5639 return ActivityManagerService.this; 5640 } 5641 } 5642 5643 /** 5644 * This can be called with or without the global lock held. 5645 */ 5646 int checkComponentPermission(String permission, int pid, int uid, 5647 int owningUid, boolean exported) { 5648 // We might be performing an operation on behalf of an indirect binder 5649 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5650 // client identity accordingly before proceeding. 5651 Identity tlsIdentity = sCallerIdentity.get(); 5652 if (tlsIdentity != null) { 5653 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5654 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5655 uid = tlsIdentity.uid; 5656 pid = tlsIdentity.pid; 5657 } 5658 5659 if (pid == MY_PID) { 5660 return PackageManager.PERMISSION_GRANTED; 5661 } 5662 5663 return ActivityManager.checkComponentPermission(permission, uid, 5664 owningUid, exported); 5665 } 5666 5667 /** 5668 * As the only public entry point for permissions checking, this method 5669 * can enforce the semantic that requesting a check on a null global 5670 * permission is automatically denied. (Internally a null permission 5671 * string is used when calling {@link #checkComponentPermission} in cases 5672 * when only uid-based security is needed.) 5673 * 5674 * This can be called with or without the global lock held. 5675 */ 5676 @Override 5677 public int checkPermission(String permission, int pid, int uid) { 5678 if (permission == null) { 5679 return PackageManager.PERMISSION_DENIED; 5680 } 5681 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5682 } 5683 5684 /** 5685 * Binder IPC calls go through the public entry point. 5686 * This can be called with or without the global lock held. 5687 */ 5688 int checkCallingPermission(String permission) { 5689 return checkPermission(permission, 5690 Binder.getCallingPid(), 5691 UserHandle.getAppId(Binder.getCallingUid())); 5692 } 5693 5694 /** 5695 * This can be called with or without the global lock held. 5696 */ 5697 void enforceCallingPermission(String permission, String func) { 5698 if (checkCallingPermission(permission) 5699 == PackageManager.PERMISSION_GRANTED) { 5700 return; 5701 } 5702 5703 String msg = "Permission Denial: " + func + " from pid=" 5704 + Binder.getCallingPid() 5705 + ", uid=" + Binder.getCallingUid() 5706 + " requires " + permission; 5707 Slog.w(TAG, msg); 5708 throw new SecurityException(msg); 5709 } 5710 5711 /** 5712 * Determine if UID is holding permissions required to access {@link Uri} in 5713 * the given {@link ProviderInfo}. Final permission checking is always done 5714 * in {@link ContentProvider}. 5715 */ 5716 private final boolean checkHoldingPermissionsLocked( 5717 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5718 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5719 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5720 5721 if (pi.applicationInfo.uid == uid) { 5722 return true; 5723 } else if (!pi.exported) { 5724 return false; 5725 } 5726 5727 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5728 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5729 try { 5730 // check if target holds top-level <provider> permissions 5731 if (!readMet && pi.readPermission != null 5732 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5733 readMet = true; 5734 } 5735 if (!writeMet && pi.writePermission != null 5736 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5737 writeMet = true; 5738 } 5739 5740 // track if unprotected read/write is allowed; any denied 5741 // <path-permission> below removes this ability 5742 boolean allowDefaultRead = pi.readPermission == null; 5743 boolean allowDefaultWrite = pi.writePermission == null; 5744 5745 // check if target holds any <path-permission> that match uri 5746 final PathPermission[] pps = pi.pathPermissions; 5747 if (pps != null) { 5748 final String path = uri.getPath(); 5749 int i = pps.length; 5750 while (i > 0 && (!readMet || !writeMet)) { 5751 i--; 5752 PathPermission pp = pps[i]; 5753 if (pp.match(path)) { 5754 if (!readMet) { 5755 final String pprperm = pp.getReadPermission(); 5756 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5757 + pprperm + " for " + pp.getPath() 5758 + ": match=" + pp.match(path) 5759 + " check=" + pm.checkUidPermission(pprperm, uid)); 5760 if (pprperm != null) { 5761 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5762 readMet = true; 5763 } else { 5764 allowDefaultRead = false; 5765 } 5766 } 5767 } 5768 if (!writeMet) { 5769 final String ppwperm = pp.getWritePermission(); 5770 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5771 + ppwperm + " for " + pp.getPath() 5772 + ": match=" + pp.match(path) 5773 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5774 if (ppwperm != null) { 5775 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5776 writeMet = true; 5777 } else { 5778 allowDefaultWrite = false; 5779 } 5780 } 5781 } 5782 } 5783 } 5784 } 5785 5786 // grant unprotected <provider> read/write, if not blocked by 5787 // <path-permission> above 5788 if (allowDefaultRead) readMet = true; 5789 if (allowDefaultWrite) writeMet = true; 5790 5791 } catch (RemoteException e) { 5792 return false; 5793 } 5794 5795 return readMet && writeMet; 5796 } 5797 5798 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5799 ProviderInfo pi = null; 5800 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5801 if (cpr != null) { 5802 pi = cpr.info; 5803 } else { 5804 try { 5805 pi = AppGlobals.getPackageManager().resolveContentProvider( 5806 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5807 } catch (RemoteException ex) { 5808 } 5809 } 5810 return pi; 5811 } 5812 5813 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5814 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5815 if (targetUris != null) { 5816 return targetUris.get(uri); 5817 } else { 5818 return null; 5819 } 5820 } 5821 5822 private UriPermission findOrCreateUriPermissionLocked( 5823 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5824 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5825 if (targetUris == null) { 5826 targetUris = Maps.newArrayMap(); 5827 mGrantedUriPermissions.put(targetUid, targetUris); 5828 } 5829 5830 UriPermission perm = targetUris.get(uri); 5831 if (perm == null) { 5832 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5833 targetUris.put(uri, perm); 5834 } 5835 5836 return perm; 5837 } 5838 5839 private final boolean checkUriPermissionLocked( 5840 Uri uri, int uid, int modeFlags, int minStrength) { 5841 // Root gets to do everything. 5842 if (uid == 0) { 5843 return true; 5844 } 5845 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5846 if (perms == null) return false; 5847 UriPermission perm = perms.get(uri); 5848 if (perm == null) return false; 5849 return perm.getStrength(modeFlags) >= minStrength; 5850 } 5851 5852 @Override 5853 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5854 enforceNotIsolatedCaller("checkUriPermission"); 5855 5856 // Another redirected-binder-call permissions check as in 5857 // {@link checkComponentPermission}. 5858 Identity tlsIdentity = sCallerIdentity.get(); 5859 if (tlsIdentity != null) { 5860 uid = tlsIdentity.uid; 5861 pid = tlsIdentity.pid; 5862 } 5863 5864 // Our own process gets to do everything. 5865 if (pid == MY_PID) { 5866 return PackageManager.PERMISSION_GRANTED; 5867 } 5868 synchronized(this) { 5869 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5870 ? PackageManager.PERMISSION_GRANTED 5871 : PackageManager.PERMISSION_DENIED; 5872 } 5873 } 5874 5875 /** 5876 * Check if the targetPkg can be granted permission to access uri by 5877 * the callingUid using the given modeFlags. Throws a security exception 5878 * if callingUid is not allowed to do this. Returns the uid of the target 5879 * if the URI permission grant should be performed; returns -1 if it is not 5880 * needed (for example targetPkg already has permission to access the URI). 5881 * If you already know the uid of the target, you can supply it in 5882 * lastTargetUid else set that to -1. 5883 */ 5884 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5885 Uri uri, int modeFlags, int lastTargetUid) { 5886 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5887 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5888 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5889 if (modeFlags == 0) { 5890 return -1; 5891 } 5892 5893 if (targetPkg != null) { 5894 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5895 "Checking grant " + targetPkg + " permission to " + uri); 5896 } 5897 5898 final IPackageManager pm = AppGlobals.getPackageManager(); 5899 5900 // If this is not a content: uri, we can't do anything with it. 5901 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5902 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5903 "Can't grant URI permission for non-content URI: " + uri); 5904 return -1; 5905 } 5906 5907 final String authority = uri.getAuthority(); 5908 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 5909 if (pi == null) { 5910 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5911 return -1; 5912 } 5913 5914 int targetUid = lastTargetUid; 5915 if (targetUid < 0 && targetPkg != null) { 5916 try { 5917 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5918 if (targetUid < 0) { 5919 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5920 "Can't grant URI permission no uid for: " + targetPkg); 5921 return -1; 5922 } 5923 } catch (RemoteException ex) { 5924 return -1; 5925 } 5926 } 5927 5928 if (targetUid >= 0) { 5929 // First... does the target actually need this permission? 5930 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5931 // No need to grant the target this permission. 5932 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5933 "Target " + targetPkg + " already has full permission to " + uri); 5934 return -1; 5935 } 5936 } else { 5937 // First... there is no target package, so can anyone access it? 5938 boolean allowed = pi.exported; 5939 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5940 if (pi.readPermission != null) { 5941 allowed = false; 5942 } 5943 } 5944 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5945 if (pi.writePermission != null) { 5946 allowed = false; 5947 } 5948 } 5949 if (allowed) { 5950 return -1; 5951 } 5952 } 5953 5954 // Second... is the provider allowing granting of URI permissions? 5955 if (!pi.grantUriPermissions) { 5956 throw new SecurityException("Provider " + pi.packageName 5957 + "/" + pi.name 5958 + " does not allow granting of Uri permissions (uri " 5959 + uri + ")"); 5960 } 5961 if (pi.uriPermissionPatterns != null) { 5962 final int N = pi.uriPermissionPatterns.length; 5963 boolean allowed = false; 5964 for (int i=0; i<N; i++) { 5965 if (pi.uriPermissionPatterns[i] != null 5966 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5967 allowed = true; 5968 break; 5969 } 5970 } 5971 if (!allowed) { 5972 throw new SecurityException("Provider " + pi.packageName 5973 + "/" + pi.name 5974 + " does not allow granting of permission to path of Uri " 5975 + uri); 5976 } 5977 } 5978 5979 // Third... does the caller itself have permission to access 5980 // this uri? 5981 if (callingUid != Process.myUid()) { 5982 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5983 // Require they hold a strong enough Uri permission 5984 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 5985 : UriPermission.STRENGTH_OWNED; 5986 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 5987 throw new SecurityException("Uid " + callingUid 5988 + " does not have permission to uri " + uri); 5989 } 5990 } 5991 } 5992 5993 return targetUid; 5994 } 5995 5996 @Override 5997 public int checkGrantUriPermission(int callingUid, String targetPkg, 5998 Uri uri, int modeFlags) { 5999 enforceNotIsolatedCaller("checkGrantUriPermission"); 6000 synchronized(this) { 6001 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6002 } 6003 } 6004 6005 void grantUriPermissionUncheckedLocked( 6006 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6007 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6008 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6009 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6010 if (modeFlags == 0) { 6011 return; 6012 } 6013 6014 // So here we are: the caller has the assumed permission 6015 // to the uri, and the target doesn't. Let's now give this to 6016 // the target. 6017 6018 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6019 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6020 6021 final String authority = uri.getAuthority(); 6022 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6023 if (pi == null) { 6024 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6025 return; 6026 } 6027 6028 final UriPermission perm = findOrCreateUriPermissionLocked( 6029 pi.packageName, targetPkg, targetUid, uri); 6030 perm.grantModes(modeFlags, persistable, owner); 6031 } 6032 6033 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6034 int modeFlags, UriPermissionOwner owner) { 6035 if (targetPkg == null) { 6036 throw new NullPointerException("targetPkg"); 6037 } 6038 6039 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6040 if (targetUid < 0) { 6041 return; 6042 } 6043 6044 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6045 } 6046 6047 static class NeededUriGrants extends ArrayList<Uri> { 6048 final String targetPkg; 6049 final int targetUid; 6050 final int flags; 6051 6052 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6053 this.targetPkg = targetPkg; 6054 this.targetUid = targetUid; 6055 this.flags = flags; 6056 } 6057 } 6058 6059 /** 6060 * Like checkGrantUriPermissionLocked, but takes an Intent. 6061 */ 6062 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6063 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6064 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6065 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6066 + " clip=" + (intent != null ? intent.getClipData() : null) 6067 + " from " + intent + "; flags=0x" 6068 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6069 6070 if (targetPkg == null) { 6071 throw new NullPointerException("targetPkg"); 6072 } 6073 6074 if (intent == null) { 6075 return null; 6076 } 6077 Uri data = intent.getData(); 6078 ClipData clip = intent.getClipData(); 6079 if (data == null && clip == null) { 6080 return null; 6081 } 6082 6083 if (data != null) { 6084 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6085 mode, needed != null ? needed.targetUid : -1); 6086 if (targetUid > 0) { 6087 if (needed == null) { 6088 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6089 } 6090 needed.add(data); 6091 } 6092 } 6093 if (clip != null) { 6094 for (int i=0; i<clip.getItemCount(); i++) { 6095 Uri uri = clip.getItemAt(i).getUri(); 6096 if (uri != null) { 6097 int targetUid = -1; 6098 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6099 mode, needed != null ? needed.targetUid : -1); 6100 if (targetUid > 0) { 6101 if (needed == null) { 6102 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6103 } 6104 needed.add(uri); 6105 } 6106 } else { 6107 Intent clipIntent = clip.getItemAt(i).getIntent(); 6108 if (clipIntent != null) { 6109 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6110 callingUid, targetPkg, clipIntent, mode, needed); 6111 if (newNeeded != null) { 6112 needed = newNeeded; 6113 } 6114 } 6115 } 6116 } 6117 } 6118 6119 return needed; 6120 } 6121 6122 /** 6123 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6124 */ 6125 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6126 UriPermissionOwner owner) { 6127 if (needed != null) { 6128 for (int i=0; i<needed.size(); i++) { 6129 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6130 needed.get(i), needed.flags, owner); 6131 } 6132 } 6133 } 6134 6135 void grantUriPermissionFromIntentLocked(int callingUid, 6136 String targetPkg, Intent intent, UriPermissionOwner owner) { 6137 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6138 intent, intent != null ? intent.getFlags() : 0, null); 6139 if (needed == null) { 6140 return; 6141 } 6142 6143 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6144 } 6145 6146 @Override 6147 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6148 Uri uri, int modeFlags) { 6149 enforceNotIsolatedCaller("grantUriPermission"); 6150 synchronized(this) { 6151 final ProcessRecord r = getRecordForAppLocked(caller); 6152 if (r == null) { 6153 throw new SecurityException("Unable to find app for caller " 6154 + caller 6155 + " when granting permission to uri " + uri); 6156 } 6157 if (targetPkg == null) { 6158 throw new IllegalArgumentException("null target"); 6159 } 6160 if (uri == null) { 6161 throw new IllegalArgumentException("null uri"); 6162 } 6163 6164 // Persistable only supported through Intents 6165 Preconditions.checkFlagsArgument(modeFlags, 6166 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6167 6168 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6169 null); 6170 } 6171 } 6172 6173 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6174 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6175 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6176 ArrayMap<Uri, UriPermission> perms 6177 = mGrantedUriPermissions.get(perm.targetUid); 6178 if (perms != null) { 6179 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6180 "Removing " + perm.targetUid + " permission to " + perm.uri); 6181 perms.remove(perm.uri); 6182 if (perms.size() == 0) { 6183 mGrantedUriPermissions.remove(perm.targetUid); 6184 } 6185 } 6186 } 6187 } 6188 6189 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6190 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6191 6192 final IPackageManager pm = AppGlobals.getPackageManager(); 6193 final String authority = uri.getAuthority(); 6194 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6195 if (pi == null) { 6196 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6197 return; 6198 } 6199 6200 // Does the caller have this permission on the URI? 6201 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6202 // Right now, if you are not the original owner of the permission, 6203 // you are not allowed to revoke it. 6204 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6205 throw new SecurityException("Uid " + callingUid 6206 + " does not have permission to uri " + uri); 6207 //} 6208 } 6209 6210 boolean persistChanged = false; 6211 6212 // Go through all of the permissions and remove any that match. 6213 final List<String> SEGMENTS = uri.getPathSegments(); 6214 if (SEGMENTS != null) { 6215 final int NS = SEGMENTS.size(); 6216 int N = mGrantedUriPermissions.size(); 6217 for (int i=0; i<N; i++) { 6218 ArrayMap<Uri, UriPermission> perms 6219 = mGrantedUriPermissions.valueAt(i); 6220 Iterator<UriPermission> it = perms.values().iterator(); 6221 toploop: 6222 while (it.hasNext()) { 6223 UriPermission perm = it.next(); 6224 Uri targetUri = perm.uri; 6225 if (!authority.equals(targetUri.getAuthority())) { 6226 continue; 6227 } 6228 List<String> targetSegments = targetUri.getPathSegments(); 6229 if (targetSegments == null) { 6230 continue; 6231 } 6232 if (targetSegments.size() < NS) { 6233 continue; 6234 } 6235 for (int j=0; j<NS; j++) { 6236 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6237 continue toploop; 6238 } 6239 } 6240 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6241 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6242 persistChanged |= perm.clearModes(modeFlags, true); 6243 if (perm.modeFlags == 0) { 6244 it.remove(); 6245 } 6246 } 6247 if (perms.size() == 0) { 6248 mGrantedUriPermissions.remove( 6249 mGrantedUriPermissions.keyAt(i)); 6250 N--; 6251 i--; 6252 } 6253 } 6254 } 6255 6256 if (persistChanged) { 6257 schedulePersistUriGrants(); 6258 } 6259 } 6260 6261 @Override 6262 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6263 int modeFlags) { 6264 enforceNotIsolatedCaller("revokeUriPermission"); 6265 synchronized(this) { 6266 final ProcessRecord r = getRecordForAppLocked(caller); 6267 if (r == null) { 6268 throw new SecurityException("Unable to find app for caller " 6269 + caller 6270 + " when revoking permission to uri " + uri); 6271 } 6272 if (uri == null) { 6273 Slog.w(TAG, "revokeUriPermission: null uri"); 6274 return; 6275 } 6276 6277 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6278 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6279 if (modeFlags == 0) { 6280 return; 6281 } 6282 6283 final IPackageManager pm = AppGlobals.getPackageManager(); 6284 final String authority = uri.getAuthority(); 6285 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6286 if (pi == null) { 6287 Slog.w(TAG, "No content provider found for permission revoke: " 6288 + uri.toSafeString()); 6289 return; 6290 } 6291 6292 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6293 } 6294 } 6295 6296 /** 6297 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6298 * given package. 6299 * 6300 * @param packageName Package name to match, or {@code null} to apply to all 6301 * packages. 6302 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6303 * to all users. 6304 * @param persistable If persistable grants should be removed. 6305 */ 6306 private void removeUriPermissionsForPackageLocked( 6307 String packageName, int userHandle, boolean persistable) { 6308 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6309 throw new IllegalArgumentException("Must narrow by either package or user"); 6310 } 6311 6312 boolean persistChanged = false; 6313 6314 final int size = mGrantedUriPermissions.size(); 6315 for (int i = 0; i < size; i++) { 6316 // Only inspect grants matching user 6317 if (userHandle == UserHandle.USER_ALL 6318 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6319 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6320 .values().iterator(); 6321 while (it.hasNext()) { 6322 final UriPermission perm = it.next(); 6323 6324 // Only inspect grants matching package 6325 if (packageName == null || perm.sourcePkg.equals(packageName) 6326 || perm.targetPkg.equals(packageName)) { 6327 persistChanged |= perm.clearModes(~0, persistable); 6328 6329 // Only remove when no modes remain; any persisted grants 6330 // will keep this alive. 6331 if (perm.modeFlags == 0) { 6332 it.remove(); 6333 } 6334 } 6335 } 6336 } 6337 } 6338 6339 if (persistChanged) { 6340 schedulePersistUriGrants(); 6341 } 6342 } 6343 6344 @Override 6345 public IBinder newUriPermissionOwner(String name) { 6346 enforceNotIsolatedCaller("newUriPermissionOwner"); 6347 synchronized(this) { 6348 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6349 return owner.getExternalTokenLocked(); 6350 } 6351 } 6352 6353 @Override 6354 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6355 Uri uri, int modeFlags) { 6356 synchronized(this) { 6357 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6358 if (owner == null) { 6359 throw new IllegalArgumentException("Unknown owner: " + token); 6360 } 6361 if (fromUid != Binder.getCallingUid()) { 6362 if (Binder.getCallingUid() != Process.myUid()) { 6363 // Only system code can grant URI permissions on behalf 6364 // of other users. 6365 throw new SecurityException("nice try"); 6366 } 6367 } 6368 if (targetPkg == null) { 6369 throw new IllegalArgumentException("null target"); 6370 } 6371 if (uri == null) { 6372 throw new IllegalArgumentException("null uri"); 6373 } 6374 6375 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6376 } 6377 } 6378 6379 @Override 6380 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6381 synchronized(this) { 6382 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6383 if (owner == null) { 6384 throw new IllegalArgumentException("Unknown owner: " + token); 6385 } 6386 6387 if (uri == null) { 6388 owner.removeUriPermissionsLocked(mode); 6389 } else { 6390 owner.removeUriPermissionLocked(uri, mode); 6391 } 6392 } 6393 } 6394 6395 private void schedulePersistUriGrants() { 6396 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6397 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6398 10 * DateUtils.SECOND_IN_MILLIS); 6399 } 6400 } 6401 6402 private void writeGrantedUriPermissions() { 6403 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6404 6405 // Snapshot permissions so we can persist without lock 6406 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6407 synchronized (this) { 6408 final int size = mGrantedUriPermissions.size(); 6409 for (int i = 0 ; i < size; i++) { 6410 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6411 if (perm.persistedModeFlags != 0) { 6412 persist.add(perm.snapshot()); 6413 } 6414 } 6415 } 6416 } 6417 6418 FileOutputStream fos = null; 6419 try { 6420 fos = mGrantFile.startWrite(); 6421 6422 XmlSerializer out = new FastXmlSerializer(); 6423 out.setOutput(fos, "utf-8"); 6424 out.startDocument(null, true); 6425 out.startTag(null, TAG_URI_GRANTS); 6426 for (UriPermission.Snapshot perm : persist) { 6427 out.startTag(null, TAG_URI_GRANT); 6428 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6429 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6430 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6431 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6432 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6433 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6434 out.endTag(null, TAG_URI_GRANT); 6435 } 6436 out.endTag(null, TAG_URI_GRANTS); 6437 out.endDocument(); 6438 6439 mGrantFile.finishWrite(fos); 6440 } catch (IOException e) { 6441 if (fos != null) { 6442 mGrantFile.failWrite(fos); 6443 } 6444 } 6445 } 6446 6447 private void readGrantedUriPermissionsLocked() { 6448 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6449 6450 final long now = System.currentTimeMillis(); 6451 6452 FileInputStream fis = null; 6453 try { 6454 fis = mGrantFile.openRead(); 6455 final XmlPullParser in = Xml.newPullParser(); 6456 in.setInput(fis, null); 6457 6458 int type; 6459 while ((type = in.next()) != END_DOCUMENT) { 6460 final String tag = in.getName(); 6461 if (type == START_TAG) { 6462 if (TAG_URI_GRANT.equals(tag)) { 6463 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6464 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6465 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6466 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6467 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6468 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6469 6470 // Sanity check that provider still belongs to source package 6471 final ProviderInfo pi = getProviderInfoLocked( 6472 uri.getAuthority(), userHandle); 6473 if (pi != null && sourcePkg.equals(pi.packageName)) { 6474 int targetUid = -1; 6475 try { 6476 targetUid = AppGlobals.getPackageManager() 6477 .getPackageUid(targetPkg, userHandle); 6478 } catch (RemoteException e) { 6479 } 6480 if (targetUid != -1) { 6481 final UriPermission perm = findOrCreateUriPermissionLocked( 6482 sourcePkg, targetPkg, targetUid, uri); 6483 perm.initPersistedModes(modeFlags, createdTime); 6484 } 6485 } else { 6486 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6487 + " but instead found " + pi); 6488 } 6489 } 6490 } 6491 } 6492 } catch (FileNotFoundException e) { 6493 // Missing grants is okay 6494 } catch (IOException e) { 6495 Log.wtf(TAG, "Failed reading Uri grants", e); 6496 } catch (XmlPullParserException e) { 6497 Log.wtf(TAG, "Failed reading Uri grants", e); 6498 } finally { 6499 IoUtils.closeQuietly(fis); 6500 } 6501 } 6502 6503 @Override 6504 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6505 enforceNotIsolatedCaller("takePersistableUriPermission"); 6506 6507 Preconditions.checkFlagsArgument(modeFlags, 6508 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6509 6510 synchronized (this) { 6511 final int callingUid = Binder.getCallingUid(); 6512 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6513 if (perm == null) { 6514 throw new SecurityException("No permission grant found for UID " + callingUid 6515 + " and Uri " + uri.toSafeString()); 6516 } 6517 6518 boolean persistChanged = perm.takePersistableModes(modeFlags); 6519 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6520 6521 if (persistChanged) { 6522 schedulePersistUriGrants(); 6523 } 6524 } 6525 } 6526 6527 @Override 6528 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6529 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6530 6531 Preconditions.checkFlagsArgument(modeFlags, 6532 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6533 6534 synchronized (this) { 6535 final int callingUid = Binder.getCallingUid(); 6536 6537 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6538 if (perm == null) { 6539 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6540 + uri.toSafeString()); 6541 return; 6542 } 6543 6544 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6545 removeUriPermissionIfNeededLocked(perm); 6546 if (persistChanged) { 6547 schedulePersistUriGrants(); 6548 } 6549 } 6550 } 6551 6552 /** 6553 * Prune any older {@link UriPermission} for the given UID until outstanding 6554 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6555 * 6556 * @return if any mutations occured that require persisting. 6557 */ 6558 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6559 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6560 if (perms == null) return false; 6561 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6562 6563 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6564 for (UriPermission perm : perms.values()) { 6565 if (perm.persistedModeFlags != 0) { 6566 persisted.add(perm); 6567 } 6568 } 6569 6570 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6571 if (trimCount <= 0) return false; 6572 6573 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6574 for (int i = 0; i < trimCount; i++) { 6575 final UriPermission perm = persisted.get(i); 6576 6577 if (DEBUG_URI_PERMISSION) { 6578 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6579 } 6580 6581 perm.releasePersistableModes(~0); 6582 removeUriPermissionIfNeededLocked(perm); 6583 } 6584 6585 return true; 6586 } 6587 6588 @Override 6589 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6590 String packageName, boolean incoming) { 6591 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6592 Preconditions.checkNotNull(packageName, "packageName"); 6593 6594 final int callingUid = Binder.getCallingUid(); 6595 final IPackageManager pm = AppGlobals.getPackageManager(); 6596 try { 6597 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6598 if (packageUid != callingUid) { 6599 throw new SecurityException( 6600 "Package " + packageName + " does not belong to calling UID " + callingUid); 6601 } 6602 } catch (RemoteException e) { 6603 throw new SecurityException("Failed to verify package name ownership"); 6604 } 6605 6606 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6607 synchronized (this) { 6608 if (incoming) { 6609 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6610 if (perms == null) { 6611 Slog.w(TAG, "No permission grants found for " + packageName); 6612 } else { 6613 final int size = perms.size(); 6614 for (int i = 0; i < size; i++) { 6615 final UriPermission perm = perms.valueAt(i); 6616 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6617 result.add(perm.buildPersistedPublicApiObject()); 6618 } 6619 } 6620 } 6621 } else { 6622 final int size = mGrantedUriPermissions.size(); 6623 for (int i = 0; i < size; i++) { 6624 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6625 final int permsSize = perms.size(); 6626 for (int j = 0; j < permsSize; j++) { 6627 final UriPermission perm = perms.valueAt(j); 6628 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6629 result.add(perm.buildPersistedPublicApiObject()); 6630 } 6631 } 6632 } 6633 } 6634 } 6635 return new ParceledListSlice<android.content.UriPermission>(result); 6636 } 6637 6638 @Override 6639 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6640 synchronized (this) { 6641 ProcessRecord app = 6642 who != null ? getRecordForAppLocked(who) : null; 6643 if (app == null) return; 6644 6645 Message msg = Message.obtain(); 6646 msg.what = WAIT_FOR_DEBUGGER_MSG; 6647 msg.obj = app; 6648 msg.arg1 = waiting ? 1 : 0; 6649 mHandler.sendMessage(msg); 6650 } 6651 } 6652 6653 @Override 6654 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6655 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6656 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6657 outInfo.availMem = Process.getFreeMemory(); 6658 outInfo.totalMem = Process.getTotalMemory(); 6659 outInfo.threshold = homeAppMem; 6660 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6661 outInfo.hiddenAppThreshold = cachedAppMem; 6662 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6663 ProcessList.SERVICE_ADJ); 6664 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6665 ProcessList.VISIBLE_APP_ADJ); 6666 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6667 ProcessList.FOREGROUND_APP_ADJ); 6668 } 6669 6670 // ========================================================= 6671 // TASK MANAGEMENT 6672 // ========================================================= 6673 6674 @Override 6675 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6676 IThumbnailReceiver receiver) { 6677 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6678 6679 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6680 ActivityRecord topRecord = null; 6681 6682 synchronized(this) { 6683 if (localLOGV) Slog.v( 6684 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6685 + ", receiver=" + receiver); 6686 6687 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6688 != PackageManager.PERMISSION_GRANTED) { 6689 if (receiver != null) { 6690 // If the caller wants to wait for pending thumbnails, 6691 // it ain't gonna get them. 6692 try { 6693 receiver.finished(); 6694 } catch (RemoteException ex) { 6695 } 6696 } 6697 String msg = "Permission Denial: getTasks() from pid=" 6698 + Binder.getCallingPid() 6699 + ", uid=" + Binder.getCallingUid() 6700 + " requires " + android.Manifest.permission.GET_TASKS; 6701 Slog.w(TAG, msg); 6702 throw new SecurityException(msg); 6703 } 6704 6705 // TODO: Improve with MRU list from all ActivityStacks. 6706 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6707 6708 if (!pending.pendingRecords.isEmpty()) { 6709 mPendingThumbnails.add(pending); 6710 } 6711 } 6712 6713 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6714 6715 if (topRecord != null) { 6716 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6717 try { 6718 IApplicationThread topThumbnail = topRecord.app.thread; 6719 topThumbnail.requestThumbnail(topRecord.appToken); 6720 } catch (Exception e) { 6721 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6722 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6723 } 6724 } 6725 6726 if (pending == null && receiver != null) { 6727 // In this case all thumbnails were available and the client 6728 // is being asked to be told when the remaining ones come in... 6729 // which is unusually, since the top-most currently running 6730 // activity should never have a canned thumbnail! Oh well. 6731 try { 6732 receiver.finished(); 6733 } catch (RemoteException ex) { 6734 } 6735 } 6736 6737 return list; 6738 } 6739 6740 TaskRecord getMostRecentTask() { 6741 return mRecentTasks.get(0); 6742 } 6743 6744 @Override 6745 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6746 int flags, int userId) { 6747 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6748 false, true, "getRecentTasks", null); 6749 6750 synchronized (this) { 6751 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6752 "getRecentTasks()"); 6753 final boolean detailed = checkCallingPermission( 6754 android.Manifest.permission.GET_DETAILED_TASKS) 6755 == PackageManager.PERMISSION_GRANTED; 6756 6757 IPackageManager pm = AppGlobals.getPackageManager(); 6758 6759 final int N = mRecentTasks.size(); 6760 ArrayList<ActivityManager.RecentTaskInfo> res 6761 = new ArrayList<ActivityManager.RecentTaskInfo>( 6762 maxNum < N ? maxNum : N); 6763 for (int i=0; i<N && maxNum > 0; i++) { 6764 TaskRecord tr = mRecentTasks.get(i); 6765 // Only add calling user's recent tasks 6766 if (tr.userId != userId) continue; 6767 // Return the entry if desired by the caller. We always return 6768 // the first entry, because callers always expect this to be the 6769 // foreground app. We may filter others if the caller has 6770 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6771 // we should exclude the entry. 6772 6773 if (i == 0 6774 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6775 || (tr.intent == null) 6776 || ((tr.intent.getFlags() 6777 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6778 ActivityManager.RecentTaskInfo rti 6779 = new ActivityManager.RecentTaskInfo(); 6780 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6781 rti.persistentId = tr.taskId; 6782 rti.baseIntent = new Intent( 6783 tr.intent != null ? tr.intent : tr.affinityIntent); 6784 if (!detailed) { 6785 rti.baseIntent.replaceExtras((Bundle)null); 6786 } 6787 rti.origActivity = tr.origActivity; 6788 rti.description = tr.lastDescription; 6789 rti.stackId = tr.stack.mStackId; 6790 6791 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6792 // Check whether this activity is currently available. 6793 try { 6794 if (rti.origActivity != null) { 6795 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6796 == null) { 6797 continue; 6798 } 6799 } else if (rti.baseIntent != null) { 6800 if (pm.queryIntentActivities(rti.baseIntent, 6801 null, 0, userId) == null) { 6802 continue; 6803 } 6804 } 6805 } catch (RemoteException e) { 6806 // Will never happen. 6807 } 6808 } 6809 6810 res.add(rti); 6811 maxNum--; 6812 } 6813 } 6814 return res; 6815 } 6816 } 6817 6818 private TaskRecord recentTaskForIdLocked(int id) { 6819 final int N = mRecentTasks.size(); 6820 for (int i=0; i<N; i++) { 6821 TaskRecord tr = mRecentTasks.get(i); 6822 if (tr.taskId == id) { 6823 return tr; 6824 } 6825 } 6826 return null; 6827 } 6828 6829 @Override 6830 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6831 synchronized (this) { 6832 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6833 "getTaskThumbnails()"); 6834 TaskRecord tr = recentTaskForIdLocked(id); 6835 if (tr != null) { 6836 return tr.getTaskThumbnailsLocked(); 6837 } 6838 } 6839 return null; 6840 } 6841 6842 @Override 6843 public Bitmap getTaskTopThumbnail(int id) { 6844 synchronized (this) { 6845 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6846 "getTaskTopThumbnail()"); 6847 TaskRecord tr = recentTaskForIdLocked(id); 6848 if (tr != null) { 6849 return tr.getTaskTopThumbnailLocked(); 6850 } 6851 } 6852 return null; 6853 } 6854 6855 @Override 6856 public boolean removeSubTask(int taskId, int subTaskIndex) { 6857 synchronized (this) { 6858 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6859 "removeSubTask()"); 6860 long ident = Binder.clearCallingIdentity(); 6861 try { 6862 TaskRecord tr = recentTaskForIdLocked(taskId); 6863 if (tr != null) { 6864 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6865 } 6866 return false; 6867 } finally { 6868 Binder.restoreCallingIdentity(ident); 6869 } 6870 } 6871 } 6872 6873 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6874 if (!pr.killedByAm) { 6875 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6876 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6877 pr.processName, pr.setAdj, reason); 6878 pr.killedByAm = true; 6879 Process.killProcessQuiet(pr.pid); 6880 } 6881 } 6882 6883 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6884 tr.disposeThumbnail(); 6885 mRecentTasks.remove(tr); 6886 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6887 Intent baseIntent = new Intent( 6888 tr.intent != null ? tr.intent : tr.affinityIntent); 6889 ComponentName component = baseIntent.getComponent(); 6890 if (component == null) { 6891 Slog.w(TAG, "Now component for base intent of task: " + tr); 6892 return; 6893 } 6894 6895 // Find any running services associated with this app. 6896 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6897 6898 if (killProcesses) { 6899 // Find any running processes associated with this app. 6900 final String pkg = component.getPackageName(); 6901 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6902 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 6903 for (int i=0; i<pmap.size(); i++) { 6904 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 6905 for (int j=0; j<uids.size(); j++) { 6906 ProcessRecord proc = uids.valueAt(j); 6907 if (proc.userId != tr.userId) { 6908 continue; 6909 } 6910 if (!proc.pkgList.containsKey(pkg)) { 6911 continue; 6912 } 6913 procs.add(proc); 6914 } 6915 } 6916 6917 // Kill the running processes. 6918 for (int i=0; i<procs.size(); i++) { 6919 ProcessRecord pr = procs.get(i); 6920 if (pr == mHomeProcess) { 6921 // Don't kill the home process along with tasks from the same package. 6922 continue; 6923 } 6924 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 6925 killUnneededProcessLocked(pr, "remove task"); 6926 } else { 6927 pr.waitingToKill = "remove task"; 6928 } 6929 } 6930 } 6931 } 6932 6933 @Override 6934 public boolean removeTask(int taskId, int flags) { 6935 synchronized (this) { 6936 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6937 "removeTask()"); 6938 long ident = Binder.clearCallingIdentity(); 6939 try { 6940 TaskRecord tr = recentTaskForIdLocked(taskId); 6941 if (tr != null) { 6942 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 6943 if (r != null) { 6944 cleanUpRemovedTaskLocked(tr, flags); 6945 return true; 6946 } 6947 if (tr.mActivities.size() == 0) { 6948 // Caller is just removing a recent task that is 6949 // not actively running. That is easy! 6950 cleanUpRemovedTaskLocked(tr, flags); 6951 return true; 6952 } 6953 Slog.w(TAG, "removeTask: task " + taskId 6954 + " does not have activities to remove, " 6955 + " but numActivities=" + tr.numActivities 6956 + ": " + tr); 6957 } 6958 } finally { 6959 Binder.restoreCallingIdentity(ident); 6960 } 6961 } 6962 return false; 6963 } 6964 6965 /** 6966 * TODO: Add mController hook 6967 */ 6968 @Override 6969 public void moveTaskToFront(int task, int flags, Bundle options) { 6970 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6971 "moveTaskToFront()"); 6972 6973 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task); 6974 synchronized(this) { 6975 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6976 Binder.getCallingUid(), "Task to front")) { 6977 ActivityOptions.abort(options); 6978 return; 6979 } 6980 final long origId = Binder.clearCallingIdentity(); 6981 try { 6982 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 6983 } finally { 6984 Binder.restoreCallingIdentity(origId); 6985 } 6986 ActivityOptions.abort(options); 6987 } 6988 } 6989 6990 @Override 6991 public void moveTaskToBack(int taskId) { 6992 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6993 "moveTaskToBack()"); 6994 6995 synchronized(this) { 6996 TaskRecord tr = recentTaskForIdLocked(taskId); 6997 if (tr != null) { 6998 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 6999 ActivityStack stack = tr.stack; 7000 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7001 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7002 Binder.getCallingUid(), "Task to back")) { 7003 return; 7004 } 7005 } 7006 final long origId = Binder.clearCallingIdentity(); 7007 try { 7008 stack.moveTaskToBackLocked(taskId, null); 7009 } finally { 7010 Binder.restoreCallingIdentity(origId); 7011 } 7012 } 7013 } 7014 } 7015 7016 /** 7017 * Moves an activity, and all of the other activities within the same task, to the bottom 7018 * of the history stack. The activity's order within the task is unchanged. 7019 * 7020 * @param token A reference to the activity we wish to move 7021 * @param nonRoot If false then this only works if the activity is the root 7022 * of a task; if true it will work for any activity in a task. 7023 * @return Returns true if the move completed, false if not. 7024 */ 7025 @Override 7026 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7027 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7028 synchronized(this) { 7029 final long origId = Binder.clearCallingIdentity(); 7030 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7031 if (taskId >= 0) { 7032 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7033 } 7034 Binder.restoreCallingIdentity(origId); 7035 } 7036 return false; 7037 } 7038 7039 @Override 7040 public void moveTaskBackwards(int task) { 7041 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7042 "moveTaskBackwards()"); 7043 7044 synchronized(this) { 7045 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7046 Binder.getCallingUid(), "Task backwards")) { 7047 return; 7048 } 7049 final long origId = Binder.clearCallingIdentity(); 7050 moveTaskBackwardsLocked(task); 7051 Binder.restoreCallingIdentity(origId); 7052 } 7053 } 7054 7055 private final void moveTaskBackwardsLocked(int task) { 7056 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7057 } 7058 7059 @Override 7060 public IBinder getHomeActivityToken() throws RemoteException { 7061 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7062 "getHomeActivityToken()"); 7063 synchronized (this) { 7064 return mStackSupervisor.getHomeActivityToken(); 7065 } 7066 } 7067 7068 @Override 7069 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7070 IActivityContainerCallback callback) throws RemoteException { 7071 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7072 "createActivityContainer()"); 7073 synchronized (this) { 7074 if (parentActivityToken == null) { 7075 throw new IllegalArgumentException("parent token must not be null"); 7076 } 7077 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7078 if (r == null) { 7079 return null; 7080 } 7081 return mStackSupervisor.createActivityContainer(r, callback); 7082 } 7083 } 7084 7085 @Override 7086 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7087 throws RemoteException { 7088 synchronized (this) { 7089 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7090 if (stack != null) { 7091 return stack.mActivityContainer; 7092 } 7093 return null; 7094 } 7095 } 7096 7097 @Override 7098 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7099 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7100 "moveTaskToStack()"); 7101 if (stackId == HOME_STACK_ID) { 7102 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7103 new RuntimeException("here").fillInStackTrace()); 7104 } 7105 synchronized (this) { 7106 long ident = Binder.clearCallingIdentity(); 7107 try { 7108 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7109 + stackId + " toTop=" + toTop); 7110 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7111 } finally { 7112 Binder.restoreCallingIdentity(ident); 7113 } 7114 } 7115 } 7116 7117 @Override 7118 public void resizeStack(int stackBoxId, Rect bounds) { 7119 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7120 "resizeStackBox()"); 7121 long ident = Binder.clearCallingIdentity(); 7122 try { 7123 mWindowManager.resizeStack(stackBoxId, bounds); 7124 } finally { 7125 Binder.restoreCallingIdentity(ident); 7126 } 7127 } 7128 7129 @Override 7130 public List<StackInfo> getAllStackInfos() { 7131 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7132 "getAllStackInfos()"); 7133 long ident = Binder.clearCallingIdentity(); 7134 try { 7135 synchronized (this) { 7136 return mStackSupervisor.getAllStackInfosLocked(); 7137 } 7138 } finally { 7139 Binder.restoreCallingIdentity(ident); 7140 } 7141 } 7142 7143 @Override 7144 public StackInfo getStackInfo(int stackId) { 7145 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7146 "getStackInfo()"); 7147 long ident = Binder.clearCallingIdentity(); 7148 try { 7149 synchronized (this) { 7150 return mStackSupervisor.getStackInfoLocked(stackId); 7151 } 7152 } finally { 7153 Binder.restoreCallingIdentity(ident); 7154 } 7155 } 7156 7157 @Override 7158 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7159 synchronized(this) { 7160 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7161 } 7162 } 7163 7164 // ========================================================= 7165 // THUMBNAILS 7166 // ========================================================= 7167 7168 public void reportThumbnail(IBinder token, 7169 Bitmap thumbnail, CharSequence description) { 7170 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7171 final long origId = Binder.clearCallingIdentity(); 7172 sendPendingThumbnail(null, token, thumbnail, description, true); 7173 Binder.restoreCallingIdentity(origId); 7174 } 7175 7176 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7177 Bitmap thumbnail, CharSequence description, boolean always) { 7178 TaskRecord task; 7179 ArrayList<PendingThumbnailsRecord> receivers = null; 7180 7181 //System.out.println("Send pending thumbnail: " + r); 7182 7183 synchronized(this) { 7184 if (r == null) { 7185 r = ActivityRecord.isInStackLocked(token); 7186 if (r == null) { 7187 return; 7188 } 7189 } 7190 if (thumbnail == null && r.thumbHolder != null) { 7191 thumbnail = r.thumbHolder.lastThumbnail; 7192 description = r.thumbHolder.lastDescription; 7193 } 7194 if (thumbnail == null && !always) { 7195 // If there is no thumbnail, and this entry is not actually 7196 // going away, then abort for now and pick up the next 7197 // thumbnail we get. 7198 return; 7199 } 7200 task = r.task; 7201 7202 int N = mPendingThumbnails.size(); 7203 int i=0; 7204 while (i<N) { 7205 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7206 //System.out.println("Looking in " + pr.pendingRecords); 7207 if (pr.pendingRecords.remove(r)) { 7208 if (receivers == null) { 7209 receivers = new ArrayList<PendingThumbnailsRecord>(); 7210 } 7211 receivers.add(pr); 7212 if (pr.pendingRecords.size() == 0) { 7213 pr.finished = true; 7214 mPendingThumbnails.remove(i); 7215 N--; 7216 continue; 7217 } 7218 } 7219 i++; 7220 } 7221 } 7222 7223 if (receivers != null) { 7224 final int N = receivers.size(); 7225 for (int i=0; i<N; i++) { 7226 try { 7227 PendingThumbnailsRecord pr = receivers.get(i); 7228 pr.receiver.newThumbnail( 7229 task != null ? task.taskId : -1, thumbnail, description); 7230 if (pr.finished) { 7231 pr.receiver.finished(); 7232 } 7233 } catch (Exception e) { 7234 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7235 } 7236 } 7237 } 7238 } 7239 7240 // ========================================================= 7241 // CONTENT PROVIDERS 7242 // ========================================================= 7243 7244 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7245 List<ProviderInfo> providers = null; 7246 try { 7247 providers = AppGlobals.getPackageManager(). 7248 queryContentProviders(app.processName, app.uid, 7249 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7250 } catch (RemoteException ex) { 7251 } 7252 if (DEBUG_MU) 7253 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7254 int userId = app.userId; 7255 if (providers != null) { 7256 int N = providers.size(); 7257 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7258 for (int i=0; i<N; i++) { 7259 ProviderInfo cpi = 7260 (ProviderInfo)providers.get(i); 7261 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7262 cpi.name, cpi.flags); 7263 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7264 // This is a singleton provider, but a user besides the 7265 // default user is asking to initialize a process it runs 7266 // in... well, no, it doesn't actually run in this process, 7267 // it runs in the process of the default user. Get rid of it. 7268 providers.remove(i); 7269 N--; 7270 i--; 7271 continue; 7272 } 7273 7274 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7275 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7276 if (cpr == null) { 7277 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7278 mProviderMap.putProviderByClass(comp, cpr); 7279 } 7280 if (DEBUG_MU) 7281 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7282 app.pubProviders.put(cpi.name, cpr); 7283 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7284 // Don't add this if it is a platform component that is marked 7285 // to run in multiple processes, because this is actually 7286 // part of the framework so doesn't make sense to track as a 7287 // separate apk in the process. 7288 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7289 } 7290 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7291 } 7292 } 7293 return providers; 7294 } 7295 7296 /** 7297 * Check if {@link ProcessRecord} has a possible chance at accessing the 7298 * given {@link ProviderInfo}. Final permission checking is always done 7299 * in {@link ContentProvider}. 7300 */ 7301 private final String checkContentProviderPermissionLocked( 7302 ProviderInfo cpi, ProcessRecord r) { 7303 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7304 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7305 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7306 cpi.applicationInfo.uid, cpi.exported) 7307 == PackageManager.PERMISSION_GRANTED) { 7308 return null; 7309 } 7310 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7311 cpi.applicationInfo.uid, cpi.exported) 7312 == PackageManager.PERMISSION_GRANTED) { 7313 return null; 7314 } 7315 7316 PathPermission[] pps = cpi.pathPermissions; 7317 if (pps != null) { 7318 int i = pps.length; 7319 while (i > 0) { 7320 i--; 7321 PathPermission pp = pps[i]; 7322 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7323 cpi.applicationInfo.uid, cpi.exported) 7324 == PackageManager.PERMISSION_GRANTED) { 7325 return null; 7326 } 7327 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7328 cpi.applicationInfo.uid, cpi.exported) 7329 == PackageManager.PERMISSION_GRANTED) { 7330 return null; 7331 } 7332 } 7333 } 7334 7335 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7336 if (perms != null) { 7337 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7338 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7339 return null; 7340 } 7341 } 7342 } 7343 7344 String msg; 7345 if (!cpi.exported) { 7346 msg = "Permission Denial: opening provider " + cpi.name 7347 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7348 + ", uid=" + callingUid + ") that is not exported from uid " 7349 + cpi.applicationInfo.uid; 7350 } else { 7351 msg = "Permission Denial: opening provider " + cpi.name 7352 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7353 + ", uid=" + callingUid + ") requires " 7354 + cpi.readPermission + " or " + cpi.writePermission; 7355 } 7356 Slog.w(TAG, msg); 7357 return msg; 7358 } 7359 7360 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7361 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7362 if (r != null) { 7363 for (int i=0; i<r.conProviders.size(); i++) { 7364 ContentProviderConnection conn = r.conProviders.get(i); 7365 if (conn.provider == cpr) { 7366 if (DEBUG_PROVIDER) Slog.v(TAG, 7367 "Adding provider requested by " 7368 + r.processName + " from process " 7369 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7370 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7371 if (stable) { 7372 conn.stableCount++; 7373 conn.numStableIncs++; 7374 } else { 7375 conn.unstableCount++; 7376 conn.numUnstableIncs++; 7377 } 7378 return conn; 7379 } 7380 } 7381 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7382 if (stable) { 7383 conn.stableCount = 1; 7384 conn.numStableIncs = 1; 7385 } else { 7386 conn.unstableCount = 1; 7387 conn.numUnstableIncs = 1; 7388 } 7389 cpr.connections.add(conn); 7390 r.conProviders.add(conn); 7391 return conn; 7392 } 7393 cpr.addExternalProcessHandleLocked(externalProcessToken); 7394 return null; 7395 } 7396 7397 boolean decProviderCountLocked(ContentProviderConnection conn, 7398 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7399 if (conn != null) { 7400 cpr = conn.provider; 7401 if (DEBUG_PROVIDER) Slog.v(TAG, 7402 "Removing provider requested by " 7403 + conn.client.processName + " from process " 7404 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7405 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7406 if (stable) { 7407 conn.stableCount--; 7408 } else { 7409 conn.unstableCount--; 7410 } 7411 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7412 cpr.connections.remove(conn); 7413 conn.client.conProviders.remove(conn); 7414 return true; 7415 } 7416 return false; 7417 } 7418 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7419 return false; 7420 } 7421 7422 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7423 String name, IBinder token, boolean stable, int userId) { 7424 ContentProviderRecord cpr; 7425 ContentProviderConnection conn = null; 7426 ProviderInfo cpi = null; 7427 7428 synchronized(this) { 7429 ProcessRecord r = null; 7430 if (caller != null) { 7431 r = getRecordForAppLocked(caller); 7432 if (r == null) { 7433 throw new SecurityException( 7434 "Unable to find app for caller " + caller 7435 + " (pid=" + Binder.getCallingPid() 7436 + ") when getting content provider " + name); 7437 } 7438 } 7439 7440 // First check if this content provider has been published... 7441 cpr = mProviderMap.getProviderByName(name, userId); 7442 boolean providerRunning = cpr != null; 7443 if (providerRunning) { 7444 cpi = cpr.info; 7445 String msg; 7446 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7447 throw new SecurityException(msg); 7448 } 7449 7450 if (r != null && cpr.canRunHere(r)) { 7451 // This provider has been published or is in the process 7452 // of being published... but it is also allowed to run 7453 // in the caller's process, so don't make a connection 7454 // and just let the caller instantiate its own instance. 7455 ContentProviderHolder holder = cpr.newHolder(null); 7456 // don't give caller the provider object, it needs 7457 // to make its own. 7458 holder.provider = null; 7459 return holder; 7460 } 7461 7462 final long origId = Binder.clearCallingIdentity(); 7463 7464 // In this case the provider instance already exists, so we can 7465 // return it right away. 7466 conn = incProviderCountLocked(r, cpr, token, stable); 7467 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7468 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7469 // If this is a perceptible app accessing the provider, 7470 // make sure to count it as being accessed and thus 7471 // back up on the LRU list. This is good because 7472 // content providers are often expensive to start. 7473 updateLruProcessLocked(cpr.proc, false, null); 7474 } 7475 } 7476 7477 if (cpr.proc != null) { 7478 if (false) { 7479 if (cpr.name.flattenToShortString().equals( 7480 "com.android.providers.calendar/.CalendarProvider2")) { 7481 Slog.v(TAG, "****************** KILLING " 7482 + cpr.name.flattenToShortString()); 7483 Process.killProcess(cpr.proc.pid); 7484 } 7485 } 7486 boolean success = updateOomAdjLocked(cpr.proc); 7487 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7488 // NOTE: there is still a race here where a signal could be 7489 // pending on the process even though we managed to update its 7490 // adj level. Not sure what to do about this, but at least 7491 // the race is now smaller. 7492 if (!success) { 7493 // Uh oh... it looks like the provider's process 7494 // has been killed on us. We need to wait for a new 7495 // process to be started, and make sure its death 7496 // doesn't kill our process. 7497 Slog.i(TAG, 7498 "Existing provider " + cpr.name.flattenToShortString() 7499 + " is crashing; detaching " + r); 7500 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7501 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7502 if (!lastRef) { 7503 // This wasn't the last ref our process had on 7504 // the provider... we have now been killed, bail. 7505 return null; 7506 } 7507 providerRunning = false; 7508 conn = null; 7509 } 7510 } 7511 7512 Binder.restoreCallingIdentity(origId); 7513 } 7514 7515 boolean singleton; 7516 if (!providerRunning) { 7517 try { 7518 cpi = AppGlobals.getPackageManager(). 7519 resolveContentProvider(name, 7520 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7521 } catch (RemoteException ex) { 7522 } 7523 if (cpi == null) { 7524 return null; 7525 } 7526 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7527 cpi.name, cpi.flags); 7528 if (singleton) { 7529 userId = 0; 7530 } 7531 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7532 7533 String msg; 7534 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7535 throw new SecurityException(msg); 7536 } 7537 7538 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7539 && !cpi.processName.equals("system")) { 7540 // If this content provider does not run in the system 7541 // process, and the system is not yet ready to run other 7542 // processes, then fail fast instead of hanging. 7543 throw new IllegalArgumentException( 7544 "Attempt to launch content provider before system ready"); 7545 } 7546 7547 // Make sure that the user who owns this provider is started. If not, 7548 // we don't want to allow it to run. 7549 if (mStartedUsers.get(userId) == null) { 7550 Slog.w(TAG, "Unable to launch app " 7551 + cpi.applicationInfo.packageName + "/" 7552 + cpi.applicationInfo.uid + " for provider " 7553 + name + ": user " + userId + " is stopped"); 7554 return null; 7555 } 7556 7557 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7558 cpr = mProviderMap.getProviderByClass(comp, userId); 7559 final boolean firstClass = cpr == null; 7560 if (firstClass) { 7561 try { 7562 ApplicationInfo ai = 7563 AppGlobals.getPackageManager(). 7564 getApplicationInfo( 7565 cpi.applicationInfo.packageName, 7566 STOCK_PM_FLAGS, userId); 7567 if (ai == null) { 7568 Slog.w(TAG, "No package info for content provider " 7569 + cpi.name); 7570 return null; 7571 } 7572 ai = getAppInfoForUser(ai, userId); 7573 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7574 } catch (RemoteException ex) { 7575 // pm is in same process, this will never happen. 7576 } 7577 } 7578 7579 if (r != null && cpr.canRunHere(r)) { 7580 // If this is a multiprocess provider, then just return its 7581 // info and allow the caller to instantiate it. Only do 7582 // this if the provider is the same user as the caller's 7583 // process, or can run as root (so can be in any process). 7584 return cpr.newHolder(null); 7585 } 7586 7587 if (DEBUG_PROVIDER) { 7588 RuntimeException e = new RuntimeException("here"); 7589 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7590 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7591 } 7592 7593 // This is single process, and our app is now connecting to it. 7594 // See if we are already in the process of launching this 7595 // provider. 7596 final int N = mLaunchingProviders.size(); 7597 int i; 7598 for (i=0; i<N; i++) { 7599 if (mLaunchingProviders.get(i) == cpr) { 7600 break; 7601 } 7602 } 7603 7604 // If the provider is not already being launched, then get it 7605 // started. 7606 if (i >= N) { 7607 final long origId = Binder.clearCallingIdentity(); 7608 7609 try { 7610 // Content provider is now in use, its package can't be stopped. 7611 try { 7612 AppGlobals.getPackageManager().setPackageStoppedState( 7613 cpr.appInfo.packageName, false, userId); 7614 } catch (RemoteException e) { 7615 } catch (IllegalArgumentException e) { 7616 Slog.w(TAG, "Failed trying to unstop package " 7617 + cpr.appInfo.packageName + ": " + e); 7618 } 7619 7620 // Use existing process if already started 7621 ProcessRecord proc = getProcessRecordLocked( 7622 cpi.processName, cpr.appInfo.uid, false); 7623 if (proc != null && proc.thread != null) { 7624 if (DEBUG_PROVIDER) { 7625 Slog.d(TAG, "Installing in existing process " + proc); 7626 } 7627 proc.pubProviders.put(cpi.name, cpr); 7628 try { 7629 proc.thread.scheduleInstallProvider(cpi); 7630 } catch (RemoteException e) { 7631 } 7632 } else { 7633 proc = startProcessLocked(cpi.processName, 7634 cpr.appInfo, false, 0, "content provider", 7635 new ComponentName(cpi.applicationInfo.packageName, 7636 cpi.name), false, false, false); 7637 if (proc == null) { 7638 Slog.w(TAG, "Unable to launch app " 7639 + cpi.applicationInfo.packageName + "/" 7640 + cpi.applicationInfo.uid + " for provider " 7641 + name + ": process is bad"); 7642 return null; 7643 } 7644 } 7645 cpr.launchingApp = proc; 7646 mLaunchingProviders.add(cpr); 7647 } finally { 7648 Binder.restoreCallingIdentity(origId); 7649 } 7650 } 7651 7652 // Make sure the provider is published (the same provider class 7653 // may be published under multiple names). 7654 if (firstClass) { 7655 mProviderMap.putProviderByClass(comp, cpr); 7656 } 7657 7658 mProviderMap.putProviderByName(name, cpr); 7659 conn = incProviderCountLocked(r, cpr, token, stable); 7660 if (conn != null) { 7661 conn.waiting = true; 7662 } 7663 } 7664 } 7665 7666 // Wait for the provider to be published... 7667 synchronized (cpr) { 7668 while (cpr.provider == null) { 7669 if (cpr.launchingApp == null) { 7670 Slog.w(TAG, "Unable to launch app " 7671 + cpi.applicationInfo.packageName + "/" 7672 + cpi.applicationInfo.uid + " for provider " 7673 + name + ": launching app became null"); 7674 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7675 UserHandle.getUserId(cpi.applicationInfo.uid), 7676 cpi.applicationInfo.packageName, 7677 cpi.applicationInfo.uid, name); 7678 return null; 7679 } 7680 try { 7681 if (DEBUG_MU) { 7682 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7683 + cpr.launchingApp); 7684 } 7685 if (conn != null) { 7686 conn.waiting = true; 7687 } 7688 cpr.wait(); 7689 } catch (InterruptedException ex) { 7690 } finally { 7691 if (conn != null) { 7692 conn.waiting = false; 7693 } 7694 } 7695 } 7696 } 7697 return cpr != null ? cpr.newHolder(conn) : null; 7698 } 7699 7700 public final ContentProviderHolder getContentProvider( 7701 IApplicationThread caller, String name, int userId, boolean stable) { 7702 enforceNotIsolatedCaller("getContentProvider"); 7703 if (caller == null) { 7704 String msg = "null IApplicationThread when getting content provider " 7705 + name; 7706 Slog.w(TAG, msg); 7707 throw new SecurityException(msg); 7708 } 7709 7710 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7711 false, true, "getContentProvider", null); 7712 return getContentProviderImpl(caller, name, null, stable, userId); 7713 } 7714 7715 public ContentProviderHolder getContentProviderExternal( 7716 String name, int userId, IBinder token) { 7717 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7718 "Do not have permission in call getContentProviderExternal()"); 7719 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7720 false, true, "getContentProvider", null); 7721 return getContentProviderExternalUnchecked(name, token, userId); 7722 } 7723 7724 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7725 IBinder token, int userId) { 7726 return getContentProviderImpl(null, name, token, true, userId); 7727 } 7728 7729 /** 7730 * Drop a content provider from a ProcessRecord's bookkeeping 7731 */ 7732 public void removeContentProvider(IBinder connection, boolean stable) { 7733 enforceNotIsolatedCaller("removeContentProvider"); 7734 synchronized (this) { 7735 ContentProviderConnection conn; 7736 try { 7737 conn = (ContentProviderConnection)connection; 7738 } catch (ClassCastException e) { 7739 String msg ="removeContentProvider: " + connection 7740 + " not a ContentProviderConnection"; 7741 Slog.w(TAG, msg); 7742 throw new IllegalArgumentException(msg); 7743 } 7744 if (conn == null) { 7745 throw new NullPointerException("connection is null"); 7746 } 7747 if (decProviderCountLocked(conn, null, null, stable)) { 7748 updateOomAdjLocked(); 7749 } 7750 } 7751 } 7752 7753 public void removeContentProviderExternal(String name, IBinder token) { 7754 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7755 "Do not have permission in call removeContentProviderExternal()"); 7756 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7757 } 7758 7759 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7760 synchronized (this) { 7761 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7762 if(cpr == null) { 7763 //remove from mProvidersByClass 7764 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7765 return; 7766 } 7767 7768 //update content provider record entry info 7769 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7770 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7771 if (localCpr.hasExternalProcessHandles()) { 7772 if (localCpr.removeExternalProcessHandleLocked(token)) { 7773 updateOomAdjLocked(); 7774 } else { 7775 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7776 + " with no external reference for token: " 7777 + token + "."); 7778 } 7779 } else { 7780 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7781 + " with no external references."); 7782 } 7783 } 7784 } 7785 7786 public final void publishContentProviders(IApplicationThread caller, 7787 List<ContentProviderHolder> providers) { 7788 if (providers == null) { 7789 return; 7790 } 7791 7792 enforceNotIsolatedCaller("publishContentProviders"); 7793 synchronized (this) { 7794 final ProcessRecord r = getRecordForAppLocked(caller); 7795 if (DEBUG_MU) 7796 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 7797 if (r == null) { 7798 throw new SecurityException( 7799 "Unable to find app for caller " + caller 7800 + " (pid=" + Binder.getCallingPid() 7801 + ") when publishing content providers"); 7802 } 7803 7804 final long origId = Binder.clearCallingIdentity(); 7805 7806 final int N = providers.size(); 7807 for (int i=0; i<N; i++) { 7808 ContentProviderHolder src = providers.get(i); 7809 if (src == null || src.info == null || src.provider == null) { 7810 continue; 7811 } 7812 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 7813 if (DEBUG_MU) 7814 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 7815 if (dst != null) { 7816 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 7817 mProviderMap.putProviderByClass(comp, dst); 7818 String names[] = dst.info.authority.split(";"); 7819 for (int j = 0; j < names.length; j++) { 7820 mProviderMap.putProviderByName(names[j], dst); 7821 } 7822 7823 int NL = mLaunchingProviders.size(); 7824 int j; 7825 for (j=0; j<NL; j++) { 7826 if (mLaunchingProviders.get(j) == dst) { 7827 mLaunchingProviders.remove(j); 7828 j--; 7829 NL--; 7830 } 7831 } 7832 synchronized (dst) { 7833 dst.provider = src.provider; 7834 dst.proc = r; 7835 dst.notifyAll(); 7836 } 7837 updateOomAdjLocked(r); 7838 } 7839 } 7840 7841 Binder.restoreCallingIdentity(origId); 7842 } 7843 } 7844 7845 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 7846 ContentProviderConnection conn; 7847 try { 7848 conn = (ContentProviderConnection)connection; 7849 } catch (ClassCastException e) { 7850 String msg ="refContentProvider: " + connection 7851 + " not a ContentProviderConnection"; 7852 Slog.w(TAG, msg); 7853 throw new IllegalArgumentException(msg); 7854 } 7855 if (conn == null) { 7856 throw new NullPointerException("connection is null"); 7857 } 7858 7859 synchronized (this) { 7860 if (stable > 0) { 7861 conn.numStableIncs += stable; 7862 } 7863 stable = conn.stableCount + stable; 7864 if (stable < 0) { 7865 throw new IllegalStateException("stableCount < 0: " + stable); 7866 } 7867 7868 if (unstable > 0) { 7869 conn.numUnstableIncs += unstable; 7870 } 7871 unstable = conn.unstableCount + unstable; 7872 if (unstable < 0) { 7873 throw new IllegalStateException("unstableCount < 0: " + unstable); 7874 } 7875 7876 if ((stable+unstable) <= 0) { 7877 throw new IllegalStateException("ref counts can't go to zero here: stable=" 7878 + stable + " unstable=" + unstable); 7879 } 7880 conn.stableCount = stable; 7881 conn.unstableCount = unstable; 7882 return !conn.dead; 7883 } 7884 } 7885 7886 public void unstableProviderDied(IBinder connection) { 7887 ContentProviderConnection conn; 7888 try { 7889 conn = (ContentProviderConnection)connection; 7890 } catch (ClassCastException e) { 7891 String msg ="refContentProvider: " + connection 7892 + " not a ContentProviderConnection"; 7893 Slog.w(TAG, msg); 7894 throw new IllegalArgumentException(msg); 7895 } 7896 if (conn == null) { 7897 throw new NullPointerException("connection is null"); 7898 } 7899 7900 // Safely retrieve the content provider associated with the connection. 7901 IContentProvider provider; 7902 synchronized (this) { 7903 provider = conn.provider.provider; 7904 } 7905 7906 if (provider == null) { 7907 // Um, yeah, we're way ahead of you. 7908 return; 7909 } 7910 7911 // Make sure the caller is being honest with us. 7912 if (provider.asBinder().pingBinder()) { 7913 // Er, no, still looks good to us. 7914 synchronized (this) { 7915 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 7916 + " says " + conn + " died, but we don't agree"); 7917 return; 7918 } 7919 } 7920 7921 // Well look at that! It's dead! 7922 synchronized (this) { 7923 if (conn.provider.provider != provider) { 7924 // But something changed... good enough. 7925 return; 7926 } 7927 7928 ProcessRecord proc = conn.provider.proc; 7929 if (proc == null || proc.thread == null) { 7930 // Seems like the process is already cleaned up. 7931 return; 7932 } 7933 7934 // As far as we're concerned, this is just like receiving a 7935 // death notification... just a bit prematurely. 7936 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 7937 + ") early provider death"); 7938 final long ident = Binder.clearCallingIdentity(); 7939 try { 7940 appDiedLocked(proc, proc.pid, proc.thread); 7941 } finally { 7942 Binder.restoreCallingIdentity(ident); 7943 } 7944 } 7945 } 7946 7947 @Override 7948 public void appNotRespondingViaProvider(IBinder connection) { 7949 enforceCallingPermission( 7950 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 7951 7952 final ContentProviderConnection conn = (ContentProviderConnection) connection; 7953 if (conn == null) { 7954 Slog.w(TAG, "ContentProviderConnection is null"); 7955 return; 7956 } 7957 7958 final ProcessRecord host = conn.provider.proc; 7959 if (host == null) { 7960 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 7961 return; 7962 } 7963 7964 final long token = Binder.clearCallingIdentity(); 7965 try { 7966 appNotResponding(host, null, null, false, "ContentProvider not responding"); 7967 } finally { 7968 Binder.restoreCallingIdentity(token); 7969 } 7970 } 7971 7972 public final void installSystemProviders() { 7973 List<ProviderInfo> providers; 7974 synchronized (this) { 7975 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 7976 providers = generateApplicationProvidersLocked(app); 7977 if (providers != null) { 7978 for (int i=providers.size()-1; i>=0; i--) { 7979 ProviderInfo pi = (ProviderInfo)providers.get(i); 7980 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 7981 Slog.w(TAG, "Not installing system proc provider " + pi.name 7982 + ": not system .apk"); 7983 providers.remove(i); 7984 } 7985 } 7986 } 7987 } 7988 if (providers != null) { 7989 mSystemThread.installSystemProviders(providers); 7990 } 7991 7992 mCoreSettingsObserver = new CoreSettingsObserver(this); 7993 7994 mUsageStatsService.monitorPackages(); 7995 } 7996 7997 /** 7998 * Allows app to retrieve the MIME type of a URI without having permission 7999 * to access its content provider. 8000 * 8001 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8002 * 8003 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8004 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8005 */ 8006 public String getProviderMimeType(Uri uri, int userId) { 8007 enforceNotIsolatedCaller("getProviderMimeType"); 8008 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8009 userId, false, true, "getProviderMimeType", null); 8010 final String name = uri.getAuthority(); 8011 final long ident = Binder.clearCallingIdentity(); 8012 ContentProviderHolder holder = null; 8013 8014 try { 8015 holder = getContentProviderExternalUnchecked(name, null, userId); 8016 if (holder != null) { 8017 return holder.provider.getType(uri); 8018 } 8019 } catch (RemoteException e) { 8020 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8021 return null; 8022 } finally { 8023 if (holder != null) { 8024 removeContentProviderExternalUnchecked(name, null, userId); 8025 } 8026 Binder.restoreCallingIdentity(ident); 8027 } 8028 8029 return null; 8030 } 8031 8032 // ========================================================= 8033 // GLOBAL MANAGEMENT 8034 // ========================================================= 8035 8036 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8037 boolean isolated) { 8038 String proc = customProcess != null ? customProcess : info.processName; 8039 BatteryStatsImpl.Uid.Proc ps = null; 8040 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8041 int uid = info.uid; 8042 if (isolated) { 8043 int userId = UserHandle.getUserId(uid); 8044 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8045 while (true) { 8046 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8047 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8048 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8049 } 8050 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8051 mNextIsolatedProcessUid++; 8052 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8053 // No process for this uid, use it. 8054 break; 8055 } 8056 stepsLeft--; 8057 if (stepsLeft <= 0) { 8058 return null; 8059 } 8060 } 8061 } 8062 return new ProcessRecord(stats, info, proc, uid); 8063 } 8064 8065 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8066 ProcessRecord app; 8067 if (!isolated) { 8068 app = getProcessRecordLocked(info.processName, info.uid, true); 8069 } else { 8070 app = null; 8071 } 8072 8073 if (app == null) { 8074 app = newProcessRecordLocked(info, null, isolated); 8075 mProcessNames.put(info.processName, app.uid, app); 8076 if (isolated) { 8077 mIsolatedProcesses.put(app.uid, app); 8078 } 8079 updateLruProcessLocked(app, false, null); 8080 updateOomAdjLocked(); 8081 } 8082 8083 // This package really, really can not be stopped. 8084 try { 8085 AppGlobals.getPackageManager().setPackageStoppedState( 8086 info.packageName, false, UserHandle.getUserId(app.uid)); 8087 } catch (RemoteException e) { 8088 } catch (IllegalArgumentException e) { 8089 Slog.w(TAG, "Failed trying to unstop package " 8090 + info.packageName + ": " + e); 8091 } 8092 8093 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8094 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8095 app.persistent = true; 8096 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8097 } 8098 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8099 mPersistentStartingProcesses.add(app); 8100 startProcessLocked(app, "added application", app.processName); 8101 } 8102 8103 return app; 8104 } 8105 8106 public void unhandledBack() { 8107 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8108 "unhandledBack()"); 8109 8110 synchronized(this) { 8111 final long origId = Binder.clearCallingIdentity(); 8112 try { 8113 getFocusedStack().unhandledBackLocked(); 8114 } finally { 8115 Binder.restoreCallingIdentity(origId); 8116 } 8117 } 8118 } 8119 8120 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8121 enforceNotIsolatedCaller("openContentUri"); 8122 final int userId = UserHandle.getCallingUserId(); 8123 String name = uri.getAuthority(); 8124 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8125 ParcelFileDescriptor pfd = null; 8126 if (cph != null) { 8127 // We record the binder invoker's uid in thread-local storage before 8128 // going to the content provider to open the file. Later, in the code 8129 // that handles all permissions checks, we look for this uid and use 8130 // that rather than the Activity Manager's own uid. The effect is that 8131 // we do the check against the caller's permissions even though it looks 8132 // to the content provider like the Activity Manager itself is making 8133 // the request. 8134 sCallerIdentity.set(new Identity( 8135 Binder.getCallingPid(), Binder.getCallingUid())); 8136 try { 8137 pfd = cph.provider.openFile(null, uri, "r", null); 8138 } catch (FileNotFoundException e) { 8139 // do nothing; pfd will be returned null 8140 } finally { 8141 // Ensure that whatever happens, we clean up the identity state 8142 sCallerIdentity.remove(); 8143 } 8144 8145 // We've got the fd now, so we're done with the provider. 8146 removeContentProviderExternalUnchecked(name, null, userId); 8147 } else { 8148 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8149 } 8150 return pfd; 8151 } 8152 8153 // Actually is sleeping or shutting down or whatever else in the future 8154 // is an inactive state. 8155 public boolean isSleepingOrShuttingDown() { 8156 return mSleeping || mShuttingDown; 8157 } 8158 8159 public void goingToSleep() { 8160 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8161 != PackageManager.PERMISSION_GRANTED) { 8162 throw new SecurityException("Requires permission " 8163 + android.Manifest.permission.DEVICE_POWER); 8164 } 8165 8166 synchronized(this) { 8167 mWentToSleep = true; 8168 updateEventDispatchingLocked(); 8169 8170 if (!mSleeping) { 8171 mSleeping = true; 8172 mStackSupervisor.goingToSleepLocked(); 8173 8174 // Initialize the wake times of all processes. 8175 checkExcessivePowerUsageLocked(false); 8176 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8177 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8178 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8179 } 8180 } 8181 } 8182 8183 @Override 8184 public boolean shutdown(int timeout) { 8185 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8186 != PackageManager.PERMISSION_GRANTED) { 8187 throw new SecurityException("Requires permission " 8188 + android.Manifest.permission.SHUTDOWN); 8189 } 8190 8191 boolean timedout = false; 8192 8193 synchronized(this) { 8194 mShuttingDown = true; 8195 updateEventDispatchingLocked(); 8196 timedout = mStackSupervisor.shutdownLocked(timeout); 8197 } 8198 8199 mAppOpsService.shutdown(); 8200 mUsageStatsService.shutdown(); 8201 mBatteryStatsService.shutdown(); 8202 synchronized (this) { 8203 mProcessStats.shutdownLocked(); 8204 } 8205 8206 return timedout; 8207 } 8208 8209 public final void activitySlept(IBinder token) { 8210 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8211 8212 final long origId = Binder.clearCallingIdentity(); 8213 8214 synchronized (this) { 8215 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8216 if (r != null) { 8217 mStackSupervisor.activitySleptLocked(r); 8218 } 8219 } 8220 8221 Binder.restoreCallingIdentity(origId); 8222 } 8223 8224 void logLockScreen(String msg) { 8225 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8226 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8227 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8228 mStackSupervisor.mDismissKeyguardOnNextActivity); 8229 } 8230 8231 private void comeOutOfSleepIfNeededLocked() { 8232 if (!mWentToSleep && !mLockScreenShown) { 8233 if (mSleeping) { 8234 mSleeping = false; 8235 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8236 } 8237 } 8238 } 8239 8240 public void wakingUp() { 8241 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8242 != PackageManager.PERMISSION_GRANTED) { 8243 throw new SecurityException("Requires permission " 8244 + android.Manifest.permission.DEVICE_POWER); 8245 } 8246 8247 synchronized(this) { 8248 mWentToSleep = false; 8249 updateEventDispatchingLocked(); 8250 comeOutOfSleepIfNeededLocked(); 8251 } 8252 } 8253 8254 private void updateEventDispatchingLocked() { 8255 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8256 } 8257 8258 public void setLockScreenShown(boolean shown) { 8259 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8260 != PackageManager.PERMISSION_GRANTED) { 8261 throw new SecurityException("Requires permission " 8262 + android.Manifest.permission.DEVICE_POWER); 8263 } 8264 8265 synchronized(this) { 8266 long ident = Binder.clearCallingIdentity(); 8267 try { 8268 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8269 mLockScreenShown = shown; 8270 comeOutOfSleepIfNeededLocked(); 8271 } finally { 8272 Binder.restoreCallingIdentity(ident); 8273 } 8274 } 8275 } 8276 8277 public void stopAppSwitches() { 8278 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8279 != PackageManager.PERMISSION_GRANTED) { 8280 throw new SecurityException("Requires permission " 8281 + android.Manifest.permission.STOP_APP_SWITCHES); 8282 } 8283 8284 synchronized(this) { 8285 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8286 + APP_SWITCH_DELAY_TIME; 8287 mDidAppSwitch = false; 8288 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8289 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8290 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8291 } 8292 } 8293 8294 public void resumeAppSwitches() { 8295 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8296 != PackageManager.PERMISSION_GRANTED) { 8297 throw new SecurityException("Requires permission " 8298 + android.Manifest.permission.STOP_APP_SWITCHES); 8299 } 8300 8301 synchronized(this) { 8302 // Note that we don't execute any pending app switches... we will 8303 // let those wait until either the timeout, or the next start 8304 // activity request. 8305 mAppSwitchesAllowedTime = 0; 8306 } 8307 } 8308 8309 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8310 String name) { 8311 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8312 return true; 8313 } 8314 8315 final int perm = checkComponentPermission( 8316 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8317 callingUid, -1, true); 8318 if (perm == PackageManager.PERMISSION_GRANTED) { 8319 return true; 8320 } 8321 8322 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8323 return false; 8324 } 8325 8326 public void setDebugApp(String packageName, boolean waitForDebugger, 8327 boolean persistent) { 8328 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8329 "setDebugApp()"); 8330 8331 long ident = Binder.clearCallingIdentity(); 8332 try { 8333 // Note that this is not really thread safe if there are multiple 8334 // callers into it at the same time, but that's not a situation we 8335 // care about. 8336 if (persistent) { 8337 final ContentResolver resolver = mContext.getContentResolver(); 8338 Settings.Global.putString( 8339 resolver, Settings.Global.DEBUG_APP, 8340 packageName); 8341 Settings.Global.putInt( 8342 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8343 waitForDebugger ? 1 : 0); 8344 } 8345 8346 synchronized (this) { 8347 if (!persistent) { 8348 mOrigDebugApp = mDebugApp; 8349 mOrigWaitForDebugger = mWaitForDebugger; 8350 } 8351 mDebugApp = packageName; 8352 mWaitForDebugger = waitForDebugger; 8353 mDebugTransient = !persistent; 8354 if (packageName != null) { 8355 forceStopPackageLocked(packageName, -1, false, false, true, true, 8356 UserHandle.USER_ALL, "set debug app"); 8357 } 8358 } 8359 } finally { 8360 Binder.restoreCallingIdentity(ident); 8361 } 8362 } 8363 8364 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8365 synchronized (this) { 8366 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8367 if (!isDebuggable) { 8368 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8369 throw new SecurityException("Process not debuggable: " + app.packageName); 8370 } 8371 } 8372 8373 mOpenGlTraceApp = processName; 8374 } 8375 } 8376 8377 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8378 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8379 synchronized (this) { 8380 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8381 if (!isDebuggable) { 8382 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8383 throw new SecurityException("Process not debuggable: " + app.packageName); 8384 } 8385 } 8386 mProfileApp = processName; 8387 mProfileFile = profileFile; 8388 if (mProfileFd != null) { 8389 try { 8390 mProfileFd.close(); 8391 } catch (IOException e) { 8392 } 8393 mProfileFd = null; 8394 } 8395 mProfileFd = profileFd; 8396 mProfileType = 0; 8397 mAutoStopProfiler = autoStopProfiler; 8398 } 8399 } 8400 8401 @Override 8402 public void setAlwaysFinish(boolean enabled) { 8403 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8404 "setAlwaysFinish()"); 8405 8406 Settings.Global.putInt( 8407 mContext.getContentResolver(), 8408 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8409 8410 synchronized (this) { 8411 mAlwaysFinishActivities = enabled; 8412 } 8413 } 8414 8415 @Override 8416 public void setActivityController(IActivityController controller) { 8417 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8418 "setActivityController()"); 8419 synchronized (this) { 8420 mController = controller; 8421 Watchdog.getInstance().setActivityController(controller); 8422 } 8423 } 8424 8425 @Override 8426 public void setUserIsMonkey(boolean userIsMonkey) { 8427 synchronized (this) { 8428 synchronized (mPidsSelfLocked) { 8429 final int callingPid = Binder.getCallingPid(); 8430 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8431 if (precessRecord == null) { 8432 throw new SecurityException("Unknown process: " + callingPid); 8433 } 8434 if (precessRecord.instrumentationUiAutomationConnection == null) { 8435 throw new SecurityException("Only an instrumentation process " 8436 + "with a UiAutomation can call setUserIsMonkey"); 8437 } 8438 } 8439 mUserIsMonkey = userIsMonkey; 8440 } 8441 } 8442 8443 @Override 8444 public boolean isUserAMonkey() { 8445 synchronized (this) { 8446 // If there is a controller also implies the user is a monkey. 8447 return (mUserIsMonkey || mController != null); 8448 } 8449 } 8450 8451 public void requestBugReport() { 8452 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8453 SystemProperties.set("ctl.start", "bugreport"); 8454 } 8455 8456 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8457 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8458 } 8459 8460 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8461 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8462 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8463 } 8464 return KEY_DISPATCHING_TIMEOUT; 8465 } 8466 8467 @Override 8468 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8469 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8470 != PackageManager.PERMISSION_GRANTED) { 8471 throw new SecurityException("Requires permission " 8472 + android.Manifest.permission.FILTER_EVENTS); 8473 } 8474 ProcessRecord proc; 8475 long timeout; 8476 synchronized (this) { 8477 synchronized (mPidsSelfLocked) { 8478 proc = mPidsSelfLocked.get(pid); 8479 } 8480 timeout = getInputDispatchingTimeoutLocked(proc); 8481 } 8482 8483 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8484 return -1; 8485 } 8486 8487 return timeout; 8488 } 8489 8490 /** 8491 * Handle input dispatching timeouts. 8492 * Returns whether input dispatching should be aborted or not. 8493 */ 8494 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8495 final ActivityRecord activity, final ActivityRecord parent, 8496 final boolean aboveSystem, String reason) { 8497 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8498 != PackageManager.PERMISSION_GRANTED) { 8499 throw new SecurityException("Requires permission " 8500 + android.Manifest.permission.FILTER_EVENTS); 8501 } 8502 8503 final String annotation; 8504 if (reason == null) { 8505 annotation = "Input dispatching timed out"; 8506 } else { 8507 annotation = "Input dispatching timed out (" + reason + ")"; 8508 } 8509 8510 if (proc != null) { 8511 synchronized (this) { 8512 if (proc.debugging) { 8513 return false; 8514 } 8515 8516 if (mDidDexOpt) { 8517 // Give more time since we were dexopting. 8518 mDidDexOpt = false; 8519 return false; 8520 } 8521 8522 if (proc.instrumentationClass != null) { 8523 Bundle info = new Bundle(); 8524 info.putString("shortMsg", "keyDispatchingTimedOut"); 8525 info.putString("longMsg", annotation); 8526 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8527 return true; 8528 } 8529 } 8530 mHandler.post(new Runnable() { 8531 @Override 8532 public void run() { 8533 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8534 } 8535 }); 8536 } 8537 8538 return true; 8539 } 8540 8541 public Bundle getAssistContextExtras(int requestType) { 8542 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8543 "getAssistContextExtras()"); 8544 PendingAssistExtras pae; 8545 Bundle extras = new Bundle(); 8546 synchronized (this) { 8547 ActivityRecord activity = getFocusedStack().mResumedActivity; 8548 if (activity == null) { 8549 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8550 return null; 8551 } 8552 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8553 if (activity.app == null || activity.app.thread == null) { 8554 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8555 return extras; 8556 } 8557 if (activity.app.pid == Binder.getCallingPid()) { 8558 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8559 return extras; 8560 } 8561 pae = new PendingAssistExtras(activity); 8562 try { 8563 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8564 requestType); 8565 mPendingAssistExtras.add(pae); 8566 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8567 } catch (RemoteException e) { 8568 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8569 return extras; 8570 } 8571 } 8572 synchronized (pae) { 8573 while (!pae.haveResult) { 8574 try { 8575 pae.wait(); 8576 } catch (InterruptedException e) { 8577 } 8578 } 8579 if (pae.result != null) { 8580 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8581 } 8582 } 8583 synchronized (this) { 8584 mPendingAssistExtras.remove(pae); 8585 mHandler.removeCallbacks(pae); 8586 } 8587 return extras; 8588 } 8589 8590 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8591 PendingAssistExtras pae = (PendingAssistExtras)token; 8592 synchronized (pae) { 8593 pae.result = extras; 8594 pae.haveResult = true; 8595 pae.notifyAll(); 8596 } 8597 } 8598 8599 public void registerProcessObserver(IProcessObserver observer) { 8600 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8601 "registerProcessObserver()"); 8602 synchronized (this) { 8603 mProcessObservers.register(observer); 8604 } 8605 } 8606 8607 @Override 8608 public void unregisterProcessObserver(IProcessObserver observer) { 8609 synchronized (this) { 8610 mProcessObservers.unregister(observer); 8611 } 8612 } 8613 8614 @Override 8615 public boolean convertFromTranslucent(IBinder token) { 8616 final long origId = Binder.clearCallingIdentity(); 8617 try { 8618 synchronized (this) { 8619 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8620 if (r == null) { 8621 return false; 8622 } 8623 if (r.changeWindowTranslucency(true)) { 8624 mWindowManager.setAppFullscreen(token, true); 8625 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8626 return true; 8627 } 8628 return false; 8629 } 8630 } finally { 8631 Binder.restoreCallingIdentity(origId); 8632 } 8633 } 8634 8635 @Override 8636 public boolean convertToTranslucent(IBinder token) { 8637 final long origId = Binder.clearCallingIdentity(); 8638 try { 8639 synchronized (this) { 8640 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8641 if (r == null) { 8642 return false; 8643 } 8644 if (r.changeWindowTranslucency(false)) { 8645 r.task.stack.convertToTranslucent(r); 8646 mWindowManager.setAppFullscreen(token, false); 8647 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8648 return true; 8649 } 8650 return false; 8651 } 8652 } finally { 8653 Binder.restoreCallingIdentity(origId); 8654 } 8655 } 8656 8657 @Override 8658 public void setImmersive(IBinder token, boolean immersive) { 8659 synchronized(this) { 8660 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8661 if (r == null) { 8662 throw new IllegalArgumentException(); 8663 } 8664 r.immersive = immersive; 8665 8666 // update associated state if we're frontmost 8667 if (r == mFocusedActivity) { 8668 if (DEBUG_IMMERSIVE) { 8669 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8670 } 8671 applyUpdateLockStateLocked(r); 8672 } 8673 } 8674 } 8675 8676 @Override 8677 public boolean isImmersive(IBinder token) { 8678 synchronized (this) { 8679 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8680 if (r == null) { 8681 throw new IllegalArgumentException(); 8682 } 8683 return r.immersive; 8684 } 8685 } 8686 8687 public boolean isTopActivityImmersive() { 8688 enforceNotIsolatedCaller("startActivity"); 8689 synchronized (this) { 8690 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8691 return (r != null) ? r.immersive : false; 8692 } 8693 } 8694 8695 public final void enterSafeMode() { 8696 synchronized(this) { 8697 // It only makes sense to do this before the system is ready 8698 // and started launching other packages. 8699 if (!mSystemReady) { 8700 try { 8701 AppGlobals.getPackageManager().enterSafeMode(); 8702 } catch (RemoteException e) { 8703 } 8704 } 8705 } 8706 } 8707 8708 public final void showSafeModeOverlay() { 8709 View v = LayoutInflater.from(mContext).inflate( 8710 com.android.internal.R.layout.safe_mode, null); 8711 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8712 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8713 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8714 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8715 lp.gravity = Gravity.BOTTOM | Gravity.START; 8716 lp.format = v.getBackground().getOpacity(); 8717 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8718 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8719 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8720 ((WindowManager)mContext.getSystemService( 8721 Context.WINDOW_SERVICE)).addView(v, lp); 8722 } 8723 8724 public void noteWakeupAlarm(IIntentSender sender) { 8725 if (!(sender instanceof PendingIntentRecord)) { 8726 return; 8727 } 8728 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8729 synchronized (stats) { 8730 if (mBatteryStatsService.isOnBattery()) { 8731 mBatteryStatsService.enforceCallingPermission(); 8732 PendingIntentRecord rec = (PendingIntentRecord)sender; 8733 int MY_UID = Binder.getCallingUid(); 8734 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8735 BatteryStatsImpl.Uid.Pkg pkg = 8736 stats.getPackageStatsLocked(uid, rec.key.packageName); 8737 pkg.incWakeupsLocked(); 8738 } 8739 } 8740 } 8741 8742 public boolean killPids(int[] pids, String pReason, boolean secure) { 8743 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8744 throw new SecurityException("killPids only available to the system"); 8745 } 8746 String reason = (pReason == null) ? "Unknown" : pReason; 8747 // XXX Note: don't acquire main activity lock here, because the window 8748 // manager calls in with its locks held. 8749 8750 boolean killed = false; 8751 synchronized (mPidsSelfLocked) { 8752 int[] types = new int[pids.length]; 8753 int worstType = 0; 8754 for (int i=0; i<pids.length; i++) { 8755 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8756 if (proc != null) { 8757 int type = proc.setAdj; 8758 types[i] = type; 8759 if (type > worstType) { 8760 worstType = type; 8761 } 8762 } 8763 } 8764 8765 // If the worst oom_adj is somewhere in the cached proc LRU range, 8766 // then constrain it so we will kill all cached procs. 8767 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8768 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8769 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8770 } 8771 8772 // If this is not a secure call, don't let it kill processes that 8773 // are important. 8774 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8775 worstType = ProcessList.SERVICE_ADJ; 8776 } 8777 8778 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8779 for (int i=0; i<pids.length; i++) { 8780 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8781 if (proc == null) { 8782 continue; 8783 } 8784 int adj = proc.setAdj; 8785 if (adj >= worstType && !proc.killedByAm) { 8786 killUnneededProcessLocked(proc, reason); 8787 killed = true; 8788 } 8789 } 8790 } 8791 return killed; 8792 } 8793 8794 @Override 8795 public void killUid(int uid, String reason) { 8796 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8797 throw new SecurityException("killUid only available to the system"); 8798 } 8799 synchronized (this) { 8800 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 8801 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 8802 reason != null ? reason : "kill uid"); 8803 } 8804 } 8805 8806 @Override 8807 public boolean killProcessesBelowForeground(String reason) { 8808 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8809 throw new SecurityException("killProcessesBelowForeground() only available to system"); 8810 } 8811 8812 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 8813 } 8814 8815 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 8816 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8817 throw new SecurityException("killProcessesBelowAdj() only available to system"); 8818 } 8819 8820 boolean killed = false; 8821 synchronized (mPidsSelfLocked) { 8822 final int size = mPidsSelfLocked.size(); 8823 for (int i = 0; i < size; i++) { 8824 final int pid = mPidsSelfLocked.keyAt(i); 8825 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8826 if (proc == null) continue; 8827 8828 final int adj = proc.setAdj; 8829 if (adj > belowAdj && !proc.killedByAm) { 8830 killUnneededProcessLocked(proc, reason); 8831 killed = true; 8832 } 8833 } 8834 } 8835 return killed; 8836 } 8837 8838 @Override 8839 public void hang(final IBinder who, boolean allowRestart) { 8840 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8841 != PackageManager.PERMISSION_GRANTED) { 8842 throw new SecurityException("Requires permission " 8843 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8844 } 8845 8846 final IBinder.DeathRecipient death = new DeathRecipient() { 8847 @Override 8848 public void binderDied() { 8849 synchronized (this) { 8850 notifyAll(); 8851 } 8852 } 8853 }; 8854 8855 try { 8856 who.linkToDeath(death, 0); 8857 } catch (RemoteException e) { 8858 Slog.w(TAG, "hang: given caller IBinder is already dead."); 8859 return; 8860 } 8861 8862 synchronized (this) { 8863 Watchdog.getInstance().setAllowRestart(allowRestart); 8864 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 8865 synchronized (death) { 8866 while (who.isBinderAlive()) { 8867 try { 8868 death.wait(); 8869 } catch (InterruptedException e) { 8870 } 8871 } 8872 } 8873 Watchdog.getInstance().setAllowRestart(true); 8874 } 8875 } 8876 8877 @Override 8878 public void restart() { 8879 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8880 != PackageManager.PERMISSION_GRANTED) { 8881 throw new SecurityException("Requires permission " 8882 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8883 } 8884 8885 Log.i(TAG, "Sending shutdown broadcast..."); 8886 8887 BroadcastReceiver br = new BroadcastReceiver() { 8888 @Override public void onReceive(Context context, Intent intent) { 8889 // Now the broadcast is done, finish up the low-level shutdown. 8890 Log.i(TAG, "Shutting down activity manager..."); 8891 shutdown(10000); 8892 Log.i(TAG, "Shutdown complete, restarting!"); 8893 Process.killProcess(Process.myPid()); 8894 System.exit(10); 8895 } 8896 }; 8897 8898 // First send the high-level shut down broadcast. 8899 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 8900 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 8901 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 8902 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 8903 mContext.sendOrderedBroadcastAsUser(intent, 8904 UserHandle.ALL, null, br, mHandler, 0, null, null); 8905 */ 8906 br.onReceive(mContext, intent); 8907 } 8908 8909 private long getLowRamTimeSinceIdle(long now) { 8910 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 8911 } 8912 8913 @Override 8914 public void performIdleMaintenance() { 8915 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8916 != PackageManager.PERMISSION_GRANTED) { 8917 throw new SecurityException("Requires permission " 8918 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8919 } 8920 8921 synchronized (this) { 8922 final long now = SystemClock.uptimeMillis(); 8923 final long timeSinceLastIdle = now - mLastIdleTime; 8924 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 8925 mLastIdleTime = now; 8926 mLowRamTimeSinceLastIdle = 0; 8927 if (mLowRamStartTime != 0) { 8928 mLowRamStartTime = now; 8929 } 8930 8931 StringBuilder sb = new StringBuilder(128); 8932 sb.append("Idle maintenance over "); 8933 TimeUtils.formatDuration(timeSinceLastIdle, sb); 8934 sb.append(" low RAM for "); 8935 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 8936 Slog.i(TAG, sb.toString()); 8937 8938 // If at least 1/3 of our time since the last idle period has been spent 8939 // with RAM low, then we want to kill processes. 8940 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 8941 8942 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 8943 ProcessRecord proc = mLruProcesses.get(i); 8944 if (proc.notCachedSinceIdle) { 8945 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 8946 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 8947 if (doKilling && proc.initialIdlePss != 0 8948 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 8949 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 8950 + " from " + proc.initialIdlePss + ")"); 8951 } 8952 } 8953 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 8954 proc.notCachedSinceIdle = true; 8955 proc.initialIdlePss = 0; 8956 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 8957 mSleeping, now); 8958 } 8959 } 8960 8961 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 8962 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 8963 } 8964 } 8965 8966 public final void startRunning(String pkg, String cls, String action, 8967 String data) { 8968 synchronized(this) { 8969 if (mStartRunning) { 8970 return; 8971 } 8972 mStartRunning = true; 8973 mTopComponent = pkg != null && cls != null 8974 ? new ComponentName(pkg, cls) : null; 8975 mTopAction = action != null ? action : Intent.ACTION_MAIN; 8976 mTopData = data; 8977 if (!mSystemReady) { 8978 return; 8979 } 8980 } 8981 8982 systemReady(null); 8983 } 8984 8985 private void retrieveSettings() { 8986 final ContentResolver resolver = mContext.getContentResolver(); 8987 String debugApp = Settings.Global.getString( 8988 resolver, Settings.Global.DEBUG_APP); 8989 boolean waitForDebugger = Settings.Global.getInt( 8990 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 8991 boolean alwaysFinishActivities = Settings.Global.getInt( 8992 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 8993 boolean forceRtl = Settings.Global.getInt( 8994 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 8995 // Transfer any global setting for forcing RTL layout, into a System Property 8996 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 8997 8998 Configuration configuration = new Configuration(); 8999 Settings.System.getConfiguration(resolver, configuration); 9000 if (forceRtl) { 9001 // This will take care of setting the correct layout direction flags 9002 configuration.setLayoutDirection(configuration.locale); 9003 } 9004 9005 synchronized (this) { 9006 mDebugApp = mOrigDebugApp = debugApp; 9007 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9008 mAlwaysFinishActivities = alwaysFinishActivities; 9009 // This happens before any activities are started, so we can 9010 // change mConfiguration in-place. 9011 updateConfigurationLocked(configuration, null, false, true); 9012 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9013 } 9014 } 9015 9016 public boolean testIsSystemReady() { 9017 // no need to synchronize(this) just to read & return the value 9018 return mSystemReady; 9019 } 9020 9021 private static File getCalledPreBootReceiversFile() { 9022 File dataDir = Environment.getDataDirectory(); 9023 File systemDir = new File(dataDir, "system"); 9024 File fname = new File(systemDir, "called_pre_boots.dat"); 9025 return fname; 9026 } 9027 9028 static final int LAST_DONE_VERSION = 10000; 9029 9030 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9031 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9032 File file = getCalledPreBootReceiversFile(); 9033 FileInputStream fis = null; 9034 try { 9035 fis = new FileInputStream(file); 9036 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9037 int fvers = dis.readInt(); 9038 if (fvers == LAST_DONE_VERSION) { 9039 String vers = dis.readUTF(); 9040 String codename = dis.readUTF(); 9041 String build = dis.readUTF(); 9042 if (android.os.Build.VERSION.RELEASE.equals(vers) 9043 && android.os.Build.VERSION.CODENAME.equals(codename) 9044 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9045 int num = dis.readInt(); 9046 while (num > 0) { 9047 num--; 9048 String pkg = dis.readUTF(); 9049 String cls = dis.readUTF(); 9050 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9051 } 9052 } 9053 } 9054 } catch (FileNotFoundException e) { 9055 } catch (IOException e) { 9056 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9057 } finally { 9058 if (fis != null) { 9059 try { 9060 fis.close(); 9061 } catch (IOException e) { 9062 } 9063 } 9064 } 9065 return lastDoneReceivers; 9066 } 9067 9068 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9069 File file = getCalledPreBootReceiversFile(); 9070 FileOutputStream fos = null; 9071 DataOutputStream dos = null; 9072 try { 9073 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9074 fos = new FileOutputStream(file); 9075 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9076 dos.writeInt(LAST_DONE_VERSION); 9077 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9078 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9079 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9080 dos.writeInt(list.size()); 9081 for (int i=0; i<list.size(); i++) { 9082 dos.writeUTF(list.get(i).getPackageName()); 9083 dos.writeUTF(list.get(i).getClassName()); 9084 } 9085 } catch (IOException e) { 9086 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9087 file.delete(); 9088 } finally { 9089 FileUtils.sync(fos); 9090 if (dos != null) { 9091 try { 9092 dos.close(); 9093 } catch (IOException e) { 9094 // TODO Auto-generated catch block 9095 e.printStackTrace(); 9096 } 9097 } 9098 } 9099 } 9100 9101 public void systemReady(final Runnable goingCallback) { 9102 synchronized(this) { 9103 if (mSystemReady) { 9104 if (goingCallback != null) goingCallback.run(); 9105 return; 9106 } 9107 9108 // Check to see if there are any update receivers to run. 9109 if (!mDidUpdate) { 9110 if (mWaitingUpdate) { 9111 return; 9112 } 9113 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9114 List<ResolveInfo> ris = null; 9115 try { 9116 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9117 intent, null, 0, 0); 9118 } catch (RemoteException e) { 9119 } 9120 if (ris != null) { 9121 for (int i=ris.size()-1; i>=0; i--) { 9122 if ((ris.get(i).activityInfo.applicationInfo.flags 9123 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9124 ris.remove(i); 9125 } 9126 } 9127 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9128 9129 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9130 9131 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9132 for (int i=0; i<ris.size(); i++) { 9133 ActivityInfo ai = ris.get(i).activityInfo; 9134 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9135 if (lastDoneReceivers.contains(comp)) { 9136 ris.remove(i); 9137 i--; 9138 } 9139 } 9140 9141 final int[] users = getUsersLocked(); 9142 for (int i=0; i<ris.size(); i++) { 9143 ActivityInfo ai = ris.get(i).activityInfo; 9144 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9145 doneReceivers.add(comp); 9146 intent.setComponent(comp); 9147 for (int j=0; j<users.length; j++) { 9148 IIntentReceiver finisher = null; 9149 if (i == ris.size()-1 && j == users.length-1) { 9150 finisher = new IIntentReceiver.Stub() { 9151 public void performReceive(Intent intent, int resultCode, 9152 String data, Bundle extras, boolean ordered, 9153 boolean sticky, int sendingUser) { 9154 // The raw IIntentReceiver interface is called 9155 // with the AM lock held, so redispatch to 9156 // execute our code without the lock. 9157 mHandler.post(new Runnable() { 9158 public void run() { 9159 synchronized (ActivityManagerService.this) { 9160 mDidUpdate = true; 9161 } 9162 writeLastDonePreBootReceivers(doneReceivers); 9163 showBootMessage(mContext.getText( 9164 R.string.android_upgrading_complete), 9165 false); 9166 systemReady(goingCallback); 9167 } 9168 }); 9169 } 9170 }; 9171 } 9172 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9173 + " for user " + users[j]); 9174 broadcastIntentLocked(null, null, intent, null, finisher, 9175 0, null, null, null, AppOpsManager.OP_NONE, 9176 true, false, MY_PID, Process.SYSTEM_UID, 9177 users[j]); 9178 if (finisher != null) { 9179 mWaitingUpdate = true; 9180 } 9181 } 9182 } 9183 } 9184 if (mWaitingUpdate) { 9185 return; 9186 } 9187 mDidUpdate = true; 9188 } 9189 9190 mAppOpsService.systemReady(); 9191 mSystemReady = true; 9192 if (!mStartRunning) { 9193 return; 9194 } 9195 } 9196 9197 ArrayList<ProcessRecord> procsToKill = null; 9198 synchronized(mPidsSelfLocked) { 9199 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9200 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9201 if (!isAllowedWhileBooting(proc.info)){ 9202 if (procsToKill == null) { 9203 procsToKill = new ArrayList<ProcessRecord>(); 9204 } 9205 procsToKill.add(proc); 9206 } 9207 } 9208 } 9209 9210 synchronized(this) { 9211 if (procsToKill != null) { 9212 for (int i=procsToKill.size()-1; i>=0; i--) { 9213 ProcessRecord proc = procsToKill.get(i); 9214 Slog.i(TAG, "Removing system update proc: " + proc); 9215 removeProcessLocked(proc, true, false, "system update done"); 9216 } 9217 } 9218 9219 // Now that we have cleaned up any update processes, we 9220 // are ready to start launching real processes and know that 9221 // we won't trample on them any more. 9222 mProcessesReady = true; 9223 } 9224 9225 Slog.i(TAG, "System now ready"); 9226 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9227 SystemClock.uptimeMillis()); 9228 9229 synchronized(this) { 9230 // Make sure we have no pre-ready processes sitting around. 9231 9232 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9233 ResolveInfo ri = mContext.getPackageManager() 9234 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9235 STOCK_PM_FLAGS); 9236 CharSequence errorMsg = null; 9237 if (ri != null) { 9238 ActivityInfo ai = ri.activityInfo; 9239 ApplicationInfo app = ai.applicationInfo; 9240 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9241 mTopAction = Intent.ACTION_FACTORY_TEST; 9242 mTopData = null; 9243 mTopComponent = new ComponentName(app.packageName, 9244 ai.name); 9245 } else { 9246 errorMsg = mContext.getResources().getText( 9247 com.android.internal.R.string.factorytest_not_system); 9248 } 9249 } else { 9250 errorMsg = mContext.getResources().getText( 9251 com.android.internal.R.string.factorytest_no_action); 9252 } 9253 if (errorMsg != null) { 9254 mTopAction = null; 9255 mTopData = null; 9256 mTopComponent = null; 9257 Message msg = Message.obtain(); 9258 msg.what = SHOW_FACTORY_ERROR_MSG; 9259 msg.getData().putCharSequence("msg", errorMsg); 9260 mHandler.sendMessage(msg); 9261 } 9262 } 9263 } 9264 9265 retrieveSettings(); 9266 9267 synchronized (this) { 9268 readGrantedUriPermissionsLocked(); 9269 } 9270 9271 if (goingCallback != null) goingCallback.run(); 9272 9273 synchronized (this) { 9274 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9275 try { 9276 List apps = AppGlobals.getPackageManager(). 9277 getPersistentApplications(STOCK_PM_FLAGS); 9278 if (apps != null) { 9279 int N = apps.size(); 9280 int i; 9281 for (i=0; i<N; i++) { 9282 ApplicationInfo info 9283 = (ApplicationInfo)apps.get(i); 9284 if (info != null && 9285 !info.packageName.equals("android")) { 9286 addAppLocked(info, false); 9287 } 9288 } 9289 } 9290 } catch (RemoteException ex) { 9291 // pm is in same process, this will never happen. 9292 } 9293 } 9294 9295 // Start up initial activity. 9296 mBooting = true; 9297 9298 try { 9299 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9300 Message msg = Message.obtain(); 9301 msg.what = SHOW_UID_ERROR_MSG; 9302 mHandler.sendMessage(msg); 9303 } 9304 } catch (RemoteException e) { 9305 } 9306 9307 long ident = Binder.clearCallingIdentity(); 9308 try { 9309 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9310 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9311 | Intent.FLAG_RECEIVER_FOREGROUND); 9312 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9313 broadcastIntentLocked(null, null, intent, 9314 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9315 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9316 intent = new Intent(Intent.ACTION_USER_STARTING); 9317 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9318 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9319 broadcastIntentLocked(null, null, intent, 9320 null, new IIntentReceiver.Stub() { 9321 @Override 9322 public void performReceive(Intent intent, int resultCode, String data, 9323 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9324 throws RemoteException { 9325 } 9326 }, 0, null, null, 9327 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9328 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9329 } finally { 9330 Binder.restoreCallingIdentity(ident); 9331 } 9332 mStackSupervisor.resumeTopActivitiesLocked(); 9333 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9334 } 9335 } 9336 9337 private boolean makeAppCrashingLocked(ProcessRecord app, 9338 String shortMsg, String longMsg, String stackTrace) { 9339 app.crashing = true; 9340 app.crashingReport = generateProcessError(app, 9341 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9342 startAppProblemLocked(app); 9343 app.stopFreezingAllLocked(); 9344 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9345 } 9346 9347 private void makeAppNotRespondingLocked(ProcessRecord app, 9348 String activity, String shortMsg, String longMsg) { 9349 app.notResponding = true; 9350 app.notRespondingReport = generateProcessError(app, 9351 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9352 activity, shortMsg, longMsg, null); 9353 startAppProblemLocked(app); 9354 app.stopFreezingAllLocked(); 9355 } 9356 9357 /** 9358 * Generate a process error record, suitable for attachment to a ProcessRecord. 9359 * 9360 * @param app The ProcessRecord in which the error occurred. 9361 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9362 * ActivityManager.AppErrorStateInfo 9363 * @param activity The activity associated with the crash, if known. 9364 * @param shortMsg Short message describing the crash. 9365 * @param longMsg Long message describing the crash. 9366 * @param stackTrace Full crash stack trace, may be null. 9367 * 9368 * @return Returns a fully-formed AppErrorStateInfo record. 9369 */ 9370 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9371 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9372 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9373 9374 report.condition = condition; 9375 report.processName = app.processName; 9376 report.pid = app.pid; 9377 report.uid = app.info.uid; 9378 report.tag = activity; 9379 report.shortMsg = shortMsg; 9380 report.longMsg = longMsg; 9381 report.stackTrace = stackTrace; 9382 9383 return report; 9384 } 9385 9386 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9387 synchronized (this) { 9388 app.crashing = false; 9389 app.crashingReport = null; 9390 app.notResponding = false; 9391 app.notRespondingReport = null; 9392 if (app.anrDialog == fromDialog) { 9393 app.anrDialog = null; 9394 } 9395 if (app.waitDialog == fromDialog) { 9396 app.waitDialog = null; 9397 } 9398 if (app.pid > 0 && app.pid != MY_PID) { 9399 handleAppCrashLocked(app, null, null, null); 9400 killUnneededProcessLocked(app, "user request after error"); 9401 } 9402 } 9403 } 9404 9405 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9406 String stackTrace) { 9407 long now = SystemClock.uptimeMillis(); 9408 9409 Long crashTime; 9410 if (!app.isolated) { 9411 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9412 } else { 9413 crashTime = null; 9414 } 9415 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9416 // This process loses! 9417 Slog.w(TAG, "Process " + app.info.processName 9418 + " has crashed too many times: killing!"); 9419 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9420 app.userId, app.info.processName, app.uid); 9421 mStackSupervisor.handleAppCrashLocked(app); 9422 if (!app.persistent) { 9423 // We don't want to start this process again until the user 9424 // explicitly does so... but for persistent process, we really 9425 // need to keep it running. If a persistent process is actually 9426 // repeatedly crashing, then badness for everyone. 9427 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9428 app.info.processName); 9429 if (!app.isolated) { 9430 // XXX We don't have a way to mark isolated processes 9431 // as bad, since they don't have a peristent identity. 9432 mBadProcesses.put(app.info.processName, app.uid, 9433 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9434 mProcessCrashTimes.remove(app.info.processName, app.uid); 9435 } 9436 app.bad = true; 9437 app.removed = true; 9438 // Don't let services in this process be restarted and potentially 9439 // annoy the user repeatedly. Unless it is persistent, since those 9440 // processes run critical code. 9441 removeProcessLocked(app, false, false, "crash"); 9442 mStackSupervisor.resumeTopActivitiesLocked(); 9443 return false; 9444 } 9445 mStackSupervisor.resumeTopActivitiesLocked(); 9446 } else { 9447 mStackSupervisor.finishTopRunningActivityLocked(app); 9448 } 9449 9450 // Bump up the crash count of any services currently running in the proc. 9451 for (int i=app.services.size()-1; i>=0; i--) { 9452 // Any services running in the application need to be placed 9453 // back in the pending list. 9454 ServiceRecord sr = app.services.valueAt(i); 9455 sr.crashCount++; 9456 } 9457 9458 // If the crashing process is what we consider to be the "home process" and it has been 9459 // replaced by a third-party app, clear the package preferred activities from packages 9460 // with a home activity running in the process to prevent a repeatedly crashing app 9461 // from blocking the user to manually clear the list. 9462 final ArrayList<ActivityRecord> activities = app.activities; 9463 if (app == mHomeProcess && activities.size() > 0 9464 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9465 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9466 final ActivityRecord r = activities.get(activityNdx); 9467 if (r.isHomeActivity()) { 9468 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9469 try { 9470 ActivityThread.getPackageManager() 9471 .clearPackagePreferredActivities(r.packageName); 9472 } catch (RemoteException c) { 9473 // pm is in same process, this will never happen. 9474 } 9475 } 9476 } 9477 } 9478 9479 if (!app.isolated) { 9480 // XXX Can't keep track of crash times for isolated processes, 9481 // because they don't have a perisistent identity. 9482 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9483 } 9484 9485 return true; 9486 } 9487 9488 void startAppProblemLocked(ProcessRecord app) { 9489 if (app.userId == mCurrentUserId) { 9490 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9491 mContext, app.info.packageName, app.info.flags); 9492 } else { 9493 // If this app is not running under the current user, then we 9494 // can't give it a report button because that would require 9495 // launching the report UI under a different user. 9496 app.errorReportReceiver = null; 9497 } 9498 skipCurrentReceiverLocked(app); 9499 } 9500 9501 void skipCurrentReceiverLocked(ProcessRecord app) { 9502 for (BroadcastQueue queue : mBroadcastQueues) { 9503 queue.skipCurrentReceiverLocked(app); 9504 } 9505 } 9506 9507 /** 9508 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9509 * The application process will exit immediately after this call returns. 9510 * @param app object of the crashing app, null for the system server 9511 * @param crashInfo describing the exception 9512 */ 9513 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9514 ProcessRecord r = findAppProcess(app, "Crash"); 9515 final String processName = app == null ? "system_server" 9516 : (r == null ? "unknown" : r.processName); 9517 9518 handleApplicationCrashInner("crash", r, processName, crashInfo); 9519 } 9520 9521 /* Native crash reporting uses this inner version because it needs to be somewhat 9522 * decoupled from the AM-managed cleanup lifecycle 9523 */ 9524 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9525 ApplicationErrorReport.CrashInfo crashInfo) { 9526 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9527 UserHandle.getUserId(Binder.getCallingUid()), processName, 9528 r == null ? -1 : r.info.flags, 9529 crashInfo.exceptionClassName, 9530 crashInfo.exceptionMessage, 9531 crashInfo.throwFileName, 9532 crashInfo.throwLineNumber); 9533 9534 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9535 9536 crashApplication(r, crashInfo); 9537 } 9538 9539 public void handleApplicationStrictModeViolation( 9540 IBinder app, 9541 int violationMask, 9542 StrictMode.ViolationInfo info) { 9543 ProcessRecord r = findAppProcess(app, "StrictMode"); 9544 if (r == null) { 9545 return; 9546 } 9547 9548 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9549 Integer stackFingerprint = info.hashCode(); 9550 boolean logIt = true; 9551 synchronized (mAlreadyLoggedViolatedStacks) { 9552 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9553 logIt = false; 9554 // TODO: sub-sample into EventLog for these, with 9555 // the info.durationMillis? Then we'd get 9556 // the relative pain numbers, without logging all 9557 // the stack traces repeatedly. We'd want to do 9558 // likewise in the client code, which also does 9559 // dup suppression, before the Binder call. 9560 } else { 9561 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9562 mAlreadyLoggedViolatedStacks.clear(); 9563 } 9564 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9565 } 9566 } 9567 if (logIt) { 9568 logStrictModeViolationToDropBox(r, info); 9569 } 9570 } 9571 9572 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9573 AppErrorResult result = new AppErrorResult(); 9574 synchronized (this) { 9575 final long origId = Binder.clearCallingIdentity(); 9576 9577 Message msg = Message.obtain(); 9578 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9579 HashMap<String, Object> data = new HashMap<String, Object>(); 9580 data.put("result", result); 9581 data.put("app", r); 9582 data.put("violationMask", violationMask); 9583 data.put("info", info); 9584 msg.obj = data; 9585 mHandler.sendMessage(msg); 9586 9587 Binder.restoreCallingIdentity(origId); 9588 } 9589 int res = result.get(); 9590 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9591 } 9592 } 9593 9594 // Depending on the policy in effect, there could be a bunch of 9595 // these in quick succession so we try to batch these together to 9596 // minimize disk writes, number of dropbox entries, and maximize 9597 // compression, by having more fewer, larger records. 9598 private void logStrictModeViolationToDropBox( 9599 ProcessRecord process, 9600 StrictMode.ViolationInfo info) { 9601 if (info == null) { 9602 return; 9603 } 9604 final boolean isSystemApp = process == null || 9605 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9606 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9607 final String processName = process == null ? "unknown" : process.processName; 9608 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9609 final DropBoxManager dbox = (DropBoxManager) 9610 mContext.getSystemService(Context.DROPBOX_SERVICE); 9611 9612 // Exit early if the dropbox isn't configured to accept this report type. 9613 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9614 9615 boolean bufferWasEmpty; 9616 boolean needsFlush; 9617 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9618 synchronized (sb) { 9619 bufferWasEmpty = sb.length() == 0; 9620 appendDropBoxProcessHeaders(process, processName, sb); 9621 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9622 sb.append("System-App: ").append(isSystemApp).append("\n"); 9623 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9624 if (info.violationNumThisLoop != 0) { 9625 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9626 } 9627 if (info.numAnimationsRunning != 0) { 9628 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9629 } 9630 if (info.broadcastIntentAction != null) { 9631 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9632 } 9633 if (info.durationMillis != -1) { 9634 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9635 } 9636 if (info.numInstances != -1) { 9637 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9638 } 9639 if (info.tags != null) { 9640 for (String tag : info.tags) { 9641 sb.append("Span-Tag: ").append(tag).append("\n"); 9642 } 9643 } 9644 sb.append("\n"); 9645 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9646 sb.append(info.crashInfo.stackTrace); 9647 } 9648 sb.append("\n"); 9649 9650 // Only buffer up to ~64k. Various logging bits truncate 9651 // things at 128k. 9652 needsFlush = (sb.length() > 64 * 1024); 9653 } 9654 9655 // Flush immediately if the buffer's grown too large, or this 9656 // is a non-system app. Non-system apps are isolated with a 9657 // different tag & policy and not batched. 9658 // 9659 // Batching is useful during internal testing with 9660 // StrictMode settings turned up high. Without batching, 9661 // thousands of separate files could be created on boot. 9662 if (!isSystemApp || needsFlush) { 9663 new Thread("Error dump: " + dropboxTag) { 9664 @Override 9665 public void run() { 9666 String report; 9667 synchronized (sb) { 9668 report = sb.toString(); 9669 sb.delete(0, sb.length()); 9670 sb.trimToSize(); 9671 } 9672 if (report.length() != 0) { 9673 dbox.addText(dropboxTag, report); 9674 } 9675 } 9676 }.start(); 9677 return; 9678 } 9679 9680 // System app batching: 9681 if (!bufferWasEmpty) { 9682 // An existing dropbox-writing thread is outstanding, so 9683 // we don't need to start it up. The existing thread will 9684 // catch the buffer appends we just did. 9685 return; 9686 } 9687 9688 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9689 // (After this point, we shouldn't access AMS internal data structures.) 9690 new Thread("Error dump: " + dropboxTag) { 9691 @Override 9692 public void run() { 9693 // 5 second sleep to let stacks arrive and be batched together 9694 try { 9695 Thread.sleep(5000); // 5 seconds 9696 } catch (InterruptedException e) {} 9697 9698 String errorReport; 9699 synchronized (mStrictModeBuffer) { 9700 errorReport = mStrictModeBuffer.toString(); 9701 if (errorReport.length() == 0) { 9702 return; 9703 } 9704 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9705 mStrictModeBuffer.trimToSize(); 9706 } 9707 dbox.addText(dropboxTag, errorReport); 9708 } 9709 }.start(); 9710 } 9711 9712 /** 9713 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9714 * @param app object of the crashing app, null for the system server 9715 * @param tag reported by the caller 9716 * @param crashInfo describing the context of the error 9717 * @return true if the process should exit immediately (WTF is fatal) 9718 */ 9719 public boolean handleApplicationWtf(IBinder app, String tag, 9720 ApplicationErrorReport.CrashInfo crashInfo) { 9721 ProcessRecord r = findAppProcess(app, "WTF"); 9722 final String processName = app == null ? "system_server" 9723 : (r == null ? "unknown" : r.processName); 9724 9725 EventLog.writeEvent(EventLogTags.AM_WTF, 9726 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9727 processName, 9728 r == null ? -1 : r.info.flags, 9729 tag, crashInfo.exceptionMessage); 9730 9731 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9732 9733 if (r != null && r.pid != Process.myPid() && 9734 Settings.Global.getInt(mContext.getContentResolver(), 9735 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9736 crashApplication(r, crashInfo); 9737 return true; 9738 } else { 9739 return false; 9740 } 9741 } 9742 9743 /** 9744 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9745 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9746 */ 9747 private ProcessRecord findAppProcess(IBinder app, String reason) { 9748 if (app == null) { 9749 return null; 9750 } 9751 9752 synchronized (this) { 9753 final int NP = mProcessNames.getMap().size(); 9754 for (int ip=0; ip<NP; ip++) { 9755 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9756 final int NA = apps.size(); 9757 for (int ia=0; ia<NA; ia++) { 9758 ProcessRecord p = apps.valueAt(ia); 9759 if (p.thread != null && p.thread.asBinder() == app) { 9760 return p; 9761 } 9762 } 9763 } 9764 9765 Slog.w(TAG, "Can't find mystery application for " + reason 9766 + " from pid=" + Binder.getCallingPid() 9767 + " uid=" + Binder.getCallingUid() + ": " + app); 9768 return null; 9769 } 9770 } 9771 9772 /** 9773 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9774 * to append various headers to the dropbox log text. 9775 */ 9776 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9777 StringBuilder sb) { 9778 // Watchdog thread ends up invoking this function (with 9779 // a null ProcessRecord) to add the stack file to dropbox. 9780 // Do not acquire a lock on this (am) in such cases, as it 9781 // could cause a potential deadlock, if and when watchdog 9782 // is invoked due to unavailability of lock on am and it 9783 // would prevent watchdog from killing system_server. 9784 if (process == null) { 9785 sb.append("Process: ").append(processName).append("\n"); 9786 return; 9787 } 9788 // Note: ProcessRecord 'process' is guarded by the service 9789 // instance. (notably process.pkgList, which could otherwise change 9790 // concurrently during execution of this method) 9791 synchronized (this) { 9792 sb.append("Process: ").append(processName).append("\n"); 9793 int flags = process.info.flags; 9794 IPackageManager pm = AppGlobals.getPackageManager(); 9795 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 9796 for (int ip=0; ip<process.pkgList.size(); ip++) { 9797 String pkg = process.pkgList.keyAt(ip); 9798 sb.append("Package: ").append(pkg); 9799 try { 9800 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 9801 if (pi != null) { 9802 sb.append(" v").append(pi.versionCode); 9803 if (pi.versionName != null) { 9804 sb.append(" (").append(pi.versionName).append(")"); 9805 } 9806 } 9807 } catch (RemoteException e) { 9808 Slog.e(TAG, "Error getting package info: " + pkg, e); 9809 } 9810 sb.append("\n"); 9811 } 9812 } 9813 } 9814 9815 private static String processClass(ProcessRecord process) { 9816 if (process == null || process.pid == MY_PID) { 9817 return "system_server"; 9818 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9819 return "system_app"; 9820 } else { 9821 return "data_app"; 9822 } 9823 } 9824 9825 /** 9826 * Write a description of an error (crash, WTF, ANR) to the drop box. 9827 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 9828 * @param process which caused the error, null means the system server 9829 * @param activity which triggered the error, null if unknown 9830 * @param parent activity related to the error, null if unknown 9831 * @param subject line related to the error, null if absent 9832 * @param report in long form describing the error, null if absent 9833 * @param logFile to include in the report, null if none 9834 * @param crashInfo giving an application stack trace, null if absent 9835 */ 9836 public void addErrorToDropBox(String eventType, 9837 ProcessRecord process, String processName, ActivityRecord activity, 9838 ActivityRecord parent, String subject, 9839 final String report, final File logFile, 9840 final ApplicationErrorReport.CrashInfo crashInfo) { 9841 // NOTE -- this must never acquire the ActivityManagerService lock, 9842 // otherwise the watchdog may be prevented from resetting the system. 9843 9844 final String dropboxTag = processClass(process) + "_" + eventType; 9845 final DropBoxManager dbox = (DropBoxManager) 9846 mContext.getSystemService(Context.DROPBOX_SERVICE); 9847 9848 // Exit early if the dropbox isn't configured to accept this report type. 9849 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9850 9851 final StringBuilder sb = new StringBuilder(1024); 9852 appendDropBoxProcessHeaders(process, processName, sb); 9853 if (activity != null) { 9854 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 9855 } 9856 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 9857 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 9858 } 9859 if (parent != null && parent != activity) { 9860 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 9861 } 9862 if (subject != null) { 9863 sb.append("Subject: ").append(subject).append("\n"); 9864 } 9865 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9866 if (Debug.isDebuggerConnected()) { 9867 sb.append("Debugger: Connected\n"); 9868 } 9869 sb.append("\n"); 9870 9871 // Do the rest in a worker thread to avoid blocking the caller on I/O 9872 // (After this point, we shouldn't access AMS internal data structures.) 9873 Thread worker = new Thread("Error dump: " + dropboxTag) { 9874 @Override 9875 public void run() { 9876 if (report != null) { 9877 sb.append(report); 9878 } 9879 if (logFile != null) { 9880 try { 9881 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 9882 "\n\n[[TRUNCATED]]")); 9883 } catch (IOException e) { 9884 Slog.e(TAG, "Error reading " + logFile, e); 9885 } 9886 } 9887 if (crashInfo != null && crashInfo.stackTrace != null) { 9888 sb.append(crashInfo.stackTrace); 9889 } 9890 9891 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 9892 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 9893 if (lines > 0) { 9894 sb.append("\n"); 9895 9896 // Merge several logcat streams, and take the last N lines 9897 InputStreamReader input = null; 9898 try { 9899 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 9900 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 9901 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 9902 9903 try { logcat.getOutputStream().close(); } catch (IOException e) {} 9904 try { logcat.getErrorStream().close(); } catch (IOException e) {} 9905 input = new InputStreamReader(logcat.getInputStream()); 9906 9907 int num; 9908 char[] buf = new char[8192]; 9909 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 9910 } catch (IOException e) { 9911 Slog.e(TAG, "Error running logcat", e); 9912 } finally { 9913 if (input != null) try { input.close(); } catch (IOException e) {} 9914 } 9915 } 9916 9917 dbox.addText(dropboxTag, sb.toString()); 9918 } 9919 }; 9920 9921 if (process == null) { 9922 // If process is null, we are being called from some internal code 9923 // and may be about to die -- run this synchronously. 9924 worker.run(); 9925 } else { 9926 worker.start(); 9927 } 9928 } 9929 9930 /** 9931 * Bring up the "unexpected error" dialog box for a crashing app. 9932 * Deal with edge cases (intercepts from instrumented applications, 9933 * ActivityController, error intent receivers, that sort of thing). 9934 * @param r the application crashing 9935 * @param crashInfo describing the failure 9936 */ 9937 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 9938 long timeMillis = System.currentTimeMillis(); 9939 String shortMsg = crashInfo.exceptionClassName; 9940 String longMsg = crashInfo.exceptionMessage; 9941 String stackTrace = crashInfo.stackTrace; 9942 if (shortMsg != null && longMsg != null) { 9943 longMsg = shortMsg + ": " + longMsg; 9944 } else if (shortMsg != null) { 9945 longMsg = shortMsg; 9946 } 9947 9948 AppErrorResult result = new AppErrorResult(); 9949 synchronized (this) { 9950 if (mController != null) { 9951 try { 9952 String name = r != null ? r.processName : null; 9953 int pid = r != null ? r.pid : Binder.getCallingPid(); 9954 if (!mController.appCrashed(name, pid, 9955 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 9956 Slog.w(TAG, "Force-killing crashed app " + name 9957 + " at watcher's request"); 9958 Process.killProcess(pid); 9959 return; 9960 } 9961 } catch (RemoteException e) { 9962 mController = null; 9963 Watchdog.getInstance().setActivityController(null); 9964 } 9965 } 9966 9967 final long origId = Binder.clearCallingIdentity(); 9968 9969 // If this process is running instrumentation, finish it. 9970 if (r != null && r.instrumentationClass != null) { 9971 Slog.w(TAG, "Error in app " + r.processName 9972 + " running instrumentation " + r.instrumentationClass + ":"); 9973 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 9974 if (longMsg != null) Slog.w(TAG, " " + longMsg); 9975 Bundle info = new Bundle(); 9976 info.putString("shortMsg", shortMsg); 9977 info.putString("longMsg", longMsg); 9978 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 9979 Binder.restoreCallingIdentity(origId); 9980 return; 9981 } 9982 9983 // If we can't identify the process or it's already exceeded its crash quota, 9984 // quit right away without showing a crash dialog. 9985 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 9986 Binder.restoreCallingIdentity(origId); 9987 return; 9988 } 9989 9990 Message msg = Message.obtain(); 9991 msg.what = SHOW_ERROR_MSG; 9992 HashMap data = new HashMap(); 9993 data.put("result", result); 9994 data.put("app", r); 9995 msg.obj = data; 9996 mHandler.sendMessage(msg); 9997 9998 Binder.restoreCallingIdentity(origId); 9999 } 10000 10001 int res = result.get(); 10002 10003 Intent appErrorIntent = null; 10004 synchronized (this) { 10005 if (r != null && !r.isolated) { 10006 // XXX Can't keep track of crash time for isolated processes, 10007 // since they don't have a persistent identity. 10008 mProcessCrashTimes.put(r.info.processName, r.uid, 10009 SystemClock.uptimeMillis()); 10010 } 10011 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10012 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10013 } 10014 } 10015 10016 if (appErrorIntent != null) { 10017 try { 10018 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10019 } catch (ActivityNotFoundException e) { 10020 Slog.w(TAG, "bug report receiver dissappeared", e); 10021 } 10022 } 10023 } 10024 10025 Intent createAppErrorIntentLocked(ProcessRecord r, 10026 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10027 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10028 if (report == null) { 10029 return null; 10030 } 10031 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10032 result.setComponent(r.errorReportReceiver); 10033 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10034 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10035 return result; 10036 } 10037 10038 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10039 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10040 if (r.errorReportReceiver == null) { 10041 return null; 10042 } 10043 10044 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10045 return null; 10046 } 10047 10048 ApplicationErrorReport report = new ApplicationErrorReport(); 10049 report.packageName = r.info.packageName; 10050 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10051 report.processName = r.processName; 10052 report.time = timeMillis; 10053 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10054 10055 if (r.crashing || r.forceCrashReport) { 10056 report.type = ApplicationErrorReport.TYPE_CRASH; 10057 report.crashInfo = crashInfo; 10058 } else if (r.notResponding) { 10059 report.type = ApplicationErrorReport.TYPE_ANR; 10060 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10061 10062 report.anrInfo.activity = r.notRespondingReport.tag; 10063 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10064 report.anrInfo.info = r.notRespondingReport.longMsg; 10065 } 10066 10067 return report; 10068 } 10069 10070 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10071 enforceNotIsolatedCaller("getProcessesInErrorState"); 10072 // assume our apps are happy - lazy create the list 10073 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10074 10075 final boolean allUsers = ActivityManager.checkUidPermission( 10076 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10077 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10078 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10079 10080 synchronized (this) { 10081 10082 // iterate across all processes 10083 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10084 ProcessRecord app = mLruProcesses.get(i); 10085 if (!allUsers && app.userId != userId) { 10086 continue; 10087 } 10088 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10089 // This one's in trouble, so we'll generate a report for it 10090 // crashes are higher priority (in case there's a crash *and* an anr) 10091 ActivityManager.ProcessErrorStateInfo report = null; 10092 if (app.crashing) { 10093 report = app.crashingReport; 10094 } else if (app.notResponding) { 10095 report = app.notRespondingReport; 10096 } 10097 10098 if (report != null) { 10099 if (errList == null) { 10100 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10101 } 10102 errList.add(report); 10103 } else { 10104 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10105 " crashing = " + app.crashing + 10106 " notResponding = " + app.notResponding); 10107 } 10108 } 10109 } 10110 } 10111 10112 return errList; 10113 } 10114 10115 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10116 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10117 if (currApp != null) { 10118 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10119 } 10120 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10121 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10122 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10123 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10124 if (currApp != null) { 10125 currApp.lru = 0; 10126 } 10127 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10128 } else if (adj >= ProcessList.SERVICE_ADJ) { 10129 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10130 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10131 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10132 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10133 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10134 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10135 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10136 } else { 10137 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10138 } 10139 } 10140 10141 private void fillInProcMemInfo(ProcessRecord app, 10142 ActivityManager.RunningAppProcessInfo outInfo) { 10143 outInfo.pid = app.pid; 10144 outInfo.uid = app.info.uid; 10145 if (mHeavyWeightProcess == app) { 10146 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10147 } 10148 if (app.persistent) { 10149 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10150 } 10151 if (app.activities.size() > 0) { 10152 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10153 } 10154 outInfo.lastTrimLevel = app.trimMemoryLevel; 10155 int adj = app.curAdj; 10156 outInfo.importance = oomAdjToImportance(adj, outInfo); 10157 outInfo.importanceReasonCode = app.adjTypeCode; 10158 } 10159 10160 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10161 enforceNotIsolatedCaller("getRunningAppProcesses"); 10162 // Lazy instantiation of list 10163 List<ActivityManager.RunningAppProcessInfo> runList = null; 10164 final boolean allUsers = ActivityManager.checkUidPermission( 10165 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10166 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10167 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10168 synchronized (this) { 10169 // Iterate across all processes 10170 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10171 ProcessRecord app = mLruProcesses.get(i); 10172 if (!allUsers && app.userId != userId) { 10173 continue; 10174 } 10175 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10176 // Generate process state info for running application 10177 ActivityManager.RunningAppProcessInfo currApp = 10178 new ActivityManager.RunningAppProcessInfo(app.processName, 10179 app.pid, app.getPackageList()); 10180 fillInProcMemInfo(app, currApp); 10181 if (app.adjSource instanceof ProcessRecord) { 10182 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10183 currApp.importanceReasonImportance = oomAdjToImportance( 10184 app.adjSourceOom, null); 10185 } else if (app.adjSource instanceof ActivityRecord) { 10186 ActivityRecord r = (ActivityRecord)app.adjSource; 10187 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10188 } 10189 if (app.adjTarget instanceof ComponentName) { 10190 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10191 } 10192 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10193 // + " lru=" + currApp.lru); 10194 if (runList == null) { 10195 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10196 } 10197 runList.add(currApp); 10198 } 10199 } 10200 } 10201 return runList; 10202 } 10203 10204 public List<ApplicationInfo> getRunningExternalApplications() { 10205 enforceNotIsolatedCaller("getRunningExternalApplications"); 10206 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10207 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10208 if (runningApps != null && runningApps.size() > 0) { 10209 Set<String> extList = new HashSet<String>(); 10210 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10211 if (app.pkgList != null) { 10212 for (String pkg : app.pkgList) { 10213 extList.add(pkg); 10214 } 10215 } 10216 } 10217 IPackageManager pm = AppGlobals.getPackageManager(); 10218 for (String pkg : extList) { 10219 try { 10220 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10221 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10222 retList.add(info); 10223 } 10224 } catch (RemoteException e) { 10225 } 10226 } 10227 } 10228 return retList; 10229 } 10230 10231 @Override 10232 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10233 enforceNotIsolatedCaller("getMyMemoryState"); 10234 synchronized (this) { 10235 ProcessRecord proc; 10236 synchronized (mPidsSelfLocked) { 10237 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10238 } 10239 fillInProcMemInfo(proc, outInfo); 10240 } 10241 } 10242 10243 @Override 10244 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10245 if (checkCallingPermission(android.Manifest.permission.DUMP) 10246 != PackageManager.PERMISSION_GRANTED) { 10247 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10248 + Binder.getCallingPid() 10249 + ", uid=" + Binder.getCallingUid() 10250 + " without permission " 10251 + android.Manifest.permission.DUMP); 10252 return; 10253 } 10254 10255 boolean dumpAll = false; 10256 boolean dumpClient = false; 10257 String dumpPackage = null; 10258 10259 int opti = 0; 10260 while (opti < args.length) { 10261 String opt = args[opti]; 10262 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10263 break; 10264 } 10265 opti++; 10266 if ("-a".equals(opt)) { 10267 dumpAll = true; 10268 } else if ("-c".equals(opt)) { 10269 dumpClient = true; 10270 } else if ("-h".equals(opt)) { 10271 pw.println("Activity manager dump options:"); 10272 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10273 pw.println(" cmd may be one of:"); 10274 pw.println(" a[ctivities]: activity stack state"); 10275 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10276 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10277 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10278 pw.println(" o[om]: out of memory management"); 10279 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10280 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10281 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10282 pw.println(" service [COMP_SPEC]: service client-side state"); 10283 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10284 pw.println(" all: dump all activities"); 10285 pw.println(" top: dump the top activity"); 10286 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10287 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10288 pw.println(" a partial substring in a component name, a"); 10289 pw.println(" hex object identifier."); 10290 pw.println(" -a: include all available server state."); 10291 pw.println(" -c: include client state."); 10292 return; 10293 } else { 10294 pw.println("Unknown argument: " + opt + "; use -h for help"); 10295 } 10296 } 10297 10298 long origId = Binder.clearCallingIdentity(); 10299 boolean more = false; 10300 // Is the caller requesting to dump a particular piece of data? 10301 if (opti < args.length) { 10302 String cmd = args[opti]; 10303 opti++; 10304 if ("activities".equals(cmd) || "a".equals(cmd)) { 10305 synchronized (this) { 10306 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10307 } 10308 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10309 String[] newArgs; 10310 String name; 10311 if (opti >= args.length) { 10312 name = null; 10313 newArgs = EMPTY_STRING_ARRAY; 10314 } else { 10315 name = args[opti]; 10316 opti++; 10317 newArgs = new String[args.length - opti]; 10318 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10319 args.length - opti); 10320 } 10321 synchronized (this) { 10322 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10323 } 10324 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10325 String[] newArgs; 10326 String name; 10327 if (opti >= args.length) { 10328 name = null; 10329 newArgs = EMPTY_STRING_ARRAY; 10330 } else { 10331 name = args[opti]; 10332 opti++; 10333 newArgs = new String[args.length - opti]; 10334 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10335 args.length - opti); 10336 } 10337 synchronized (this) { 10338 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10339 } 10340 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10341 String[] newArgs; 10342 String name; 10343 if (opti >= args.length) { 10344 name = null; 10345 newArgs = EMPTY_STRING_ARRAY; 10346 } else { 10347 name = args[opti]; 10348 opti++; 10349 newArgs = new String[args.length - opti]; 10350 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10351 args.length - opti); 10352 } 10353 synchronized (this) { 10354 dumpProcessesLocked(fd, pw, args, opti, true, name); 10355 } 10356 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10357 synchronized (this) { 10358 dumpOomLocked(fd, pw, args, opti, true); 10359 } 10360 } else if ("provider".equals(cmd)) { 10361 String[] newArgs; 10362 String name; 10363 if (opti >= args.length) { 10364 name = null; 10365 newArgs = EMPTY_STRING_ARRAY; 10366 } else { 10367 name = args[opti]; 10368 opti++; 10369 newArgs = new String[args.length - opti]; 10370 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10371 } 10372 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10373 pw.println("No providers match: " + name); 10374 pw.println("Use -h for help."); 10375 } 10376 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10377 synchronized (this) { 10378 dumpProvidersLocked(fd, pw, args, opti, true, null); 10379 } 10380 } else if ("service".equals(cmd)) { 10381 String[] newArgs; 10382 String name; 10383 if (opti >= args.length) { 10384 name = null; 10385 newArgs = EMPTY_STRING_ARRAY; 10386 } else { 10387 name = args[opti]; 10388 opti++; 10389 newArgs = new String[args.length - opti]; 10390 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10391 args.length - opti); 10392 } 10393 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10394 pw.println("No services match: " + name); 10395 pw.println("Use -h for help."); 10396 } 10397 } else if ("package".equals(cmd)) { 10398 String[] newArgs; 10399 if (opti >= args.length) { 10400 pw.println("package: no package name specified"); 10401 pw.println("Use -h for help."); 10402 } else { 10403 dumpPackage = args[opti]; 10404 opti++; 10405 newArgs = new String[args.length - opti]; 10406 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10407 args.length - opti); 10408 args = newArgs; 10409 opti = 0; 10410 more = true; 10411 } 10412 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10413 synchronized (this) { 10414 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10415 } 10416 } else { 10417 // Dumping a single activity? 10418 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10419 pw.println("Bad activity command, or no activities match: " + cmd); 10420 pw.println("Use -h for help."); 10421 } 10422 } 10423 if (!more) { 10424 Binder.restoreCallingIdentity(origId); 10425 return; 10426 } 10427 } 10428 10429 // No piece of data specified, dump everything. 10430 synchronized (this) { 10431 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10432 pw.println(); 10433 if (dumpAll) { 10434 pw.println("-------------------------------------------------------------------------------"); 10435 } 10436 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10437 pw.println(); 10438 if (dumpAll) { 10439 pw.println("-------------------------------------------------------------------------------"); 10440 } 10441 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10442 pw.println(); 10443 if (dumpAll) { 10444 pw.println("-------------------------------------------------------------------------------"); 10445 } 10446 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10447 pw.println(); 10448 if (dumpAll) { 10449 pw.println("-------------------------------------------------------------------------------"); 10450 } 10451 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10452 pw.println(); 10453 if (dumpAll) { 10454 pw.println("-------------------------------------------------------------------------------"); 10455 } 10456 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10457 } 10458 Binder.restoreCallingIdentity(origId); 10459 } 10460 10461 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10462 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10463 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10464 10465 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10466 dumpPackage); 10467 boolean needSep = printedAnything; 10468 10469 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10470 dumpPackage, needSep, " mFocusedActivity: "); 10471 if (printed) { 10472 printedAnything = true; 10473 needSep = false; 10474 } 10475 10476 if (dumpPackage == null) { 10477 if (needSep) { 10478 pw.println(); 10479 } 10480 needSep = true; 10481 printedAnything = true; 10482 mStackSupervisor.dump(pw, " "); 10483 } 10484 10485 if (mRecentTasks.size() > 0) { 10486 boolean printedHeader = false; 10487 10488 final int N = mRecentTasks.size(); 10489 for (int i=0; i<N; i++) { 10490 TaskRecord tr = mRecentTasks.get(i); 10491 if (dumpPackage != null) { 10492 if (tr.realActivity == null || 10493 !dumpPackage.equals(tr.realActivity)) { 10494 continue; 10495 } 10496 } 10497 if (!printedHeader) { 10498 if (needSep) { 10499 pw.println(); 10500 } 10501 pw.println(" Recent tasks:"); 10502 printedHeader = true; 10503 printedAnything = true; 10504 } 10505 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10506 pw.println(tr); 10507 if (dumpAll) { 10508 mRecentTasks.get(i).dump(pw, " "); 10509 } 10510 } 10511 } 10512 10513 if (!printedAnything) { 10514 pw.println(" (nothing)"); 10515 } 10516 } 10517 10518 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10519 int opti, boolean dumpAll, String dumpPackage) { 10520 boolean needSep = false; 10521 boolean printedAnything = false; 10522 int numPers = 0; 10523 10524 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10525 10526 if (dumpAll) { 10527 final int NP = mProcessNames.getMap().size(); 10528 for (int ip=0; ip<NP; ip++) { 10529 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10530 final int NA = procs.size(); 10531 for (int ia=0; ia<NA; ia++) { 10532 ProcessRecord r = procs.valueAt(ia); 10533 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10534 continue; 10535 } 10536 if (!needSep) { 10537 pw.println(" All known processes:"); 10538 needSep = true; 10539 printedAnything = true; 10540 } 10541 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10542 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10543 pw.print(" "); pw.println(r); 10544 r.dump(pw, " "); 10545 if (r.persistent) { 10546 numPers++; 10547 } 10548 } 10549 } 10550 } 10551 10552 if (mIsolatedProcesses.size() > 0) { 10553 boolean printed = false; 10554 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10555 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10556 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10557 continue; 10558 } 10559 if (!printed) { 10560 if (needSep) { 10561 pw.println(); 10562 } 10563 pw.println(" Isolated process list (sorted by uid):"); 10564 printedAnything = true; 10565 printed = true; 10566 needSep = true; 10567 } 10568 pw.println(String.format("%sIsolated #%2d: %s", 10569 " ", i, r.toString())); 10570 } 10571 } 10572 10573 if (mLruProcesses.size() > 0) { 10574 if (needSep) { 10575 pw.println(); 10576 } 10577 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10578 pw.print(" total, non-act at "); 10579 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10580 pw.print(", non-svc at "); 10581 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10582 pw.println("):"); 10583 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10584 needSep = true; 10585 printedAnything = true; 10586 } 10587 10588 if (dumpAll || dumpPackage != null) { 10589 synchronized (mPidsSelfLocked) { 10590 boolean printed = false; 10591 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10592 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10593 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10594 continue; 10595 } 10596 if (!printed) { 10597 if (needSep) pw.println(); 10598 needSep = true; 10599 pw.println(" PID mappings:"); 10600 printed = true; 10601 printedAnything = true; 10602 } 10603 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10604 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10605 } 10606 } 10607 } 10608 10609 if (mForegroundProcesses.size() > 0) { 10610 synchronized (mPidsSelfLocked) { 10611 boolean printed = false; 10612 for (int i=0; i<mForegroundProcesses.size(); i++) { 10613 ProcessRecord r = mPidsSelfLocked.get( 10614 mForegroundProcesses.valueAt(i).pid); 10615 if (dumpPackage != null && (r == null 10616 || !r.pkgList.containsKey(dumpPackage))) { 10617 continue; 10618 } 10619 if (!printed) { 10620 if (needSep) pw.println(); 10621 needSep = true; 10622 pw.println(" Foreground Processes:"); 10623 printed = true; 10624 printedAnything = true; 10625 } 10626 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10627 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10628 } 10629 } 10630 } 10631 10632 if (mPersistentStartingProcesses.size() > 0) { 10633 if (needSep) pw.println(); 10634 needSep = true; 10635 printedAnything = true; 10636 pw.println(" Persisent processes that are starting:"); 10637 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10638 "Starting Norm", "Restarting PERS", dumpPackage); 10639 } 10640 10641 if (mRemovedProcesses.size() > 0) { 10642 if (needSep) pw.println(); 10643 needSep = true; 10644 printedAnything = true; 10645 pw.println(" Processes that are being removed:"); 10646 dumpProcessList(pw, this, mRemovedProcesses, " ", 10647 "Removed Norm", "Removed PERS", dumpPackage); 10648 } 10649 10650 if (mProcessesOnHold.size() > 0) { 10651 if (needSep) pw.println(); 10652 needSep = true; 10653 printedAnything = true; 10654 pw.println(" Processes that are on old until the system is ready:"); 10655 dumpProcessList(pw, this, mProcessesOnHold, " ", 10656 "OnHold Norm", "OnHold PERS", dumpPackage); 10657 } 10658 10659 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10660 10661 if (mProcessCrashTimes.getMap().size() > 0) { 10662 boolean printed = false; 10663 long now = SystemClock.uptimeMillis(); 10664 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10665 final int NP = pmap.size(); 10666 for (int ip=0; ip<NP; ip++) { 10667 String pname = pmap.keyAt(ip); 10668 SparseArray<Long> uids = pmap.valueAt(ip); 10669 final int N = uids.size(); 10670 for (int i=0; i<N; i++) { 10671 int puid = uids.keyAt(i); 10672 ProcessRecord r = mProcessNames.get(pname, puid); 10673 if (dumpPackage != null && (r == null 10674 || !r.pkgList.containsKey(dumpPackage))) { 10675 continue; 10676 } 10677 if (!printed) { 10678 if (needSep) pw.println(); 10679 needSep = true; 10680 pw.println(" Time since processes crashed:"); 10681 printed = true; 10682 printedAnything = true; 10683 } 10684 pw.print(" Process "); pw.print(pname); 10685 pw.print(" uid "); pw.print(puid); 10686 pw.print(": last crashed "); 10687 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10688 pw.println(" ago"); 10689 } 10690 } 10691 } 10692 10693 if (mBadProcesses.getMap().size() > 0) { 10694 boolean printed = false; 10695 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10696 final int NP = pmap.size(); 10697 for (int ip=0; ip<NP; ip++) { 10698 String pname = pmap.keyAt(ip); 10699 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10700 final int N = uids.size(); 10701 for (int i=0; i<N; i++) { 10702 int puid = uids.keyAt(i); 10703 ProcessRecord r = mProcessNames.get(pname, puid); 10704 if (dumpPackage != null && (r == null 10705 || !r.pkgList.containsKey(dumpPackage))) { 10706 continue; 10707 } 10708 if (!printed) { 10709 if (needSep) pw.println(); 10710 needSep = true; 10711 pw.println(" Bad processes:"); 10712 printedAnything = true; 10713 } 10714 BadProcessInfo info = uids.valueAt(i); 10715 pw.print(" Bad process "); pw.print(pname); 10716 pw.print(" uid "); pw.print(puid); 10717 pw.print(": crashed at time "); pw.println(info.time); 10718 if (info.shortMsg != null) { 10719 pw.print(" Short msg: "); pw.println(info.shortMsg); 10720 } 10721 if (info.longMsg != null) { 10722 pw.print(" Long msg: "); pw.println(info.longMsg); 10723 } 10724 if (info.stack != null) { 10725 pw.println(" Stack:"); 10726 int lastPos = 0; 10727 for (int pos=0; pos<info.stack.length(); pos++) { 10728 if (info.stack.charAt(pos) == '\n') { 10729 pw.print(" "); 10730 pw.write(info.stack, lastPos, pos-lastPos); 10731 pw.println(); 10732 lastPos = pos+1; 10733 } 10734 } 10735 if (lastPos < info.stack.length()) { 10736 pw.print(" "); 10737 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10738 pw.println(); 10739 } 10740 } 10741 } 10742 } 10743 } 10744 10745 if (dumpPackage == null) { 10746 pw.println(); 10747 needSep = false; 10748 pw.println(" mStartedUsers:"); 10749 for (int i=0; i<mStartedUsers.size(); i++) { 10750 UserStartedState uss = mStartedUsers.valueAt(i); 10751 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10752 pw.print(": "); uss.dump("", pw); 10753 } 10754 pw.print(" mStartedUserArray: ["); 10755 for (int i=0; i<mStartedUserArray.length; i++) { 10756 if (i > 0) pw.print(", "); 10757 pw.print(mStartedUserArray[i]); 10758 } 10759 pw.println("]"); 10760 pw.print(" mUserLru: ["); 10761 for (int i=0; i<mUserLru.size(); i++) { 10762 if (i > 0) pw.print(", "); 10763 pw.print(mUserLru.get(i)); 10764 } 10765 pw.println("]"); 10766 if (dumpAll) { 10767 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10768 } 10769 } 10770 if (mHomeProcess != null && (dumpPackage == null 10771 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10772 if (needSep) { 10773 pw.println(); 10774 needSep = false; 10775 } 10776 pw.println(" mHomeProcess: " + mHomeProcess); 10777 } 10778 if (mPreviousProcess != null && (dumpPackage == null 10779 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 10780 if (needSep) { 10781 pw.println(); 10782 needSep = false; 10783 } 10784 pw.println(" mPreviousProcess: " + mPreviousProcess); 10785 } 10786 if (dumpAll) { 10787 StringBuilder sb = new StringBuilder(128); 10788 sb.append(" mPreviousProcessVisibleTime: "); 10789 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 10790 pw.println(sb); 10791 } 10792 if (mHeavyWeightProcess != null && (dumpPackage == null 10793 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 10794 if (needSep) { 10795 pw.println(); 10796 needSep = false; 10797 } 10798 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10799 } 10800 if (dumpPackage == null) { 10801 pw.println(" mConfiguration: " + mConfiguration); 10802 } 10803 if (dumpAll) { 10804 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 10805 if (mCompatModePackages.getPackages().size() > 0) { 10806 boolean printed = false; 10807 for (Map.Entry<String, Integer> entry 10808 : mCompatModePackages.getPackages().entrySet()) { 10809 String pkg = entry.getKey(); 10810 int mode = entry.getValue(); 10811 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 10812 continue; 10813 } 10814 if (!printed) { 10815 pw.println(" mScreenCompatPackages:"); 10816 printed = true; 10817 } 10818 pw.print(" "); pw.print(pkg); pw.print(": "); 10819 pw.print(mode); pw.println(); 10820 } 10821 } 10822 } 10823 if (dumpPackage == null) { 10824 if (mSleeping || mWentToSleep || mLockScreenShown) { 10825 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 10826 + " mLockScreenShown " + mLockScreenShown); 10827 } 10828 if (mShuttingDown) { 10829 pw.println(" mShuttingDown=" + mShuttingDown); 10830 } 10831 } 10832 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 10833 || mOrigWaitForDebugger) { 10834 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 10835 || dumpPackage.equals(mOrigDebugApp)) { 10836 if (needSep) { 10837 pw.println(); 10838 needSep = false; 10839 } 10840 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 10841 + " mDebugTransient=" + mDebugTransient 10842 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 10843 } 10844 } 10845 if (mOpenGlTraceApp != null) { 10846 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 10847 if (needSep) { 10848 pw.println(); 10849 needSep = false; 10850 } 10851 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 10852 } 10853 } 10854 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 10855 || mProfileFd != null) { 10856 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 10857 if (needSep) { 10858 pw.println(); 10859 needSep = false; 10860 } 10861 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 10862 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 10863 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 10864 + mAutoStopProfiler); 10865 } 10866 } 10867 if (dumpPackage == null) { 10868 if (mAlwaysFinishActivities || mController != null) { 10869 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 10870 + " mController=" + mController); 10871 } 10872 if (dumpAll) { 10873 pw.println(" Total persistent processes: " + numPers); 10874 pw.println(" mStartRunning=" + mStartRunning 10875 + " mProcessesReady=" + mProcessesReady 10876 + " mSystemReady=" + mSystemReady); 10877 pw.println(" mBooting=" + mBooting 10878 + " mBooted=" + mBooted 10879 + " mFactoryTest=" + mFactoryTest); 10880 pw.print(" mLastPowerCheckRealtime="); 10881 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 10882 pw.println(""); 10883 pw.print(" mLastPowerCheckUptime="); 10884 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 10885 pw.println(""); 10886 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 10887 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 10888 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 10889 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 10890 + " (" + mLruProcesses.size() + " total)" 10891 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 10892 + " mNumServiceProcs=" + mNumServiceProcs 10893 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 10894 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 10895 + " mLastMemoryLevel" + mLastMemoryLevel 10896 + " mLastNumProcesses" + mLastNumProcesses); 10897 long now = SystemClock.uptimeMillis(); 10898 pw.print(" mLastIdleTime="); 10899 TimeUtils.formatDuration(now, mLastIdleTime, pw); 10900 pw.print(" mLowRamSinceLastIdle="); 10901 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 10902 pw.println(); 10903 } 10904 } 10905 10906 if (!printedAnything) { 10907 pw.println(" (nothing)"); 10908 } 10909 } 10910 10911 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 10912 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 10913 if (mProcessesToGc.size() > 0) { 10914 boolean printed = false; 10915 long now = SystemClock.uptimeMillis(); 10916 for (int i=0; i<mProcessesToGc.size(); i++) { 10917 ProcessRecord proc = mProcessesToGc.get(i); 10918 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 10919 continue; 10920 } 10921 if (!printed) { 10922 if (needSep) pw.println(); 10923 needSep = true; 10924 pw.println(" Processes that are waiting to GC:"); 10925 printed = true; 10926 } 10927 pw.print(" Process "); pw.println(proc); 10928 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 10929 pw.print(", last gced="); 10930 pw.print(now-proc.lastRequestedGc); 10931 pw.print(" ms ago, last lowMem="); 10932 pw.print(now-proc.lastLowMemory); 10933 pw.println(" ms ago"); 10934 10935 } 10936 } 10937 return needSep; 10938 } 10939 10940 void printOomLevel(PrintWriter pw, String name, int adj) { 10941 pw.print(" "); 10942 if (adj >= 0) { 10943 pw.print(' '); 10944 if (adj < 10) pw.print(' '); 10945 } else { 10946 if (adj > -10) pw.print(' '); 10947 } 10948 pw.print(adj); 10949 pw.print(": "); 10950 pw.print(name); 10951 pw.print(" ("); 10952 pw.print(mProcessList.getMemLevel(adj)/1024); 10953 pw.println(" kB)"); 10954 } 10955 10956 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10957 int opti, boolean dumpAll) { 10958 boolean needSep = false; 10959 10960 if (mLruProcesses.size() > 0) { 10961 if (needSep) pw.println(); 10962 needSep = true; 10963 pw.println(" OOM levels:"); 10964 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 10965 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 10966 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 10967 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 10968 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 10969 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 10970 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 10971 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 10972 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 10973 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 10974 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 10975 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 10976 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 10977 10978 if (needSep) pw.println(); 10979 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 10980 pw.print(" total, non-act at "); 10981 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10982 pw.print(", non-svc at "); 10983 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10984 pw.println("):"); 10985 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 10986 needSep = true; 10987 } 10988 10989 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 10990 10991 pw.println(); 10992 pw.println(" mHomeProcess: " + mHomeProcess); 10993 pw.println(" mPreviousProcess: " + mPreviousProcess); 10994 if (mHeavyWeightProcess != null) { 10995 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10996 } 10997 10998 return true; 10999 } 11000 11001 /** 11002 * There are three ways to call this: 11003 * - no provider specified: dump all the providers 11004 * - a flattened component name that matched an existing provider was specified as the 11005 * first arg: dump that one provider 11006 * - the first arg isn't the flattened component name of an existing provider: 11007 * dump all providers whose component contains the first arg as a substring 11008 */ 11009 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11010 int opti, boolean dumpAll) { 11011 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11012 } 11013 11014 static class ItemMatcher { 11015 ArrayList<ComponentName> components; 11016 ArrayList<String> strings; 11017 ArrayList<Integer> objects; 11018 boolean all; 11019 11020 ItemMatcher() { 11021 all = true; 11022 } 11023 11024 void build(String name) { 11025 ComponentName componentName = ComponentName.unflattenFromString(name); 11026 if (componentName != null) { 11027 if (components == null) { 11028 components = new ArrayList<ComponentName>(); 11029 } 11030 components.add(componentName); 11031 all = false; 11032 } else { 11033 int objectId = 0; 11034 // Not a '/' separated full component name; maybe an object ID? 11035 try { 11036 objectId = Integer.parseInt(name, 16); 11037 if (objects == null) { 11038 objects = new ArrayList<Integer>(); 11039 } 11040 objects.add(objectId); 11041 all = false; 11042 } catch (RuntimeException e) { 11043 // Not an integer; just do string match. 11044 if (strings == null) { 11045 strings = new ArrayList<String>(); 11046 } 11047 strings.add(name); 11048 all = false; 11049 } 11050 } 11051 } 11052 11053 int build(String[] args, int opti) { 11054 for (; opti<args.length; opti++) { 11055 String name = args[opti]; 11056 if ("--".equals(name)) { 11057 return opti+1; 11058 } 11059 build(name); 11060 } 11061 return opti; 11062 } 11063 11064 boolean match(Object object, ComponentName comp) { 11065 if (all) { 11066 return true; 11067 } 11068 if (components != null) { 11069 for (int i=0; i<components.size(); i++) { 11070 if (components.get(i).equals(comp)) { 11071 return true; 11072 } 11073 } 11074 } 11075 if (objects != null) { 11076 for (int i=0; i<objects.size(); i++) { 11077 if (System.identityHashCode(object) == objects.get(i)) { 11078 return true; 11079 } 11080 } 11081 } 11082 if (strings != null) { 11083 String flat = comp.flattenToString(); 11084 for (int i=0; i<strings.size(); i++) { 11085 if (flat.contains(strings.get(i))) { 11086 return true; 11087 } 11088 } 11089 } 11090 return false; 11091 } 11092 } 11093 11094 /** 11095 * There are three things that cmd can be: 11096 * - a flattened component name that matches an existing activity 11097 * - the cmd arg isn't the flattened component name of an existing activity: 11098 * dump all activity whose component contains the cmd as a substring 11099 * - A hex number of the ActivityRecord object instance. 11100 */ 11101 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11102 int opti, boolean dumpAll) { 11103 ArrayList<ActivityRecord> activities; 11104 11105 synchronized (this) { 11106 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11107 } 11108 11109 if (activities.size() <= 0) { 11110 return false; 11111 } 11112 11113 String[] newArgs = new String[args.length - opti]; 11114 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11115 11116 TaskRecord lastTask = null; 11117 boolean needSep = false; 11118 for (int i=activities.size()-1; i>=0; i--) { 11119 ActivityRecord r = activities.get(i); 11120 if (needSep) { 11121 pw.println(); 11122 } 11123 needSep = true; 11124 synchronized (this) { 11125 if (lastTask != r.task) { 11126 lastTask = r.task; 11127 pw.print("TASK "); pw.print(lastTask.affinity); 11128 pw.print(" id="); pw.println(lastTask.taskId); 11129 if (dumpAll) { 11130 lastTask.dump(pw, " "); 11131 } 11132 } 11133 } 11134 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11135 } 11136 return true; 11137 } 11138 11139 /** 11140 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11141 * there is a thread associated with the activity. 11142 */ 11143 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11144 final ActivityRecord r, String[] args, boolean dumpAll) { 11145 String innerPrefix = prefix + " "; 11146 synchronized (this) { 11147 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11148 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11149 pw.print(" pid="); 11150 if (r.app != null) pw.println(r.app.pid); 11151 else pw.println("(not running)"); 11152 if (dumpAll) { 11153 r.dump(pw, innerPrefix); 11154 } 11155 } 11156 if (r.app != null && r.app.thread != null) { 11157 // flush anything that is already in the PrintWriter since the thread is going 11158 // to write to the file descriptor directly 11159 pw.flush(); 11160 try { 11161 TransferPipe tp = new TransferPipe(); 11162 try { 11163 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11164 r.appToken, innerPrefix, args); 11165 tp.go(fd); 11166 } finally { 11167 tp.kill(); 11168 } 11169 } catch (IOException e) { 11170 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11171 } catch (RemoteException e) { 11172 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11173 } 11174 } 11175 } 11176 11177 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11178 int opti, boolean dumpAll, String dumpPackage) { 11179 boolean needSep = false; 11180 boolean onlyHistory = false; 11181 boolean printedAnything = false; 11182 11183 if ("history".equals(dumpPackage)) { 11184 if (opti < args.length && "-s".equals(args[opti])) { 11185 dumpAll = false; 11186 } 11187 onlyHistory = true; 11188 dumpPackage = null; 11189 } 11190 11191 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11192 if (!onlyHistory && dumpAll) { 11193 if (mRegisteredReceivers.size() > 0) { 11194 boolean printed = false; 11195 Iterator it = mRegisteredReceivers.values().iterator(); 11196 while (it.hasNext()) { 11197 ReceiverList r = (ReceiverList)it.next(); 11198 if (dumpPackage != null && (r.app == null || 11199 !dumpPackage.equals(r.app.info.packageName))) { 11200 continue; 11201 } 11202 if (!printed) { 11203 pw.println(" Registered Receivers:"); 11204 needSep = true; 11205 printed = true; 11206 printedAnything = true; 11207 } 11208 pw.print(" * "); pw.println(r); 11209 r.dump(pw, " "); 11210 } 11211 } 11212 11213 if (mReceiverResolver.dump(pw, needSep ? 11214 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11215 " ", dumpPackage, false)) { 11216 needSep = true; 11217 printedAnything = true; 11218 } 11219 } 11220 11221 for (BroadcastQueue q : mBroadcastQueues) { 11222 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11223 printedAnything |= needSep; 11224 } 11225 11226 needSep = true; 11227 11228 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11229 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11230 if (needSep) { 11231 pw.println(); 11232 } 11233 needSep = true; 11234 printedAnything = true; 11235 pw.print(" Sticky broadcasts for user "); 11236 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11237 StringBuilder sb = new StringBuilder(128); 11238 for (Map.Entry<String, ArrayList<Intent>> ent 11239 : mStickyBroadcasts.valueAt(user).entrySet()) { 11240 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11241 if (dumpAll) { 11242 pw.println(":"); 11243 ArrayList<Intent> intents = ent.getValue(); 11244 final int N = intents.size(); 11245 for (int i=0; i<N; i++) { 11246 sb.setLength(0); 11247 sb.append(" Intent: "); 11248 intents.get(i).toShortString(sb, false, true, false, false); 11249 pw.println(sb.toString()); 11250 Bundle bundle = intents.get(i).getExtras(); 11251 if (bundle != null) { 11252 pw.print(" "); 11253 pw.println(bundle.toString()); 11254 } 11255 } 11256 } else { 11257 pw.println(""); 11258 } 11259 } 11260 } 11261 } 11262 11263 if (!onlyHistory && dumpAll) { 11264 pw.println(); 11265 for (BroadcastQueue queue : mBroadcastQueues) { 11266 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11267 + queue.mBroadcastsScheduled); 11268 } 11269 pw.println(" mHandler:"); 11270 mHandler.dump(new PrintWriterPrinter(pw), " "); 11271 needSep = true; 11272 printedAnything = true; 11273 } 11274 11275 if (!printedAnything) { 11276 pw.println(" (nothing)"); 11277 } 11278 } 11279 11280 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11281 int opti, boolean dumpAll, String dumpPackage) { 11282 boolean needSep; 11283 boolean printedAnything = false; 11284 11285 ItemMatcher matcher = new ItemMatcher(); 11286 matcher.build(args, opti); 11287 11288 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11289 11290 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11291 printedAnything |= needSep; 11292 11293 if (mLaunchingProviders.size() > 0) { 11294 boolean printed = false; 11295 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11296 ContentProviderRecord r = mLaunchingProviders.get(i); 11297 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11298 continue; 11299 } 11300 if (!printed) { 11301 if (needSep) pw.println(); 11302 needSep = true; 11303 pw.println(" Launching content providers:"); 11304 printed = true; 11305 printedAnything = true; 11306 } 11307 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11308 pw.println(r); 11309 } 11310 } 11311 11312 if (mGrantedUriPermissions.size() > 0) { 11313 boolean printed = false; 11314 int dumpUid = -2; 11315 if (dumpPackage != null) { 11316 try { 11317 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11318 } catch (NameNotFoundException e) { 11319 dumpUid = -1; 11320 } 11321 } 11322 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11323 int uid = mGrantedUriPermissions.keyAt(i); 11324 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11325 continue; 11326 } 11327 ArrayMap<Uri, UriPermission> perms 11328 = mGrantedUriPermissions.valueAt(i); 11329 if (!printed) { 11330 if (needSep) pw.println(); 11331 needSep = true; 11332 pw.println(" Granted Uri Permissions:"); 11333 printed = true; 11334 printedAnything = true; 11335 } 11336 pw.print(" * UID "); pw.print(uid); 11337 pw.println(" holds:"); 11338 for (UriPermission perm : perms.values()) { 11339 pw.print(" "); pw.println(perm); 11340 if (dumpAll) { 11341 perm.dump(pw, " "); 11342 } 11343 } 11344 } 11345 } 11346 11347 if (!printedAnything) { 11348 pw.println(" (nothing)"); 11349 } 11350 } 11351 11352 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11353 int opti, boolean dumpAll, String dumpPackage) { 11354 boolean printed = false; 11355 11356 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11357 11358 if (mIntentSenderRecords.size() > 0) { 11359 Iterator<WeakReference<PendingIntentRecord>> it 11360 = mIntentSenderRecords.values().iterator(); 11361 while (it.hasNext()) { 11362 WeakReference<PendingIntentRecord> ref = it.next(); 11363 PendingIntentRecord rec = ref != null ? ref.get(): null; 11364 if (dumpPackage != null && (rec == null 11365 || !dumpPackage.equals(rec.key.packageName))) { 11366 continue; 11367 } 11368 printed = true; 11369 if (rec != null) { 11370 pw.print(" * "); pw.println(rec); 11371 if (dumpAll) { 11372 rec.dump(pw, " "); 11373 } 11374 } else { 11375 pw.print(" * "); pw.println(ref); 11376 } 11377 } 11378 } 11379 11380 if (!printed) { 11381 pw.println(" (nothing)"); 11382 } 11383 } 11384 11385 private static final int dumpProcessList(PrintWriter pw, 11386 ActivityManagerService service, List list, 11387 String prefix, String normalLabel, String persistentLabel, 11388 String dumpPackage) { 11389 int numPers = 0; 11390 final int N = list.size()-1; 11391 for (int i=N; i>=0; i--) { 11392 ProcessRecord r = (ProcessRecord)list.get(i); 11393 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11394 continue; 11395 } 11396 pw.println(String.format("%s%s #%2d: %s", 11397 prefix, (r.persistent ? persistentLabel : normalLabel), 11398 i, r.toString())); 11399 if (r.persistent) { 11400 numPers++; 11401 } 11402 } 11403 return numPers; 11404 } 11405 11406 private static final boolean dumpProcessOomList(PrintWriter pw, 11407 ActivityManagerService service, List<ProcessRecord> origList, 11408 String prefix, String normalLabel, String persistentLabel, 11409 boolean inclDetails, String dumpPackage) { 11410 11411 ArrayList<Pair<ProcessRecord, Integer>> list 11412 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11413 for (int i=0; i<origList.size(); i++) { 11414 ProcessRecord r = origList.get(i); 11415 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11416 continue; 11417 } 11418 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11419 } 11420 11421 if (list.size() <= 0) { 11422 return false; 11423 } 11424 11425 Comparator<Pair<ProcessRecord, Integer>> comparator 11426 = new Comparator<Pair<ProcessRecord, Integer>>() { 11427 @Override 11428 public int compare(Pair<ProcessRecord, Integer> object1, 11429 Pair<ProcessRecord, Integer> object2) { 11430 if (object1.first.setAdj != object2.first.setAdj) { 11431 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11432 } 11433 if (object1.second.intValue() != object2.second.intValue()) { 11434 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11435 } 11436 return 0; 11437 } 11438 }; 11439 11440 Collections.sort(list, comparator); 11441 11442 final long curRealtime = SystemClock.elapsedRealtime(); 11443 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11444 final long curUptime = SystemClock.uptimeMillis(); 11445 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11446 11447 for (int i=list.size()-1; i>=0; i--) { 11448 ProcessRecord r = list.get(i).first; 11449 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11450 char schedGroup; 11451 switch (r.setSchedGroup) { 11452 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11453 schedGroup = 'B'; 11454 break; 11455 case Process.THREAD_GROUP_DEFAULT: 11456 schedGroup = 'F'; 11457 break; 11458 default: 11459 schedGroup = '?'; 11460 break; 11461 } 11462 char foreground; 11463 if (r.foregroundActivities) { 11464 foreground = 'A'; 11465 } else if (r.foregroundServices) { 11466 foreground = 'S'; 11467 } else { 11468 foreground = ' '; 11469 } 11470 String procState = ProcessList.makeProcStateString(r.curProcState); 11471 pw.print(prefix); 11472 pw.print(r.persistent ? persistentLabel : normalLabel); 11473 pw.print(" #"); 11474 int num = (origList.size()-1)-list.get(i).second; 11475 if (num < 10) pw.print(' '); 11476 pw.print(num); 11477 pw.print(": "); 11478 pw.print(oomAdj); 11479 pw.print(' '); 11480 pw.print(schedGroup); 11481 pw.print('/'); 11482 pw.print(foreground); 11483 pw.print('/'); 11484 pw.print(procState); 11485 pw.print(" trm:"); 11486 if (r.trimMemoryLevel < 10) pw.print(' '); 11487 pw.print(r.trimMemoryLevel); 11488 pw.print(' '); 11489 pw.print(r.toShortString()); 11490 pw.print(" ("); 11491 pw.print(r.adjType); 11492 pw.println(')'); 11493 if (r.adjSource != null || r.adjTarget != null) { 11494 pw.print(prefix); 11495 pw.print(" "); 11496 if (r.adjTarget instanceof ComponentName) { 11497 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11498 } else if (r.adjTarget != null) { 11499 pw.print(r.adjTarget.toString()); 11500 } else { 11501 pw.print("{null}"); 11502 } 11503 pw.print("<="); 11504 if (r.adjSource instanceof ProcessRecord) { 11505 pw.print("Proc{"); 11506 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11507 pw.println("}"); 11508 } else if (r.adjSource != null) { 11509 pw.println(r.adjSource.toString()); 11510 } else { 11511 pw.println("{null}"); 11512 } 11513 } 11514 if (inclDetails) { 11515 pw.print(prefix); 11516 pw.print(" "); 11517 pw.print("oom: max="); pw.print(r.maxAdj); 11518 pw.print(" curRaw="); pw.print(r.curRawAdj); 11519 pw.print(" setRaw="); pw.print(r.setRawAdj); 11520 pw.print(" cur="); pw.print(r.curAdj); 11521 pw.print(" set="); pw.println(r.setAdj); 11522 pw.print(prefix); 11523 pw.print(" "); 11524 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11525 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11526 pw.print(" lastPss="); pw.print(r.lastPss); 11527 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11528 pw.print(prefix); 11529 pw.print(" "); 11530 pw.print("keeping="); pw.print(r.keeping); 11531 pw.print(" cached="); pw.print(r.cached); 11532 pw.print(" empty="); pw.print(r.empty); 11533 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11534 11535 if (!r.keeping) { 11536 if (r.lastWakeTime != 0) { 11537 long wtime; 11538 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11539 synchronized (stats) { 11540 wtime = stats.getProcessWakeTime(r.info.uid, 11541 r.pid, curRealtime); 11542 } 11543 long timeUsed = wtime - r.lastWakeTime; 11544 pw.print(prefix); 11545 pw.print(" "); 11546 pw.print("keep awake over "); 11547 TimeUtils.formatDuration(realtimeSince, pw); 11548 pw.print(" used "); 11549 TimeUtils.formatDuration(timeUsed, pw); 11550 pw.print(" ("); 11551 pw.print((timeUsed*100)/realtimeSince); 11552 pw.println("%)"); 11553 } 11554 if (r.lastCpuTime != 0) { 11555 long timeUsed = r.curCpuTime - r.lastCpuTime; 11556 pw.print(prefix); 11557 pw.print(" "); 11558 pw.print("run cpu over "); 11559 TimeUtils.formatDuration(uptimeSince, pw); 11560 pw.print(" used "); 11561 TimeUtils.formatDuration(timeUsed, pw); 11562 pw.print(" ("); 11563 pw.print((timeUsed*100)/uptimeSince); 11564 pw.println("%)"); 11565 } 11566 } 11567 } 11568 } 11569 return true; 11570 } 11571 11572 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11573 ArrayList<ProcessRecord> procs; 11574 synchronized (this) { 11575 if (args != null && args.length > start 11576 && args[start].charAt(0) != '-') { 11577 procs = new ArrayList<ProcessRecord>(); 11578 int pid = -1; 11579 try { 11580 pid = Integer.parseInt(args[start]); 11581 } catch (NumberFormatException e) { 11582 } 11583 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11584 ProcessRecord proc = mLruProcesses.get(i); 11585 if (proc.pid == pid) { 11586 procs.add(proc); 11587 } else if (proc.processName.equals(args[start])) { 11588 procs.add(proc); 11589 } 11590 } 11591 if (procs.size() <= 0) { 11592 return null; 11593 } 11594 } else { 11595 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11596 } 11597 } 11598 return procs; 11599 } 11600 11601 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11602 PrintWriter pw, String[] args) { 11603 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11604 if (procs == null) { 11605 pw.println("No process found for: " + args[0]); 11606 return; 11607 } 11608 11609 long uptime = SystemClock.uptimeMillis(); 11610 long realtime = SystemClock.elapsedRealtime(); 11611 pw.println("Applications Graphics Acceleration Info:"); 11612 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11613 11614 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11615 ProcessRecord r = procs.get(i); 11616 if (r.thread != null) { 11617 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11618 pw.flush(); 11619 try { 11620 TransferPipe tp = new TransferPipe(); 11621 try { 11622 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11623 tp.go(fd); 11624 } finally { 11625 tp.kill(); 11626 } 11627 } catch (IOException e) { 11628 pw.println("Failure while dumping the app: " + r); 11629 pw.flush(); 11630 } catch (RemoteException e) { 11631 pw.println("Got a RemoteException while dumping the app " + r); 11632 pw.flush(); 11633 } 11634 } 11635 } 11636 } 11637 11638 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11639 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11640 if (procs == null) { 11641 pw.println("No process found for: " + args[0]); 11642 return; 11643 } 11644 11645 pw.println("Applications Database Info:"); 11646 11647 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11648 ProcessRecord r = procs.get(i); 11649 if (r.thread != null) { 11650 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11651 pw.flush(); 11652 try { 11653 TransferPipe tp = new TransferPipe(); 11654 try { 11655 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11656 tp.go(fd); 11657 } finally { 11658 tp.kill(); 11659 } 11660 } catch (IOException e) { 11661 pw.println("Failure while dumping the app: " + r); 11662 pw.flush(); 11663 } catch (RemoteException e) { 11664 pw.println("Got a RemoteException while dumping the app " + r); 11665 pw.flush(); 11666 } 11667 } 11668 } 11669 } 11670 11671 final static class MemItem { 11672 final boolean isProc; 11673 final String label; 11674 final String shortLabel; 11675 final long pss; 11676 final int id; 11677 final boolean hasActivities; 11678 ArrayList<MemItem> subitems; 11679 11680 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11681 boolean _hasActivities) { 11682 isProc = true; 11683 label = _label; 11684 shortLabel = _shortLabel; 11685 pss = _pss; 11686 id = _id; 11687 hasActivities = _hasActivities; 11688 } 11689 11690 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11691 isProc = false; 11692 label = _label; 11693 shortLabel = _shortLabel; 11694 pss = _pss; 11695 id = _id; 11696 hasActivities = false; 11697 } 11698 } 11699 11700 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11701 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11702 if (sort && !isCompact) { 11703 Collections.sort(items, new Comparator<MemItem>() { 11704 @Override 11705 public int compare(MemItem lhs, MemItem rhs) { 11706 if (lhs.pss < rhs.pss) { 11707 return 1; 11708 } else if (lhs.pss > rhs.pss) { 11709 return -1; 11710 } 11711 return 0; 11712 } 11713 }); 11714 } 11715 11716 for (int i=0; i<items.size(); i++) { 11717 MemItem mi = items.get(i); 11718 if (!isCompact) { 11719 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11720 } else if (mi.isProc) { 11721 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11722 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11723 pw.println(mi.hasActivities ? ",a" : ",e"); 11724 } else { 11725 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11726 pw.println(mi.pss); 11727 } 11728 if (mi.subitems != null) { 11729 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11730 true, isCompact); 11731 } 11732 } 11733 } 11734 11735 // These are in KB. 11736 static final long[] DUMP_MEM_BUCKETS = new long[] { 11737 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11738 120*1024, 160*1024, 200*1024, 11739 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11740 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11741 }; 11742 11743 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11744 boolean stackLike) { 11745 int start = label.lastIndexOf('.'); 11746 if (start >= 0) start++; 11747 else start = 0; 11748 int end = label.length(); 11749 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11750 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11751 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11752 out.append(bucket); 11753 out.append(stackLike ? "MB." : "MB "); 11754 out.append(label, start, end); 11755 return; 11756 } 11757 } 11758 out.append(memKB/1024); 11759 out.append(stackLike ? "MB." : "MB "); 11760 out.append(label, start, end); 11761 } 11762 11763 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11764 ProcessList.NATIVE_ADJ, 11765 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11766 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11767 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11768 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11769 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11770 }; 11771 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11772 "Native", 11773 "System", "Persistent", "Foreground", 11774 "Visible", "Perceptible", 11775 "Heavy Weight", "Backup", 11776 "A Services", "Home", 11777 "Previous", "B Services", "Cached" 11778 }; 11779 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 11780 "native", 11781 "sys", "pers", "fore", 11782 "vis", "percept", 11783 "heavy", "backup", 11784 "servicea", "home", 11785 "prev", "serviceb", "cached" 11786 }; 11787 11788 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 11789 long realtime, boolean isCheckinRequest, boolean isCompact) { 11790 if (isCheckinRequest || isCompact) { 11791 // short checkin version 11792 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 11793 } else { 11794 pw.println("Applications Memory Usage (kB):"); 11795 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11796 } 11797 } 11798 11799 final void dumpApplicationMemoryUsage(FileDescriptor fd, 11800 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 11801 boolean dumpDetails = false; 11802 boolean dumpFullDetails = false; 11803 boolean dumpDalvik = false; 11804 boolean oomOnly = false; 11805 boolean isCompact = false; 11806 boolean localOnly = false; 11807 11808 int opti = 0; 11809 while (opti < args.length) { 11810 String opt = args[opti]; 11811 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11812 break; 11813 } 11814 opti++; 11815 if ("-a".equals(opt)) { 11816 dumpDetails = true; 11817 dumpFullDetails = true; 11818 dumpDalvik = true; 11819 } else if ("-d".equals(opt)) { 11820 dumpDalvik = true; 11821 } else if ("-c".equals(opt)) { 11822 isCompact = true; 11823 } else if ("--oom".equals(opt)) { 11824 oomOnly = true; 11825 } else if ("--local".equals(opt)) { 11826 localOnly = true; 11827 } else if ("-h".equals(opt)) { 11828 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 11829 pw.println(" -a: include all available information for each process."); 11830 pw.println(" -d: include dalvik details when dumping process details."); 11831 pw.println(" -c: dump in a compact machine-parseable representation."); 11832 pw.println(" --oom: only show processes organized by oom adj."); 11833 pw.println(" --local: only collect details locally, don't call process."); 11834 pw.println("If [process] is specified it can be the name or "); 11835 pw.println("pid of a specific process to dump."); 11836 return; 11837 } else { 11838 pw.println("Unknown argument: " + opt + "; use -h for help"); 11839 } 11840 } 11841 11842 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 11843 long uptime = SystemClock.uptimeMillis(); 11844 long realtime = SystemClock.elapsedRealtime(); 11845 final long[] tmpLong = new long[1]; 11846 11847 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 11848 if (procs == null) { 11849 // No Java processes. Maybe they want to print a native process. 11850 if (args != null && args.length > opti 11851 && args[opti].charAt(0) != '-') { 11852 ArrayList<ProcessCpuTracker.Stats> nativeProcs 11853 = new ArrayList<ProcessCpuTracker.Stats>(); 11854 updateCpuStatsNow(); 11855 int findPid = -1; 11856 try { 11857 findPid = Integer.parseInt(args[opti]); 11858 } catch (NumberFormatException e) { 11859 } 11860 synchronized (mProcessCpuThread) { 11861 final int N = mProcessCpuTracker.countStats(); 11862 for (int i=0; i<N; i++) { 11863 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 11864 if (st.pid == findPid || (st.baseName != null 11865 && st.baseName.equals(args[opti]))) { 11866 nativeProcs.add(st); 11867 } 11868 } 11869 } 11870 if (nativeProcs.size() > 0) { 11871 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 11872 isCompact); 11873 Debug.MemoryInfo mi = null; 11874 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 11875 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 11876 final int pid = r.pid; 11877 if (!isCheckinRequest && dumpDetails) { 11878 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 11879 } 11880 if (mi == null) { 11881 mi = new Debug.MemoryInfo(); 11882 } 11883 if (dumpDetails || (!brief && !oomOnly)) { 11884 Debug.getMemoryInfo(pid, mi); 11885 } else { 11886 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11887 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11888 } 11889 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11890 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 11891 if (isCheckinRequest) { 11892 pw.println(); 11893 } 11894 } 11895 return; 11896 } 11897 } 11898 pw.println("No process found for: " + args[opti]); 11899 return; 11900 } 11901 11902 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 11903 dumpDetails = true; 11904 } 11905 11906 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 11907 11908 String[] innerArgs = new String[args.length-opti]; 11909 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 11910 11911 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 11912 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 11913 long nativePss=0, dalvikPss=0, otherPss=0; 11914 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 11915 11916 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 11917 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 11918 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 11919 11920 long totalPss = 0; 11921 long cachedPss = 0; 11922 11923 Debug.MemoryInfo mi = null; 11924 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11925 final ProcessRecord r = procs.get(i); 11926 final IApplicationThread thread; 11927 final int pid; 11928 final int oomAdj; 11929 final boolean hasActivities; 11930 synchronized (this) { 11931 thread = r.thread; 11932 pid = r.pid; 11933 oomAdj = r.getSetAdjWithServices(); 11934 hasActivities = r.activities.size() > 0; 11935 } 11936 if (thread != null) { 11937 if (!isCheckinRequest && dumpDetails) { 11938 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 11939 } 11940 if (mi == null) { 11941 mi = new Debug.MemoryInfo(); 11942 } 11943 if (dumpDetails || (!brief && !oomOnly)) { 11944 Debug.getMemoryInfo(pid, mi); 11945 } else { 11946 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11947 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11948 } 11949 if (dumpDetails) { 11950 if (localOnly) { 11951 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11952 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 11953 if (isCheckinRequest) { 11954 pw.println(); 11955 } 11956 } else { 11957 try { 11958 pw.flush(); 11959 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 11960 dumpDalvik, innerArgs); 11961 } catch (RemoteException e) { 11962 if (!isCheckinRequest) { 11963 pw.println("Got RemoteException!"); 11964 pw.flush(); 11965 } 11966 } 11967 } 11968 } 11969 11970 final long myTotalPss = mi.getTotalPss(); 11971 final long myTotalUss = mi.getTotalUss(); 11972 11973 synchronized (this) { 11974 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 11975 // Record this for posterity if the process has been stable. 11976 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 11977 } 11978 } 11979 11980 if (!isCheckinRequest && mi != null) { 11981 totalPss += myTotalPss; 11982 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 11983 (hasActivities ? " / activities)" : ")"), 11984 r.processName, myTotalPss, pid, hasActivities); 11985 procMems.add(pssItem); 11986 procMemsMap.put(pid, pssItem); 11987 11988 nativePss += mi.nativePss; 11989 dalvikPss += mi.dalvikPss; 11990 otherPss += mi.otherPss; 11991 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 11992 long mem = mi.getOtherPss(j); 11993 miscPss[j] += mem; 11994 otherPss -= mem; 11995 } 11996 11997 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 11998 cachedPss += myTotalPss; 11999 } 12000 12001 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12002 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12003 || oomIndex == (oomPss.length-1)) { 12004 oomPss[oomIndex] += myTotalPss; 12005 if (oomProcs[oomIndex] == null) { 12006 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12007 } 12008 oomProcs[oomIndex].add(pssItem); 12009 break; 12010 } 12011 } 12012 } 12013 } 12014 } 12015 12016 if (!isCheckinRequest && procs.size() > 1) { 12017 // If we are showing aggregations, also look for native processes to 12018 // include so that our aggregations are more accurate. 12019 updateCpuStatsNow(); 12020 synchronized (mProcessCpuThread) { 12021 final int N = mProcessCpuTracker.countStats(); 12022 for (int i=0; i<N; i++) { 12023 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12024 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12025 if (mi == null) { 12026 mi = new Debug.MemoryInfo(); 12027 } 12028 if (!brief && !oomOnly) { 12029 Debug.getMemoryInfo(st.pid, mi); 12030 } else { 12031 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12032 mi.nativePrivateDirty = (int)tmpLong[0]; 12033 } 12034 12035 final long myTotalPss = mi.getTotalPss(); 12036 totalPss += myTotalPss; 12037 12038 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12039 st.name, myTotalPss, st.pid, false); 12040 procMems.add(pssItem); 12041 12042 nativePss += mi.nativePss; 12043 dalvikPss += mi.dalvikPss; 12044 otherPss += mi.otherPss; 12045 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12046 long mem = mi.getOtherPss(j); 12047 miscPss[j] += mem; 12048 otherPss -= mem; 12049 } 12050 oomPss[0] += myTotalPss; 12051 if (oomProcs[0] == null) { 12052 oomProcs[0] = new ArrayList<MemItem>(); 12053 } 12054 oomProcs[0].add(pssItem); 12055 } 12056 } 12057 } 12058 12059 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12060 12061 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12062 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12063 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12064 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12065 String label = Debug.MemoryInfo.getOtherLabel(j); 12066 catMems.add(new MemItem(label, label, miscPss[j], j)); 12067 } 12068 12069 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12070 for (int j=0; j<oomPss.length; j++) { 12071 if (oomPss[j] != 0) { 12072 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12073 : DUMP_MEM_OOM_LABEL[j]; 12074 MemItem item = new MemItem(label, label, oomPss[j], 12075 DUMP_MEM_OOM_ADJ[j]); 12076 item.subitems = oomProcs[j]; 12077 oomMems.add(item); 12078 } 12079 } 12080 12081 if (!brief && !oomOnly && !isCompact) { 12082 pw.println(); 12083 pw.println("Total PSS by process:"); 12084 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12085 pw.println(); 12086 } 12087 if (!isCompact) { 12088 pw.println("Total PSS by OOM adjustment:"); 12089 } 12090 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12091 if (!brief && !oomOnly) { 12092 PrintWriter out = categoryPw != null ? categoryPw : pw; 12093 if (!isCompact) { 12094 out.println(); 12095 out.println("Total PSS by category:"); 12096 } 12097 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12098 } 12099 if (!isCompact) { 12100 pw.println(); 12101 } 12102 MemInfoReader memInfo = new MemInfoReader(); 12103 memInfo.readMemInfo(); 12104 if (!brief) { 12105 if (!isCompact) { 12106 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12107 pw.println(" kB"); 12108 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12109 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12110 pw.print(cachedPss); pw.print(" cached pss + "); 12111 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12112 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12113 } else { 12114 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12115 pw.print(cachedPss + memInfo.getCachedSizeKb() 12116 + memInfo.getFreeSizeKb()); pw.print(","); 12117 pw.println(totalPss - cachedPss); 12118 } 12119 } 12120 if (!isCompact) { 12121 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12122 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12123 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12124 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12125 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12126 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12127 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12128 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12129 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12130 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12131 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12132 } 12133 if (!brief) { 12134 if (memInfo.getZramTotalSizeKb() != 0) { 12135 if (!isCompact) { 12136 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12137 pw.print(" kB physical used for "); 12138 pw.print(memInfo.getSwapTotalSizeKb() 12139 - memInfo.getSwapFreeSizeKb()); 12140 pw.print(" kB in swap ("); 12141 pw.print(memInfo.getSwapTotalSizeKb()); 12142 pw.println(" kB total swap)"); 12143 } else { 12144 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12145 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12146 pw.println(memInfo.getSwapFreeSizeKb()); 12147 } 12148 } 12149 final int[] SINGLE_LONG_FORMAT = new int[] { 12150 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12151 }; 12152 long[] longOut = new long[1]; 12153 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12154 SINGLE_LONG_FORMAT, null, longOut, null); 12155 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12156 longOut[0] = 0; 12157 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12158 SINGLE_LONG_FORMAT, null, longOut, null); 12159 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12160 longOut[0] = 0; 12161 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12162 SINGLE_LONG_FORMAT, null, longOut, null); 12163 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12164 longOut[0] = 0; 12165 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12166 SINGLE_LONG_FORMAT, null, longOut, null); 12167 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12168 if (!isCompact) { 12169 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12170 pw.print(" KSM: "); pw.print(sharing); 12171 pw.print(" kB saved from shared "); 12172 pw.print(shared); pw.println(" kB"); 12173 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12174 pw.print(voltile); pw.println(" kB volatile"); 12175 } 12176 pw.print(" Tuning: "); 12177 pw.print(ActivityManager.staticGetMemoryClass()); 12178 pw.print(" (large "); 12179 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12180 pw.print("), oom "); 12181 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12182 pw.print(" kB"); 12183 pw.print(", restore limit "); 12184 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12185 pw.print(" kB"); 12186 if (ActivityManager.isLowRamDeviceStatic()) { 12187 pw.print(" (low-ram)"); 12188 } 12189 if (ActivityManager.isHighEndGfx()) { 12190 pw.print(" (high-end-gfx)"); 12191 } 12192 pw.println(); 12193 } else { 12194 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12195 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12196 pw.println(voltile); 12197 pw.print("tuning,"); 12198 pw.print(ActivityManager.staticGetMemoryClass()); 12199 pw.print(','); 12200 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12201 pw.print(','); 12202 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12203 if (ActivityManager.isLowRamDeviceStatic()) { 12204 pw.print(",low-ram"); 12205 } 12206 if (ActivityManager.isHighEndGfx()) { 12207 pw.print(",high-end-gfx"); 12208 } 12209 pw.println(); 12210 } 12211 } 12212 } 12213 } 12214 12215 /** 12216 * Searches array of arguments for the specified string 12217 * @param args array of argument strings 12218 * @param value value to search for 12219 * @return true if the value is contained in the array 12220 */ 12221 private static boolean scanArgs(String[] args, String value) { 12222 if (args != null) { 12223 for (String arg : args) { 12224 if (value.equals(arg)) { 12225 return true; 12226 } 12227 } 12228 } 12229 return false; 12230 } 12231 12232 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12233 ContentProviderRecord cpr, boolean always) { 12234 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12235 12236 if (!inLaunching || always) { 12237 synchronized (cpr) { 12238 cpr.launchingApp = null; 12239 cpr.notifyAll(); 12240 } 12241 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12242 String names[] = cpr.info.authority.split(";"); 12243 for (int j = 0; j < names.length; j++) { 12244 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12245 } 12246 } 12247 12248 for (int i=0; i<cpr.connections.size(); i++) { 12249 ContentProviderConnection conn = cpr.connections.get(i); 12250 if (conn.waiting) { 12251 // If this connection is waiting for the provider, then we don't 12252 // need to mess with its process unless we are always removing 12253 // or for some reason the provider is not currently launching. 12254 if (inLaunching && !always) { 12255 continue; 12256 } 12257 } 12258 ProcessRecord capp = conn.client; 12259 conn.dead = true; 12260 if (conn.stableCount > 0) { 12261 if (!capp.persistent && capp.thread != null 12262 && capp.pid != 0 12263 && capp.pid != MY_PID) { 12264 killUnneededProcessLocked(capp, "depends on provider " 12265 + cpr.name.flattenToShortString() 12266 + " in dying proc " + (proc != null ? proc.processName : "??")); 12267 } 12268 } else if (capp.thread != null && conn.provider.provider != null) { 12269 try { 12270 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12271 } catch (RemoteException e) { 12272 } 12273 // In the protocol here, we don't expect the client to correctly 12274 // clean up this connection, we'll just remove it. 12275 cpr.connections.remove(i); 12276 conn.client.conProviders.remove(conn); 12277 } 12278 } 12279 12280 if (inLaunching && always) { 12281 mLaunchingProviders.remove(cpr); 12282 } 12283 return inLaunching; 12284 } 12285 12286 /** 12287 * Main code for cleaning up a process when it has gone away. This is 12288 * called both as a result of the process dying, or directly when stopping 12289 * a process when running in single process mode. 12290 */ 12291 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12292 boolean restarting, boolean allowRestart, int index) { 12293 if (index >= 0) { 12294 removeLruProcessLocked(app); 12295 ProcessList.remove(app.pid); 12296 } 12297 12298 mProcessesToGc.remove(app); 12299 mPendingPssProcesses.remove(app); 12300 12301 // Dismiss any open dialogs. 12302 if (app.crashDialog != null && !app.forceCrashReport) { 12303 app.crashDialog.dismiss(); 12304 app.crashDialog = null; 12305 } 12306 if (app.anrDialog != null) { 12307 app.anrDialog.dismiss(); 12308 app.anrDialog = null; 12309 } 12310 if (app.waitDialog != null) { 12311 app.waitDialog.dismiss(); 12312 app.waitDialog = null; 12313 } 12314 12315 app.crashing = false; 12316 app.notResponding = false; 12317 12318 app.resetPackageList(mProcessStats); 12319 app.unlinkDeathRecipient(); 12320 app.makeInactive(mProcessStats); 12321 app.forcingToForeground = null; 12322 app.foregroundServices = false; 12323 app.foregroundActivities = false; 12324 app.hasShownUi = false; 12325 app.hasAboveClient = false; 12326 12327 mServices.killServicesLocked(app, allowRestart); 12328 12329 boolean restart = false; 12330 12331 // Remove published content providers. 12332 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12333 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12334 final boolean always = app.bad || !allowRestart; 12335 if (removeDyingProviderLocked(app, cpr, always) || always) { 12336 // We left the provider in the launching list, need to 12337 // restart it. 12338 restart = true; 12339 } 12340 12341 cpr.provider = null; 12342 cpr.proc = null; 12343 } 12344 app.pubProviders.clear(); 12345 12346 // Take care of any launching providers waiting for this process. 12347 if (checkAppInLaunchingProvidersLocked(app, false)) { 12348 restart = true; 12349 } 12350 12351 // Unregister from connected content providers. 12352 if (!app.conProviders.isEmpty()) { 12353 for (int i=0; i<app.conProviders.size(); i++) { 12354 ContentProviderConnection conn = app.conProviders.get(i); 12355 conn.provider.connections.remove(conn); 12356 } 12357 app.conProviders.clear(); 12358 } 12359 12360 // At this point there may be remaining entries in mLaunchingProviders 12361 // where we were the only one waiting, so they are no longer of use. 12362 // Look for these and clean up if found. 12363 // XXX Commented out for now. Trying to figure out a way to reproduce 12364 // the actual situation to identify what is actually going on. 12365 if (false) { 12366 for (int i=0; i<mLaunchingProviders.size(); i++) { 12367 ContentProviderRecord cpr = (ContentProviderRecord) 12368 mLaunchingProviders.get(i); 12369 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12370 synchronized (cpr) { 12371 cpr.launchingApp = null; 12372 cpr.notifyAll(); 12373 } 12374 } 12375 } 12376 } 12377 12378 skipCurrentReceiverLocked(app); 12379 12380 // Unregister any receivers. 12381 for (int i=app.receivers.size()-1; i>=0; i--) { 12382 removeReceiverLocked(app.receivers.valueAt(i)); 12383 } 12384 app.receivers.clear(); 12385 12386 // If the app is undergoing backup, tell the backup manager about it 12387 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12388 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12389 + mBackupTarget.appInfo + " died during backup"); 12390 try { 12391 IBackupManager bm = IBackupManager.Stub.asInterface( 12392 ServiceManager.getService(Context.BACKUP_SERVICE)); 12393 bm.agentDisconnected(app.info.packageName); 12394 } catch (RemoteException e) { 12395 // can't happen; backup manager is local 12396 } 12397 } 12398 12399 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12400 ProcessChangeItem item = mPendingProcessChanges.get(i); 12401 if (item.pid == app.pid) { 12402 mPendingProcessChanges.remove(i); 12403 mAvailProcessChanges.add(item); 12404 } 12405 } 12406 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12407 12408 // If the caller is restarting this app, then leave it in its 12409 // current lists and let the caller take care of it. 12410 if (restarting) { 12411 return; 12412 } 12413 12414 if (!app.persistent || app.isolated) { 12415 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12416 "Removing non-persistent process during cleanup: " + app); 12417 mProcessNames.remove(app.processName, app.uid); 12418 mIsolatedProcesses.remove(app.uid); 12419 if (mHeavyWeightProcess == app) { 12420 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12421 mHeavyWeightProcess.userId, 0)); 12422 mHeavyWeightProcess = null; 12423 } 12424 } else if (!app.removed) { 12425 // This app is persistent, so we need to keep its record around. 12426 // If it is not already on the pending app list, add it there 12427 // and start a new process for it. 12428 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12429 mPersistentStartingProcesses.add(app); 12430 restart = true; 12431 } 12432 } 12433 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12434 "Clean-up removing on hold: " + app); 12435 mProcessesOnHold.remove(app); 12436 12437 if (app == mHomeProcess) { 12438 mHomeProcess = null; 12439 } 12440 if (app == mPreviousProcess) { 12441 mPreviousProcess = null; 12442 } 12443 12444 if (restart && !app.isolated) { 12445 // We have components that still need to be running in the 12446 // process, so re-launch it. 12447 mProcessNames.put(app.processName, app.uid, app); 12448 startProcessLocked(app, "restart", app.processName); 12449 } else if (app.pid > 0 && app.pid != MY_PID) { 12450 // Goodbye! 12451 synchronized (mPidsSelfLocked) { 12452 mPidsSelfLocked.remove(app.pid); 12453 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12454 } 12455 app.setPid(0); 12456 } 12457 } 12458 12459 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12460 // Look through the content providers we are waiting to have launched, 12461 // and if any run in this process then either schedule a restart of 12462 // the process or kill the client waiting for it if this process has 12463 // gone bad. 12464 int NL = mLaunchingProviders.size(); 12465 boolean restart = false; 12466 for (int i=0; i<NL; i++) { 12467 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12468 if (cpr.launchingApp == app) { 12469 if (!alwaysBad && !app.bad) { 12470 restart = true; 12471 } else { 12472 removeDyingProviderLocked(app, cpr, true); 12473 // cpr should have been removed from mLaunchingProviders 12474 NL = mLaunchingProviders.size(); 12475 i--; 12476 } 12477 } 12478 } 12479 return restart; 12480 } 12481 12482 // ========================================================= 12483 // SERVICES 12484 // ========================================================= 12485 12486 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12487 int flags) { 12488 enforceNotIsolatedCaller("getServices"); 12489 synchronized (this) { 12490 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12491 } 12492 } 12493 12494 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12495 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12496 synchronized (this) { 12497 return mServices.getRunningServiceControlPanelLocked(name); 12498 } 12499 } 12500 12501 public ComponentName startService(IApplicationThread caller, Intent service, 12502 String resolvedType, int userId) { 12503 enforceNotIsolatedCaller("startService"); 12504 // Refuse possible leaked file descriptors 12505 if (service != null && service.hasFileDescriptors() == true) { 12506 throw new IllegalArgumentException("File descriptors passed in Intent"); 12507 } 12508 12509 if (DEBUG_SERVICE) 12510 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12511 synchronized(this) { 12512 final int callingPid = Binder.getCallingPid(); 12513 final int callingUid = Binder.getCallingUid(); 12514 final long origId = Binder.clearCallingIdentity(); 12515 ComponentName res = mServices.startServiceLocked(caller, service, 12516 resolvedType, callingPid, callingUid, userId); 12517 Binder.restoreCallingIdentity(origId); 12518 return res; 12519 } 12520 } 12521 12522 ComponentName startServiceInPackage(int uid, 12523 Intent service, String resolvedType, int userId) { 12524 synchronized(this) { 12525 if (DEBUG_SERVICE) 12526 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12527 final long origId = Binder.clearCallingIdentity(); 12528 ComponentName res = mServices.startServiceLocked(null, service, 12529 resolvedType, -1, uid, userId); 12530 Binder.restoreCallingIdentity(origId); 12531 return res; 12532 } 12533 } 12534 12535 public int stopService(IApplicationThread caller, Intent service, 12536 String resolvedType, int userId) { 12537 enforceNotIsolatedCaller("stopService"); 12538 // Refuse possible leaked file descriptors 12539 if (service != null && service.hasFileDescriptors() == true) { 12540 throw new IllegalArgumentException("File descriptors passed in Intent"); 12541 } 12542 12543 synchronized(this) { 12544 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12545 } 12546 } 12547 12548 public IBinder peekService(Intent service, String resolvedType) { 12549 enforceNotIsolatedCaller("peekService"); 12550 // Refuse possible leaked file descriptors 12551 if (service != null && service.hasFileDescriptors() == true) { 12552 throw new IllegalArgumentException("File descriptors passed in Intent"); 12553 } 12554 synchronized(this) { 12555 return mServices.peekServiceLocked(service, resolvedType); 12556 } 12557 } 12558 12559 public boolean stopServiceToken(ComponentName className, IBinder token, 12560 int startId) { 12561 synchronized(this) { 12562 return mServices.stopServiceTokenLocked(className, token, startId); 12563 } 12564 } 12565 12566 public void setServiceForeground(ComponentName className, IBinder token, 12567 int id, Notification notification, boolean removeNotification) { 12568 synchronized(this) { 12569 mServices.setServiceForegroundLocked(className, token, id, notification, 12570 removeNotification); 12571 } 12572 } 12573 12574 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12575 boolean requireFull, String name, String callerPackage) { 12576 final int callingUserId = UserHandle.getUserId(callingUid); 12577 if (callingUserId != userId) { 12578 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12579 if ((requireFull || checkComponentPermission( 12580 android.Manifest.permission.INTERACT_ACROSS_USERS, 12581 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12582 && checkComponentPermission( 12583 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12584 callingPid, callingUid, -1, true) 12585 != PackageManager.PERMISSION_GRANTED) { 12586 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12587 // In this case, they would like to just execute as their 12588 // owner user instead of failing. 12589 userId = callingUserId; 12590 } else { 12591 StringBuilder builder = new StringBuilder(128); 12592 builder.append("Permission Denial: "); 12593 builder.append(name); 12594 if (callerPackage != null) { 12595 builder.append(" from "); 12596 builder.append(callerPackage); 12597 } 12598 builder.append(" asks to run as user "); 12599 builder.append(userId); 12600 builder.append(" but is calling from user "); 12601 builder.append(UserHandle.getUserId(callingUid)); 12602 builder.append("; this requires "); 12603 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12604 if (!requireFull) { 12605 builder.append(" or "); 12606 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12607 } 12608 String msg = builder.toString(); 12609 Slog.w(TAG, msg); 12610 throw new SecurityException(msg); 12611 } 12612 } 12613 } 12614 if (userId == UserHandle.USER_CURRENT 12615 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12616 // Note that we may be accessing this outside of a lock... 12617 // shouldn't be a big deal, if this is being called outside 12618 // of a locked context there is intrinsically a race with 12619 // the value the caller will receive and someone else changing it. 12620 userId = mCurrentUserId; 12621 } 12622 if (!allowAll && userId < 0) { 12623 throw new IllegalArgumentException( 12624 "Call does not support special user #" + userId); 12625 } 12626 } 12627 return userId; 12628 } 12629 12630 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12631 String className, int flags) { 12632 boolean result = false; 12633 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12634 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12635 if (ActivityManager.checkUidPermission( 12636 android.Manifest.permission.INTERACT_ACROSS_USERS, 12637 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12638 ComponentName comp = new ComponentName(aInfo.packageName, className); 12639 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12640 + " requests FLAG_SINGLE_USER, but app does not hold " 12641 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12642 Slog.w(TAG, msg); 12643 throw new SecurityException(msg); 12644 } 12645 result = true; 12646 } 12647 } else if (componentProcessName == aInfo.packageName) { 12648 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12649 } else if ("system".equals(componentProcessName)) { 12650 result = true; 12651 } 12652 if (DEBUG_MU) { 12653 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12654 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12655 } 12656 return result; 12657 } 12658 12659 public int bindService(IApplicationThread caller, IBinder token, 12660 Intent service, String resolvedType, 12661 IServiceConnection connection, int flags, int userId) { 12662 enforceNotIsolatedCaller("bindService"); 12663 // Refuse possible leaked file descriptors 12664 if (service != null && service.hasFileDescriptors() == true) { 12665 throw new IllegalArgumentException("File descriptors passed in Intent"); 12666 } 12667 12668 synchronized(this) { 12669 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12670 connection, flags, userId); 12671 } 12672 } 12673 12674 public boolean unbindService(IServiceConnection connection) { 12675 synchronized (this) { 12676 return mServices.unbindServiceLocked(connection); 12677 } 12678 } 12679 12680 public void publishService(IBinder token, Intent intent, IBinder service) { 12681 // Refuse possible leaked file descriptors 12682 if (intent != null && intent.hasFileDescriptors() == true) { 12683 throw new IllegalArgumentException("File descriptors passed in Intent"); 12684 } 12685 12686 synchronized(this) { 12687 if (!(token instanceof ServiceRecord)) { 12688 throw new IllegalArgumentException("Invalid service token"); 12689 } 12690 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12691 } 12692 } 12693 12694 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12695 // Refuse possible leaked file descriptors 12696 if (intent != null && intent.hasFileDescriptors() == true) { 12697 throw new IllegalArgumentException("File descriptors passed in Intent"); 12698 } 12699 12700 synchronized(this) { 12701 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12702 } 12703 } 12704 12705 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12706 synchronized(this) { 12707 if (!(token instanceof ServiceRecord)) { 12708 throw new IllegalArgumentException("Invalid service token"); 12709 } 12710 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12711 } 12712 } 12713 12714 // ========================================================= 12715 // BACKUP AND RESTORE 12716 // ========================================================= 12717 12718 // Cause the target app to be launched if necessary and its backup agent 12719 // instantiated. The backup agent will invoke backupAgentCreated() on the 12720 // activity manager to announce its creation. 12721 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12722 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12723 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12724 12725 synchronized(this) { 12726 // !!! TODO: currently no check here that we're already bound 12727 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12728 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12729 synchronized (stats) { 12730 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12731 } 12732 12733 // Backup agent is now in use, its package can't be stopped. 12734 try { 12735 AppGlobals.getPackageManager().setPackageStoppedState( 12736 app.packageName, false, UserHandle.getUserId(app.uid)); 12737 } catch (RemoteException e) { 12738 } catch (IllegalArgumentException e) { 12739 Slog.w(TAG, "Failed trying to unstop package " 12740 + app.packageName + ": " + e); 12741 } 12742 12743 BackupRecord r = new BackupRecord(ss, app, backupMode); 12744 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12745 ? new ComponentName(app.packageName, app.backupAgentName) 12746 : new ComponentName("android", "FullBackupAgent"); 12747 // startProcessLocked() returns existing proc's record if it's already running 12748 ProcessRecord proc = startProcessLocked(app.processName, app, 12749 false, 0, "backup", hostingName, false, false, false); 12750 if (proc == null) { 12751 Slog.e(TAG, "Unable to start backup agent process " + r); 12752 return false; 12753 } 12754 12755 r.app = proc; 12756 mBackupTarget = r; 12757 mBackupAppName = app.packageName; 12758 12759 // Try not to kill the process during backup 12760 updateOomAdjLocked(proc); 12761 12762 // If the process is already attached, schedule the creation of the backup agent now. 12763 // If it is not yet live, this will be done when it attaches to the framework. 12764 if (proc.thread != null) { 12765 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12766 try { 12767 proc.thread.scheduleCreateBackupAgent(app, 12768 compatibilityInfoForPackageLocked(app), backupMode); 12769 } catch (RemoteException e) { 12770 // Will time out on the backup manager side 12771 } 12772 } else { 12773 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12774 } 12775 // Invariants: at this point, the target app process exists and the application 12776 // is either already running or in the process of coming up. mBackupTarget and 12777 // mBackupAppName describe the app, so that when it binds back to the AM we 12778 // know that it's scheduled for a backup-agent operation. 12779 } 12780 12781 return true; 12782 } 12783 12784 @Override 12785 public void clearPendingBackup() { 12786 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 12787 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 12788 12789 synchronized (this) { 12790 mBackupTarget = null; 12791 mBackupAppName = null; 12792 } 12793 } 12794 12795 // A backup agent has just come up 12796 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12797 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12798 + " = " + agent); 12799 12800 synchronized(this) { 12801 if (!agentPackageName.equals(mBackupAppName)) { 12802 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12803 return; 12804 } 12805 } 12806 12807 long oldIdent = Binder.clearCallingIdentity(); 12808 try { 12809 IBackupManager bm = IBackupManager.Stub.asInterface( 12810 ServiceManager.getService(Context.BACKUP_SERVICE)); 12811 bm.agentConnected(agentPackageName, agent); 12812 } catch (RemoteException e) { 12813 // can't happen; the backup manager service is local 12814 } catch (Exception e) { 12815 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12816 e.printStackTrace(); 12817 } finally { 12818 Binder.restoreCallingIdentity(oldIdent); 12819 } 12820 } 12821 12822 // done with this agent 12823 public void unbindBackupAgent(ApplicationInfo appInfo) { 12824 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12825 if (appInfo == null) { 12826 Slog.w(TAG, "unbind backup agent for null app"); 12827 return; 12828 } 12829 12830 synchronized(this) { 12831 try { 12832 if (mBackupAppName == null) { 12833 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12834 return; 12835 } 12836 12837 if (!mBackupAppName.equals(appInfo.packageName)) { 12838 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12839 return; 12840 } 12841 12842 // Not backing this app up any more; reset its OOM adjustment 12843 final ProcessRecord proc = mBackupTarget.app; 12844 updateOomAdjLocked(proc); 12845 12846 // If the app crashed during backup, 'thread' will be null here 12847 if (proc.thread != null) { 12848 try { 12849 proc.thread.scheduleDestroyBackupAgent(appInfo, 12850 compatibilityInfoForPackageLocked(appInfo)); 12851 } catch (Exception e) { 12852 Slog.e(TAG, "Exception when unbinding backup agent:"); 12853 e.printStackTrace(); 12854 } 12855 } 12856 } finally { 12857 mBackupTarget = null; 12858 mBackupAppName = null; 12859 } 12860 } 12861 } 12862 // ========================================================= 12863 // BROADCASTS 12864 // ========================================================= 12865 12866 private final List getStickiesLocked(String action, IntentFilter filter, 12867 List cur, int userId) { 12868 final ContentResolver resolver = mContext.getContentResolver(); 12869 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12870 if (stickies == null) { 12871 return cur; 12872 } 12873 final ArrayList<Intent> list = stickies.get(action); 12874 if (list == null) { 12875 return cur; 12876 } 12877 int N = list.size(); 12878 for (int i=0; i<N; i++) { 12879 Intent intent = list.get(i); 12880 if (filter.match(resolver, intent, true, TAG) >= 0) { 12881 if (cur == null) { 12882 cur = new ArrayList<Intent>(); 12883 } 12884 cur.add(intent); 12885 } 12886 } 12887 return cur; 12888 } 12889 12890 boolean isPendingBroadcastProcessLocked(int pid) { 12891 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12892 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12893 } 12894 12895 void skipPendingBroadcastLocked(int pid) { 12896 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 12897 for (BroadcastQueue queue : mBroadcastQueues) { 12898 queue.skipPendingBroadcastLocked(pid); 12899 } 12900 } 12901 12902 // The app just attached; send any pending broadcasts that it should receive 12903 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 12904 boolean didSomething = false; 12905 for (BroadcastQueue queue : mBroadcastQueues) { 12906 didSomething |= queue.sendPendingBroadcastsLocked(app); 12907 } 12908 return didSomething; 12909 } 12910 12911 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 12912 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 12913 enforceNotIsolatedCaller("registerReceiver"); 12914 int callingUid; 12915 int callingPid; 12916 synchronized(this) { 12917 ProcessRecord callerApp = null; 12918 if (caller != null) { 12919 callerApp = getRecordForAppLocked(caller); 12920 if (callerApp == null) { 12921 throw new SecurityException( 12922 "Unable to find app for caller " + caller 12923 + " (pid=" + Binder.getCallingPid() 12924 + ") when registering receiver " + receiver); 12925 } 12926 if (callerApp.info.uid != Process.SYSTEM_UID && 12927 !callerApp.pkgList.containsKey(callerPackage) && 12928 !"android".equals(callerPackage)) { 12929 throw new SecurityException("Given caller package " + callerPackage 12930 + " is not running in process " + callerApp); 12931 } 12932 callingUid = callerApp.info.uid; 12933 callingPid = callerApp.pid; 12934 } else { 12935 callerPackage = null; 12936 callingUid = Binder.getCallingUid(); 12937 callingPid = Binder.getCallingPid(); 12938 } 12939 12940 userId = this.handleIncomingUser(callingPid, callingUid, userId, 12941 true, true, "registerReceiver", callerPackage); 12942 12943 List allSticky = null; 12944 12945 // Look for any matching sticky broadcasts... 12946 Iterator actions = filter.actionsIterator(); 12947 if (actions != null) { 12948 while (actions.hasNext()) { 12949 String action = (String)actions.next(); 12950 allSticky = getStickiesLocked(action, filter, allSticky, 12951 UserHandle.USER_ALL); 12952 allSticky = getStickiesLocked(action, filter, allSticky, 12953 UserHandle.getUserId(callingUid)); 12954 } 12955 } else { 12956 allSticky = getStickiesLocked(null, filter, allSticky, 12957 UserHandle.USER_ALL); 12958 allSticky = getStickiesLocked(null, filter, allSticky, 12959 UserHandle.getUserId(callingUid)); 12960 } 12961 12962 // The first sticky in the list is returned directly back to 12963 // the client. 12964 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 12965 12966 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 12967 + ": " + sticky); 12968 12969 if (receiver == null) { 12970 return sticky; 12971 } 12972 12973 ReceiverList rl 12974 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12975 if (rl == null) { 12976 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 12977 userId, receiver); 12978 if (rl.app != null) { 12979 rl.app.receivers.add(rl); 12980 } else { 12981 try { 12982 receiver.asBinder().linkToDeath(rl, 0); 12983 } catch (RemoteException e) { 12984 return sticky; 12985 } 12986 rl.linkedToDeath = true; 12987 } 12988 mRegisteredReceivers.put(receiver.asBinder(), rl); 12989 } else if (rl.uid != callingUid) { 12990 throw new IllegalArgumentException( 12991 "Receiver requested to register for uid " + callingUid 12992 + " was previously registered for uid " + rl.uid); 12993 } else if (rl.pid != callingPid) { 12994 throw new IllegalArgumentException( 12995 "Receiver requested to register for pid " + callingPid 12996 + " was previously registered for pid " + rl.pid); 12997 } else if (rl.userId != userId) { 12998 throw new IllegalArgumentException( 12999 "Receiver requested to register for user " + userId 13000 + " was previously registered for user " + rl.userId); 13001 } 13002 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13003 permission, callingUid, userId); 13004 rl.add(bf); 13005 if (!bf.debugCheck()) { 13006 Slog.w(TAG, "==> For Dynamic broadast"); 13007 } 13008 mReceiverResolver.addFilter(bf); 13009 13010 // Enqueue broadcasts for all existing stickies that match 13011 // this filter. 13012 if (allSticky != null) { 13013 ArrayList receivers = new ArrayList(); 13014 receivers.add(bf); 13015 13016 int N = allSticky.size(); 13017 for (int i=0; i<N; i++) { 13018 Intent intent = (Intent)allSticky.get(i); 13019 BroadcastQueue queue = broadcastQueueForIntent(intent); 13020 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13021 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13022 null, null, false, true, true, -1); 13023 queue.enqueueParallelBroadcastLocked(r); 13024 queue.scheduleBroadcastsLocked(); 13025 } 13026 } 13027 13028 return sticky; 13029 } 13030 } 13031 13032 public void unregisterReceiver(IIntentReceiver receiver) { 13033 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13034 13035 final long origId = Binder.clearCallingIdentity(); 13036 try { 13037 boolean doTrim = false; 13038 13039 synchronized(this) { 13040 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13041 if (rl != null) { 13042 if (rl.curBroadcast != null) { 13043 BroadcastRecord r = rl.curBroadcast; 13044 final boolean doNext = finishReceiverLocked( 13045 receiver.asBinder(), r.resultCode, r.resultData, 13046 r.resultExtras, r.resultAbort); 13047 if (doNext) { 13048 doTrim = true; 13049 r.queue.processNextBroadcast(false); 13050 } 13051 } 13052 13053 if (rl.app != null) { 13054 rl.app.receivers.remove(rl); 13055 } 13056 removeReceiverLocked(rl); 13057 if (rl.linkedToDeath) { 13058 rl.linkedToDeath = false; 13059 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13060 } 13061 } 13062 } 13063 13064 // If we actually concluded any broadcasts, we might now be able 13065 // to trim the recipients' apps from our working set 13066 if (doTrim) { 13067 trimApplications(); 13068 return; 13069 } 13070 13071 } finally { 13072 Binder.restoreCallingIdentity(origId); 13073 } 13074 } 13075 13076 void removeReceiverLocked(ReceiverList rl) { 13077 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13078 int N = rl.size(); 13079 for (int i=0; i<N; i++) { 13080 mReceiverResolver.removeFilter(rl.get(i)); 13081 } 13082 } 13083 13084 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13085 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13086 ProcessRecord r = mLruProcesses.get(i); 13087 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13088 try { 13089 r.thread.dispatchPackageBroadcast(cmd, packages); 13090 } catch (RemoteException ex) { 13091 } 13092 } 13093 } 13094 } 13095 13096 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13097 int[] users) { 13098 List<ResolveInfo> receivers = null; 13099 try { 13100 HashSet<ComponentName> singleUserReceivers = null; 13101 boolean scannedFirstReceivers = false; 13102 for (int user : users) { 13103 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13104 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13105 if (user != 0 && newReceivers != null) { 13106 // If this is not the primary user, we need to check for 13107 // any receivers that should be filtered out. 13108 for (int i=0; i<newReceivers.size(); i++) { 13109 ResolveInfo ri = newReceivers.get(i); 13110 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13111 newReceivers.remove(i); 13112 i--; 13113 } 13114 } 13115 } 13116 if (newReceivers != null && newReceivers.size() == 0) { 13117 newReceivers = null; 13118 } 13119 if (receivers == null) { 13120 receivers = newReceivers; 13121 } else if (newReceivers != null) { 13122 // We need to concatenate the additional receivers 13123 // found with what we have do far. This would be easy, 13124 // but we also need to de-dup any receivers that are 13125 // singleUser. 13126 if (!scannedFirstReceivers) { 13127 // Collect any single user receivers we had already retrieved. 13128 scannedFirstReceivers = true; 13129 for (int i=0; i<receivers.size(); i++) { 13130 ResolveInfo ri = receivers.get(i); 13131 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13132 ComponentName cn = new ComponentName( 13133 ri.activityInfo.packageName, ri.activityInfo.name); 13134 if (singleUserReceivers == null) { 13135 singleUserReceivers = new HashSet<ComponentName>(); 13136 } 13137 singleUserReceivers.add(cn); 13138 } 13139 } 13140 } 13141 // Add the new results to the existing results, tracking 13142 // and de-dupping single user receivers. 13143 for (int i=0; i<newReceivers.size(); i++) { 13144 ResolveInfo ri = newReceivers.get(i); 13145 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13146 ComponentName cn = new ComponentName( 13147 ri.activityInfo.packageName, ri.activityInfo.name); 13148 if (singleUserReceivers == null) { 13149 singleUserReceivers = new HashSet<ComponentName>(); 13150 } 13151 if (!singleUserReceivers.contains(cn)) { 13152 singleUserReceivers.add(cn); 13153 receivers.add(ri); 13154 } 13155 } else { 13156 receivers.add(ri); 13157 } 13158 } 13159 } 13160 } 13161 } catch (RemoteException ex) { 13162 // pm is in same process, this will never happen. 13163 } 13164 return receivers; 13165 } 13166 13167 private final int broadcastIntentLocked(ProcessRecord callerApp, 13168 String callerPackage, Intent intent, String resolvedType, 13169 IIntentReceiver resultTo, int resultCode, String resultData, 13170 Bundle map, String requiredPermission, int appOp, 13171 boolean ordered, boolean sticky, int callingPid, int callingUid, 13172 int userId) { 13173 intent = new Intent(intent); 13174 13175 // By default broadcasts do not go to stopped apps. 13176 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13177 13178 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13179 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13180 + " ordered=" + ordered + " userid=" + userId); 13181 if ((resultTo != null) && !ordered) { 13182 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13183 } 13184 13185 userId = handleIncomingUser(callingPid, callingUid, userId, 13186 true, false, "broadcast", callerPackage); 13187 13188 // Make sure that the user who is receiving this broadcast is started. 13189 // If not, we will just skip it. 13190 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13191 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13192 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13193 Slog.w(TAG, "Skipping broadcast of " + intent 13194 + ": user " + userId + " is stopped"); 13195 return ActivityManager.BROADCAST_SUCCESS; 13196 } 13197 } 13198 13199 /* 13200 * Prevent non-system code (defined here to be non-persistent 13201 * processes) from sending protected broadcasts. 13202 */ 13203 int callingAppId = UserHandle.getAppId(callingUid); 13204 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13205 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13206 callingUid == 0) { 13207 // Always okay. 13208 } else if (callerApp == null || !callerApp.persistent) { 13209 try { 13210 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13211 intent.getAction())) { 13212 String msg = "Permission Denial: not allowed to send broadcast " 13213 + intent.getAction() + " from pid=" 13214 + callingPid + ", uid=" + callingUid; 13215 Slog.w(TAG, msg); 13216 throw new SecurityException(msg); 13217 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13218 // Special case for compatibility: we don't want apps to send this, 13219 // but historically it has not been protected and apps may be using it 13220 // to poke their own app widget. So, instead of making it protected, 13221 // just limit it to the caller. 13222 if (callerApp == null) { 13223 String msg = "Permission Denial: not allowed to send broadcast " 13224 + intent.getAction() + " from unknown caller."; 13225 Slog.w(TAG, msg); 13226 throw new SecurityException(msg); 13227 } else if (intent.getComponent() != null) { 13228 // They are good enough to send to an explicit component... verify 13229 // it is being sent to the calling app. 13230 if (!intent.getComponent().getPackageName().equals( 13231 callerApp.info.packageName)) { 13232 String msg = "Permission Denial: not allowed to send broadcast " 13233 + intent.getAction() + " to " 13234 + intent.getComponent().getPackageName() + " from " 13235 + callerApp.info.packageName; 13236 Slog.w(TAG, msg); 13237 throw new SecurityException(msg); 13238 } 13239 } else { 13240 // Limit broadcast to their own package. 13241 intent.setPackage(callerApp.info.packageName); 13242 } 13243 } 13244 } catch (RemoteException e) { 13245 Slog.w(TAG, "Remote exception", e); 13246 return ActivityManager.BROADCAST_SUCCESS; 13247 } 13248 } 13249 13250 // Handle special intents: if this broadcast is from the package 13251 // manager about a package being removed, we need to remove all of 13252 // its activities from the history stack. 13253 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13254 intent.getAction()); 13255 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13256 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13257 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13258 || uidRemoved) { 13259 if (checkComponentPermission( 13260 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13261 callingPid, callingUid, -1, true) 13262 == PackageManager.PERMISSION_GRANTED) { 13263 if (uidRemoved) { 13264 final Bundle intentExtras = intent.getExtras(); 13265 final int uid = intentExtras != null 13266 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13267 if (uid >= 0) { 13268 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13269 synchronized (bs) { 13270 bs.removeUidStatsLocked(uid); 13271 } 13272 mAppOpsService.uidRemoved(uid); 13273 } 13274 } else { 13275 // If resources are unavailable just force stop all 13276 // those packages and flush the attribute cache as well. 13277 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13278 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13279 if (list != null && (list.length > 0)) { 13280 for (String pkg : list) { 13281 forceStopPackageLocked(pkg, -1, false, true, true, false, userId, 13282 "storage unmount"); 13283 } 13284 sendPackageBroadcastLocked( 13285 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13286 } 13287 } else { 13288 Uri data = intent.getData(); 13289 String ssp; 13290 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13291 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13292 intent.getAction()); 13293 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13294 forceStopPackageLocked(ssp, UserHandle.getAppId( 13295 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13296 false, userId, removed ? "pkg removed" : "pkg changed"); 13297 } 13298 if (removed) { 13299 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13300 new String[] {ssp}, userId); 13301 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13302 mAppOpsService.packageRemoved( 13303 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13304 13305 // Remove all permissions granted from/to this package 13306 removeUriPermissionsForPackageLocked(ssp, userId, true); 13307 } 13308 } 13309 } 13310 } 13311 } 13312 } else { 13313 String msg = "Permission Denial: " + intent.getAction() 13314 + " broadcast from " + callerPackage + " (pid=" + callingPid 13315 + ", uid=" + callingUid + ")" 13316 + " requires " 13317 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13318 Slog.w(TAG, msg); 13319 throw new SecurityException(msg); 13320 } 13321 13322 // Special case for adding a package: by default turn on compatibility 13323 // mode. 13324 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13325 Uri data = intent.getData(); 13326 String ssp; 13327 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13328 mCompatModePackages.handlePackageAddedLocked(ssp, 13329 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13330 } 13331 } 13332 13333 /* 13334 * If this is the time zone changed action, queue up a message that will reset the timezone 13335 * of all currently running processes. This message will get queued up before the broadcast 13336 * happens. 13337 */ 13338 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13339 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13340 } 13341 13342 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13343 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13344 } 13345 13346 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13347 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13348 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13349 } 13350 13351 // Add to the sticky list if requested. 13352 if (sticky) { 13353 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13354 callingPid, callingUid) 13355 != PackageManager.PERMISSION_GRANTED) { 13356 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13357 + callingPid + ", uid=" + callingUid 13358 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13359 Slog.w(TAG, msg); 13360 throw new SecurityException(msg); 13361 } 13362 if (requiredPermission != null) { 13363 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13364 + " and enforce permission " + requiredPermission); 13365 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13366 } 13367 if (intent.getComponent() != null) { 13368 throw new SecurityException( 13369 "Sticky broadcasts can't target a specific component"); 13370 } 13371 // We use userId directly here, since the "all" target is maintained 13372 // as a separate set of sticky broadcasts. 13373 if (userId != UserHandle.USER_ALL) { 13374 // But first, if this is not a broadcast to all users, then 13375 // make sure it doesn't conflict with an existing broadcast to 13376 // all users. 13377 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13378 UserHandle.USER_ALL); 13379 if (stickies != null) { 13380 ArrayList<Intent> list = stickies.get(intent.getAction()); 13381 if (list != null) { 13382 int N = list.size(); 13383 int i; 13384 for (i=0; i<N; i++) { 13385 if (intent.filterEquals(list.get(i))) { 13386 throw new IllegalArgumentException( 13387 "Sticky broadcast " + intent + " for user " 13388 + userId + " conflicts with existing global broadcast"); 13389 } 13390 } 13391 } 13392 } 13393 } 13394 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13395 if (stickies == null) { 13396 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13397 mStickyBroadcasts.put(userId, stickies); 13398 } 13399 ArrayList<Intent> list = stickies.get(intent.getAction()); 13400 if (list == null) { 13401 list = new ArrayList<Intent>(); 13402 stickies.put(intent.getAction(), list); 13403 } 13404 int N = list.size(); 13405 int i; 13406 for (i=0; i<N; i++) { 13407 if (intent.filterEquals(list.get(i))) { 13408 // This sticky already exists, replace it. 13409 list.set(i, new Intent(intent)); 13410 break; 13411 } 13412 } 13413 if (i >= N) { 13414 list.add(new Intent(intent)); 13415 } 13416 } 13417 13418 int[] users; 13419 if (userId == UserHandle.USER_ALL) { 13420 // Caller wants broadcast to go to all started users. 13421 users = mStartedUserArray; 13422 } else { 13423 // Caller wants broadcast to go to one specific user. 13424 users = new int[] {userId}; 13425 } 13426 13427 // Figure out who all will receive this broadcast. 13428 List receivers = null; 13429 List<BroadcastFilter> registeredReceivers = null; 13430 // Need to resolve the intent to interested receivers... 13431 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13432 == 0) { 13433 receivers = collectReceiverComponents(intent, resolvedType, users); 13434 } 13435 if (intent.getComponent() == null) { 13436 registeredReceivers = mReceiverResolver.queryIntent(intent, 13437 resolvedType, false, userId); 13438 } 13439 13440 final boolean replacePending = 13441 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13442 13443 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13444 + " replacePending=" + replacePending); 13445 13446 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13447 if (!ordered && NR > 0) { 13448 // If we are not serializing this broadcast, then send the 13449 // registered receivers separately so they don't wait for the 13450 // components to be launched. 13451 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13452 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13453 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13454 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13455 ordered, sticky, false, userId); 13456 if (DEBUG_BROADCAST) Slog.v( 13457 TAG, "Enqueueing parallel broadcast " + r); 13458 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13459 if (!replaced) { 13460 queue.enqueueParallelBroadcastLocked(r); 13461 queue.scheduleBroadcastsLocked(); 13462 } 13463 registeredReceivers = null; 13464 NR = 0; 13465 } 13466 13467 // Merge into one list. 13468 int ir = 0; 13469 if (receivers != null) { 13470 // A special case for PACKAGE_ADDED: do not allow the package 13471 // being added to see this broadcast. This prevents them from 13472 // using this as a back door to get run as soon as they are 13473 // installed. Maybe in the future we want to have a special install 13474 // broadcast or such for apps, but we'd like to deliberately make 13475 // this decision. 13476 String skipPackages[] = null; 13477 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13478 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13479 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13480 Uri data = intent.getData(); 13481 if (data != null) { 13482 String pkgName = data.getSchemeSpecificPart(); 13483 if (pkgName != null) { 13484 skipPackages = new String[] { pkgName }; 13485 } 13486 } 13487 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13488 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13489 } 13490 if (skipPackages != null && (skipPackages.length > 0)) { 13491 for (String skipPackage : skipPackages) { 13492 if (skipPackage != null) { 13493 int NT = receivers.size(); 13494 for (int it=0; it<NT; it++) { 13495 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13496 if (curt.activityInfo.packageName.equals(skipPackage)) { 13497 receivers.remove(it); 13498 it--; 13499 NT--; 13500 } 13501 } 13502 } 13503 } 13504 } 13505 13506 int NT = receivers != null ? receivers.size() : 0; 13507 int it = 0; 13508 ResolveInfo curt = null; 13509 BroadcastFilter curr = null; 13510 while (it < NT && ir < NR) { 13511 if (curt == null) { 13512 curt = (ResolveInfo)receivers.get(it); 13513 } 13514 if (curr == null) { 13515 curr = registeredReceivers.get(ir); 13516 } 13517 if (curr.getPriority() >= curt.priority) { 13518 // Insert this broadcast record into the final list. 13519 receivers.add(it, curr); 13520 ir++; 13521 curr = null; 13522 it++; 13523 NT++; 13524 } else { 13525 // Skip to the next ResolveInfo in the final list. 13526 it++; 13527 curt = null; 13528 } 13529 } 13530 } 13531 while (ir < NR) { 13532 if (receivers == null) { 13533 receivers = new ArrayList(); 13534 } 13535 receivers.add(registeredReceivers.get(ir)); 13536 ir++; 13537 } 13538 13539 if ((receivers != null && receivers.size() > 0) 13540 || resultTo != null) { 13541 BroadcastQueue queue = broadcastQueueForIntent(intent); 13542 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13543 callerPackage, callingPid, callingUid, resolvedType, 13544 requiredPermission, appOp, receivers, resultTo, resultCode, 13545 resultData, map, ordered, sticky, false, userId); 13546 if (DEBUG_BROADCAST) Slog.v( 13547 TAG, "Enqueueing ordered broadcast " + r 13548 + ": prev had " + queue.mOrderedBroadcasts.size()); 13549 if (DEBUG_BROADCAST) { 13550 int seq = r.intent.getIntExtra("seq", -1); 13551 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13552 } 13553 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13554 if (!replaced) { 13555 queue.enqueueOrderedBroadcastLocked(r); 13556 queue.scheduleBroadcastsLocked(); 13557 } 13558 } 13559 13560 return ActivityManager.BROADCAST_SUCCESS; 13561 } 13562 13563 final Intent verifyBroadcastLocked(Intent intent) { 13564 // Refuse possible leaked file descriptors 13565 if (intent != null && intent.hasFileDescriptors() == true) { 13566 throw new IllegalArgumentException("File descriptors passed in Intent"); 13567 } 13568 13569 int flags = intent.getFlags(); 13570 13571 if (!mProcessesReady) { 13572 // if the caller really truly claims to know what they're doing, go 13573 // ahead and allow the broadcast without launching any receivers 13574 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13575 intent = new Intent(intent); 13576 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13577 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13578 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13579 + " before boot completion"); 13580 throw new IllegalStateException("Cannot broadcast before boot completed"); 13581 } 13582 } 13583 13584 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13585 throw new IllegalArgumentException( 13586 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13587 } 13588 13589 return intent; 13590 } 13591 13592 public final int broadcastIntent(IApplicationThread caller, 13593 Intent intent, String resolvedType, IIntentReceiver resultTo, 13594 int resultCode, String resultData, Bundle map, 13595 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13596 enforceNotIsolatedCaller("broadcastIntent"); 13597 synchronized(this) { 13598 intent = verifyBroadcastLocked(intent); 13599 13600 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13601 final int callingPid = Binder.getCallingPid(); 13602 final int callingUid = Binder.getCallingUid(); 13603 final long origId = Binder.clearCallingIdentity(); 13604 int res = broadcastIntentLocked(callerApp, 13605 callerApp != null ? callerApp.info.packageName : null, 13606 intent, resolvedType, resultTo, 13607 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13608 callingPid, callingUid, userId); 13609 Binder.restoreCallingIdentity(origId); 13610 return res; 13611 } 13612 } 13613 13614 int broadcastIntentInPackage(String packageName, int uid, 13615 Intent intent, String resolvedType, IIntentReceiver resultTo, 13616 int resultCode, String resultData, Bundle map, 13617 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13618 synchronized(this) { 13619 intent = verifyBroadcastLocked(intent); 13620 13621 final long origId = Binder.clearCallingIdentity(); 13622 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13623 resultTo, resultCode, resultData, map, requiredPermission, 13624 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13625 Binder.restoreCallingIdentity(origId); 13626 return res; 13627 } 13628 } 13629 13630 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13631 // Refuse possible leaked file descriptors 13632 if (intent != null && intent.hasFileDescriptors() == true) { 13633 throw new IllegalArgumentException("File descriptors passed in Intent"); 13634 } 13635 13636 userId = handleIncomingUser(Binder.getCallingPid(), 13637 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13638 13639 synchronized(this) { 13640 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13641 != PackageManager.PERMISSION_GRANTED) { 13642 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13643 + Binder.getCallingPid() 13644 + ", uid=" + Binder.getCallingUid() 13645 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13646 Slog.w(TAG, msg); 13647 throw new SecurityException(msg); 13648 } 13649 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13650 if (stickies != null) { 13651 ArrayList<Intent> list = stickies.get(intent.getAction()); 13652 if (list != null) { 13653 int N = list.size(); 13654 int i; 13655 for (i=0; i<N; i++) { 13656 if (intent.filterEquals(list.get(i))) { 13657 list.remove(i); 13658 break; 13659 } 13660 } 13661 if (list.size() <= 0) { 13662 stickies.remove(intent.getAction()); 13663 } 13664 } 13665 if (stickies.size() <= 0) { 13666 mStickyBroadcasts.remove(userId); 13667 } 13668 } 13669 } 13670 } 13671 13672 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13673 String resultData, Bundle resultExtras, boolean resultAbort) { 13674 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13675 if (r == null) { 13676 Slog.w(TAG, "finishReceiver called but not found on queue"); 13677 return false; 13678 } 13679 13680 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13681 } 13682 13683 void backgroundServicesFinishedLocked(int userId) { 13684 for (BroadcastQueue queue : mBroadcastQueues) { 13685 queue.backgroundServicesFinishedLocked(userId); 13686 } 13687 } 13688 13689 public void finishReceiver(IBinder who, int resultCode, String resultData, 13690 Bundle resultExtras, boolean resultAbort) { 13691 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13692 13693 // Refuse possible leaked file descriptors 13694 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13695 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13696 } 13697 13698 final long origId = Binder.clearCallingIdentity(); 13699 try { 13700 boolean doNext = false; 13701 BroadcastRecord r; 13702 13703 synchronized(this) { 13704 r = broadcastRecordForReceiverLocked(who); 13705 if (r != null) { 13706 doNext = r.queue.finishReceiverLocked(r, resultCode, 13707 resultData, resultExtras, resultAbort, true); 13708 } 13709 } 13710 13711 if (doNext) { 13712 r.queue.processNextBroadcast(false); 13713 } 13714 trimApplications(); 13715 } finally { 13716 Binder.restoreCallingIdentity(origId); 13717 } 13718 } 13719 13720 // ========================================================= 13721 // INSTRUMENTATION 13722 // ========================================================= 13723 13724 public boolean startInstrumentation(ComponentName className, 13725 String profileFile, int flags, Bundle arguments, 13726 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13727 int userId) { 13728 enforceNotIsolatedCaller("startInstrumentation"); 13729 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13730 userId, false, true, "startInstrumentation", null); 13731 // Refuse possible leaked file descriptors 13732 if (arguments != null && arguments.hasFileDescriptors()) { 13733 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13734 } 13735 13736 synchronized(this) { 13737 InstrumentationInfo ii = null; 13738 ApplicationInfo ai = null; 13739 try { 13740 ii = mContext.getPackageManager().getInstrumentationInfo( 13741 className, STOCK_PM_FLAGS); 13742 ai = AppGlobals.getPackageManager().getApplicationInfo( 13743 ii.targetPackage, STOCK_PM_FLAGS, userId); 13744 } catch (PackageManager.NameNotFoundException e) { 13745 } catch (RemoteException e) { 13746 } 13747 if (ii == null) { 13748 reportStartInstrumentationFailure(watcher, className, 13749 "Unable to find instrumentation info for: " + className); 13750 return false; 13751 } 13752 if (ai == null) { 13753 reportStartInstrumentationFailure(watcher, className, 13754 "Unable to find instrumentation target package: " + ii.targetPackage); 13755 return false; 13756 } 13757 13758 int match = mContext.getPackageManager().checkSignatures( 13759 ii.targetPackage, ii.packageName); 13760 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13761 String msg = "Permission Denial: starting instrumentation " 13762 + className + " from pid=" 13763 + Binder.getCallingPid() 13764 + ", uid=" + Binder.getCallingPid() 13765 + " not allowed because package " + ii.packageName 13766 + " does not have a signature matching the target " 13767 + ii.targetPackage; 13768 reportStartInstrumentationFailure(watcher, className, msg); 13769 throw new SecurityException(msg); 13770 } 13771 13772 final long origId = Binder.clearCallingIdentity(); 13773 // Instrumentation can kill and relaunch even persistent processes 13774 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId, 13775 "start instr"); 13776 ProcessRecord app = addAppLocked(ai, false); 13777 app.instrumentationClass = className; 13778 app.instrumentationInfo = ai; 13779 app.instrumentationProfileFile = profileFile; 13780 app.instrumentationArguments = arguments; 13781 app.instrumentationWatcher = watcher; 13782 app.instrumentationUiAutomationConnection = uiAutomationConnection; 13783 app.instrumentationResultClass = className; 13784 Binder.restoreCallingIdentity(origId); 13785 } 13786 13787 return true; 13788 } 13789 13790 /** 13791 * Report errors that occur while attempting to start Instrumentation. Always writes the 13792 * error to the logs, but if somebody is watching, send the report there too. This enables 13793 * the "am" command to report errors with more information. 13794 * 13795 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13796 * @param cn The component name of the instrumentation. 13797 * @param report The error report. 13798 */ 13799 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13800 ComponentName cn, String report) { 13801 Slog.w(TAG, report); 13802 try { 13803 if (watcher != null) { 13804 Bundle results = new Bundle(); 13805 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13806 results.putString("Error", report); 13807 watcher.instrumentationStatus(cn, -1, results); 13808 } 13809 } catch (RemoteException e) { 13810 Slog.w(TAG, e); 13811 } 13812 } 13813 13814 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13815 if (app.instrumentationWatcher != null) { 13816 try { 13817 // NOTE: IInstrumentationWatcher *must* be oneway here 13818 app.instrumentationWatcher.instrumentationFinished( 13819 app.instrumentationClass, 13820 resultCode, 13821 results); 13822 } catch (RemoteException e) { 13823 } 13824 } 13825 if (app.instrumentationUiAutomationConnection != null) { 13826 try { 13827 app.instrumentationUiAutomationConnection.shutdown(); 13828 } catch (RemoteException re) { 13829 /* ignore */ 13830 } 13831 // Only a UiAutomation can set this flag and now that 13832 // it is finished we make sure it is reset to its default. 13833 mUserIsMonkey = false; 13834 } 13835 app.instrumentationWatcher = null; 13836 app.instrumentationUiAutomationConnection = null; 13837 app.instrumentationClass = null; 13838 app.instrumentationInfo = null; 13839 app.instrumentationProfileFile = null; 13840 app.instrumentationArguments = null; 13841 13842 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId, 13843 "finished inst"); 13844 } 13845 13846 public void finishInstrumentation(IApplicationThread target, 13847 int resultCode, Bundle results) { 13848 int userId = UserHandle.getCallingUserId(); 13849 // Refuse possible leaked file descriptors 13850 if (results != null && results.hasFileDescriptors()) { 13851 throw new IllegalArgumentException("File descriptors passed in Intent"); 13852 } 13853 13854 synchronized(this) { 13855 ProcessRecord app = getRecordForAppLocked(target); 13856 if (app == null) { 13857 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13858 return; 13859 } 13860 final long origId = Binder.clearCallingIdentity(); 13861 finishInstrumentationLocked(app, resultCode, results); 13862 Binder.restoreCallingIdentity(origId); 13863 } 13864 } 13865 13866 // ========================================================= 13867 // CONFIGURATION 13868 // ========================================================= 13869 13870 public ConfigurationInfo getDeviceConfigurationInfo() { 13871 ConfigurationInfo config = new ConfigurationInfo(); 13872 synchronized (this) { 13873 config.reqTouchScreen = mConfiguration.touchscreen; 13874 config.reqKeyboardType = mConfiguration.keyboard; 13875 config.reqNavigation = mConfiguration.navigation; 13876 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13877 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13878 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13879 } 13880 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13881 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13882 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13883 } 13884 config.reqGlEsVersion = GL_ES_VERSION; 13885 } 13886 return config; 13887 } 13888 13889 ActivityStack getFocusedStack() { 13890 return mStackSupervisor.getFocusedStack(); 13891 } 13892 13893 public Configuration getConfiguration() { 13894 Configuration ci; 13895 synchronized(this) { 13896 ci = new Configuration(mConfiguration); 13897 } 13898 return ci; 13899 } 13900 13901 public void updatePersistentConfiguration(Configuration values) { 13902 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13903 "updateConfiguration()"); 13904 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 13905 "updateConfiguration()"); 13906 if (values == null) { 13907 throw new NullPointerException("Configuration must not be null"); 13908 } 13909 13910 synchronized(this) { 13911 final long origId = Binder.clearCallingIdentity(); 13912 updateConfigurationLocked(values, null, true, false); 13913 Binder.restoreCallingIdentity(origId); 13914 } 13915 } 13916 13917 public void updateConfiguration(Configuration values) { 13918 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13919 "updateConfiguration()"); 13920 13921 synchronized(this) { 13922 if (values == null && mWindowManager != null) { 13923 // sentinel: fetch the current configuration from the window manager 13924 values = mWindowManager.computeNewConfiguration(); 13925 } 13926 13927 if (mWindowManager != null) { 13928 mProcessList.applyDisplaySize(mWindowManager); 13929 } 13930 13931 final long origId = Binder.clearCallingIdentity(); 13932 if (values != null) { 13933 Settings.System.clearConfiguration(values); 13934 } 13935 updateConfigurationLocked(values, null, false, false); 13936 Binder.restoreCallingIdentity(origId); 13937 } 13938 } 13939 13940 /** 13941 * Do either or both things: (1) change the current configuration, and (2) 13942 * make sure the given activity is running with the (now) current 13943 * configuration. Returns true if the activity has been left running, or 13944 * false if <var>starting</var> is being destroyed to match the new 13945 * configuration. 13946 * @param persistent TODO 13947 */ 13948 boolean updateConfigurationLocked(Configuration values, 13949 ActivityRecord starting, boolean persistent, boolean initLocale) { 13950 int changes = 0; 13951 13952 if (values != null) { 13953 Configuration newConfig = new Configuration(mConfiguration); 13954 changes = newConfig.updateFrom(values); 13955 if (changes != 0) { 13956 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13957 Slog.i(TAG, "Updating configuration to: " + values); 13958 } 13959 13960 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 13961 13962 if (values.locale != null && !initLocale) { 13963 saveLocaleLocked(values.locale, 13964 !values.locale.equals(mConfiguration.locale), 13965 values.userSetLocale); 13966 } 13967 13968 mConfigurationSeq++; 13969 if (mConfigurationSeq <= 0) { 13970 mConfigurationSeq = 1; 13971 } 13972 newConfig.seq = mConfigurationSeq; 13973 mConfiguration = newConfig; 13974 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 13975 13976 final Configuration configCopy = new Configuration(mConfiguration); 13977 13978 // TODO: If our config changes, should we auto dismiss any currently 13979 // showing dialogs? 13980 mShowDialogs = shouldShowDialogs(newConfig); 13981 13982 AttributeCache ac = AttributeCache.instance(); 13983 if (ac != null) { 13984 ac.updateConfiguration(configCopy); 13985 } 13986 13987 // Make sure all resources in our process are updated 13988 // right now, so that anyone who is going to retrieve 13989 // resource values after we return will be sure to get 13990 // the new ones. This is especially important during 13991 // boot, where the first config change needs to guarantee 13992 // all resources have that config before following boot 13993 // code is executed. 13994 mSystemThread.applyConfigurationToResources(configCopy); 13995 13996 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 13997 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 13998 msg.obj = new Configuration(configCopy); 13999 mHandler.sendMessage(msg); 14000 } 14001 14002 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14003 ProcessRecord app = mLruProcesses.get(i); 14004 try { 14005 if (app.thread != null) { 14006 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14007 + app.processName + " new config " + mConfiguration); 14008 app.thread.scheduleConfigurationChanged(configCopy); 14009 } 14010 } catch (Exception e) { 14011 } 14012 } 14013 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14014 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14015 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14016 | Intent.FLAG_RECEIVER_FOREGROUND); 14017 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14018 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14019 Process.SYSTEM_UID, UserHandle.USER_ALL); 14020 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14021 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14022 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14023 broadcastIntentLocked(null, null, intent, 14024 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14025 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14026 } 14027 } 14028 } 14029 14030 boolean kept = true; 14031 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14032 // mainStack is null during startup. 14033 if (mainStack != null) { 14034 if (changes != 0 && starting == null) { 14035 // If the configuration changed, and the caller is not already 14036 // in the process of starting an activity, then find the top 14037 // activity to check if its configuration needs to change. 14038 starting = mainStack.topRunningActivityLocked(null); 14039 } 14040 14041 if (starting != null) { 14042 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14043 // And we need to make sure at this point that all other activities 14044 // are made visible with the correct configuration. 14045 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14046 } 14047 } 14048 14049 if (values != null && mWindowManager != null) { 14050 mWindowManager.setNewConfiguration(mConfiguration); 14051 } 14052 14053 return kept; 14054 } 14055 14056 /** 14057 * Decide based on the configuration whether we should shouw the ANR, 14058 * crash, etc dialogs. The idea is that if there is no affordnace to 14059 * press the on-screen buttons, we shouldn't show the dialog. 14060 * 14061 * A thought: SystemUI might also want to get told about this, the Power 14062 * dialog / global actions also might want different behaviors. 14063 */ 14064 private static final boolean shouldShowDialogs(Configuration config) { 14065 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14066 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14067 } 14068 14069 /** 14070 * Save the locale. You must be inside a synchronized (this) block. 14071 */ 14072 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14073 if(isDiff) { 14074 SystemProperties.set("user.language", l.getLanguage()); 14075 SystemProperties.set("user.region", l.getCountry()); 14076 } 14077 14078 if(isPersist) { 14079 SystemProperties.set("persist.sys.language", l.getLanguage()); 14080 SystemProperties.set("persist.sys.country", l.getCountry()); 14081 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14082 } 14083 } 14084 14085 @Override 14086 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14087 ActivityRecord srec = ActivityRecord.forToken(token); 14088 return srec != null && srec.task.affinity != null && 14089 srec.task.affinity.equals(destAffinity); 14090 } 14091 14092 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14093 Intent resultData) { 14094 14095 synchronized (this) { 14096 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14097 if (stack != null) { 14098 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14099 } 14100 return false; 14101 } 14102 } 14103 14104 public int getLaunchedFromUid(IBinder activityToken) { 14105 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14106 if (srec == null) { 14107 return -1; 14108 } 14109 return srec.launchedFromUid; 14110 } 14111 14112 public String getLaunchedFromPackage(IBinder activityToken) { 14113 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14114 if (srec == null) { 14115 return null; 14116 } 14117 return srec.launchedFromPackage; 14118 } 14119 14120 // ========================================================= 14121 // LIFETIME MANAGEMENT 14122 // ========================================================= 14123 14124 // Returns which broadcast queue the app is the current [or imminent] receiver 14125 // on, or 'null' if the app is not an active broadcast recipient. 14126 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14127 BroadcastRecord r = app.curReceiver; 14128 if (r != null) { 14129 return r.queue; 14130 } 14131 14132 // It's not the current receiver, but it might be starting up to become one 14133 synchronized (this) { 14134 for (BroadcastQueue queue : mBroadcastQueues) { 14135 r = queue.mPendingBroadcast; 14136 if (r != null && r.curApp == app) { 14137 // found it; report which queue it's in 14138 return queue; 14139 } 14140 } 14141 } 14142 14143 return null; 14144 } 14145 14146 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14147 boolean doingAll, long now) { 14148 if (mAdjSeq == app.adjSeq) { 14149 // This adjustment has already been computed. 14150 return app.curRawAdj; 14151 } 14152 14153 if (app.thread == null) { 14154 app.adjSeq = mAdjSeq; 14155 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14156 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14157 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14158 } 14159 14160 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14161 app.adjSource = null; 14162 app.adjTarget = null; 14163 app.empty = false; 14164 app.cached = false; 14165 14166 final int activitiesSize = app.activities.size(); 14167 14168 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14169 // The max adjustment doesn't allow this app to be anything 14170 // below foreground, so it is not worth doing work for it. 14171 app.adjType = "fixed"; 14172 app.adjSeq = mAdjSeq; 14173 app.curRawAdj = app.maxAdj; 14174 app.foregroundActivities = false; 14175 app.keeping = true; 14176 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14177 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14178 // System process can do UI, and when they do we want to have 14179 // them trim their memory after the user leaves the UI. To 14180 // facilitate this, here we need to determine whether or not it 14181 // is currently showing UI. 14182 app.systemNoUi = true; 14183 if (app == TOP_APP) { 14184 app.systemNoUi = false; 14185 } else if (activitiesSize > 0) { 14186 for (int j = 0; j < activitiesSize; j++) { 14187 final ActivityRecord r = app.activities.get(j); 14188 if (r.visible) { 14189 app.systemNoUi = false; 14190 } 14191 } 14192 } 14193 if (!app.systemNoUi) { 14194 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14195 } 14196 return (app.curAdj=app.maxAdj); 14197 } 14198 14199 app.keeping = false; 14200 app.systemNoUi = false; 14201 14202 // Determine the importance of the process, starting with most 14203 // important to least, and assign an appropriate OOM adjustment. 14204 int adj; 14205 int schedGroup; 14206 int procState; 14207 boolean foregroundActivities = false; 14208 boolean interesting = false; 14209 BroadcastQueue queue; 14210 if (app == TOP_APP) { 14211 // The last app on the list is the foreground app. 14212 adj = ProcessList.FOREGROUND_APP_ADJ; 14213 schedGroup = Process.THREAD_GROUP_DEFAULT; 14214 app.adjType = "top-activity"; 14215 foregroundActivities = true; 14216 interesting = true; 14217 procState = ActivityManager.PROCESS_STATE_TOP; 14218 } else if (app.instrumentationClass != null) { 14219 // Don't want to kill running instrumentation. 14220 adj = ProcessList.FOREGROUND_APP_ADJ; 14221 schedGroup = Process.THREAD_GROUP_DEFAULT; 14222 app.adjType = "instrumentation"; 14223 interesting = true; 14224 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14225 } else if ((queue = isReceivingBroadcast(app)) != null) { 14226 // An app that is currently receiving a broadcast also 14227 // counts as being in the foreground for OOM killer purposes. 14228 // It's placed in a sched group based on the nature of the 14229 // broadcast as reflected by which queue it's active in. 14230 adj = ProcessList.FOREGROUND_APP_ADJ; 14231 schedGroup = (queue == mFgBroadcastQueue) 14232 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14233 app.adjType = "broadcast"; 14234 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14235 } else if (app.executingServices.size() > 0) { 14236 // An app that is currently executing a service callback also 14237 // counts as being in the foreground. 14238 adj = ProcessList.FOREGROUND_APP_ADJ; 14239 schedGroup = app.execServicesFg ? 14240 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14241 app.adjType = "exec-service"; 14242 procState = ActivityManager.PROCESS_STATE_SERVICE; 14243 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14244 } else { 14245 // As far as we know the process is empty. We may change our mind later. 14246 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14247 // At this point we don't actually know the adjustment. Use the cached adj 14248 // value that the caller wants us to. 14249 adj = cachedAdj; 14250 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14251 app.cached = true; 14252 app.empty = true; 14253 app.adjType = "cch-empty"; 14254 } 14255 14256 // Examine all activities if not already foreground. 14257 if (!foregroundActivities && activitiesSize > 0) { 14258 for (int j = 0; j < activitiesSize; j++) { 14259 final ActivityRecord r = app.activities.get(j); 14260 if (r.app != app) { 14261 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14262 + app + "?!?"); 14263 continue; 14264 } 14265 if (r.visible) { 14266 // App has a visible activity; only upgrade adjustment. 14267 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14268 adj = ProcessList.VISIBLE_APP_ADJ; 14269 app.adjType = "visible"; 14270 } 14271 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14272 procState = ActivityManager.PROCESS_STATE_TOP; 14273 } 14274 schedGroup = Process.THREAD_GROUP_DEFAULT; 14275 app.cached = false; 14276 app.empty = false; 14277 foregroundActivities = true; 14278 break; 14279 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14280 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14281 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14282 app.adjType = "pausing"; 14283 } 14284 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14285 procState = ActivityManager.PROCESS_STATE_TOP; 14286 } 14287 schedGroup = Process.THREAD_GROUP_DEFAULT; 14288 app.cached = false; 14289 app.empty = false; 14290 foregroundActivities = true; 14291 } else if (r.state == ActivityState.STOPPING) { 14292 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14293 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14294 app.adjType = "stopping"; 14295 } 14296 // For the process state, we will at this point consider the 14297 // process to be cached. It will be cached either as an activity 14298 // or empty depending on whether the activity is finishing. We do 14299 // this so that we can treat the process as cached for purposes of 14300 // memory trimming (determing current memory level, trim command to 14301 // send to process) since there can be an arbitrary number of stopping 14302 // processes and they should soon all go into the cached state. 14303 if (!r.finishing) { 14304 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14305 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14306 } 14307 } 14308 app.cached = false; 14309 app.empty = false; 14310 foregroundActivities = true; 14311 } else { 14312 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14313 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14314 app.adjType = "cch-act"; 14315 } 14316 } 14317 } 14318 } 14319 14320 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14321 if (app.foregroundServices) { 14322 // The user is aware of this app, so make it visible. 14323 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14324 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14325 app.cached = false; 14326 app.adjType = "fg-service"; 14327 schedGroup = Process.THREAD_GROUP_DEFAULT; 14328 } else if (app.forcingToForeground != null) { 14329 // The user is aware of this app, so make it visible. 14330 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14331 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14332 app.cached = false; 14333 app.adjType = "force-fg"; 14334 app.adjSource = app.forcingToForeground; 14335 schedGroup = Process.THREAD_GROUP_DEFAULT; 14336 } 14337 } 14338 14339 if (app.foregroundServices) { 14340 interesting = true; 14341 } 14342 14343 if (app == mHeavyWeightProcess) { 14344 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14345 // We don't want to kill the current heavy-weight process. 14346 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14347 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14348 app.cached = false; 14349 app.adjType = "heavy"; 14350 } 14351 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14352 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14353 } 14354 } 14355 14356 if (app == mHomeProcess) { 14357 if (adj > ProcessList.HOME_APP_ADJ) { 14358 // This process is hosting what we currently consider to be the 14359 // home app, so we don't want to let it go into the background. 14360 adj = ProcessList.HOME_APP_ADJ; 14361 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14362 app.cached = false; 14363 app.adjType = "home"; 14364 } 14365 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14366 procState = ActivityManager.PROCESS_STATE_HOME; 14367 } 14368 } 14369 14370 if (app == mPreviousProcess && app.activities.size() > 0) { 14371 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14372 // This was the previous process that showed UI to the user. 14373 // We want to try to keep it around more aggressively, to give 14374 // a good experience around switching between two apps. 14375 adj = ProcessList.PREVIOUS_APP_ADJ; 14376 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14377 app.cached = false; 14378 app.adjType = "previous"; 14379 } 14380 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14381 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14382 } 14383 } 14384 14385 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14386 + " reason=" + app.adjType); 14387 14388 // By default, we use the computed adjustment. It may be changed if 14389 // there are applications dependent on our services or providers, but 14390 // this gives us a baseline and makes sure we don't get into an 14391 // infinite recursion. 14392 app.adjSeq = mAdjSeq; 14393 app.curRawAdj = adj; 14394 app.hasStartedServices = false; 14395 14396 if (mBackupTarget != null && app == mBackupTarget.app) { 14397 // If possible we want to avoid killing apps while they're being backed up 14398 if (adj > ProcessList.BACKUP_APP_ADJ) { 14399 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14400 adj = ProcessList.BACKUP_APP_ADJ; 14401 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14402 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14403 } 14404 app.adjType = "backup"; 14405 app.cached = false; 14406 } 14407 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14408 procState = ActivityManager.PROCESS_STATE_BACKUP; 14409 } 14410 } 14411 14412 boolean mayBeTop = false; 14413 14414 for (int is = app.services.size()-1; 14415 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14416 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14417 || procState > ActivityManager.PROCESS_STATE_TOP); 14418 is--) { 14419 ServiceRecord s = app.services.valueAt(is); 14420 if (s.startRequested) { 14421 app.hasStartedServices = true; 14422 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14423 procState = ActivityManager.PROCESS_STATE_SERVICE; 14424 } 14425 if (app.hasShownUi && app != mHomeProcess) { 14426 // If this process has shown some UI, let it immediately 14427 // go to the LRU list because it may be pretty heavy with 14428 // UI stuff. We'll tag it with a label just to help 14429 // debug and understand what is going on. 14430 if (adj > ProcessList.SERVICE_ADJ) { 14431 app.adjType = "cch-started-ui-services"; 14432 } 14433 } else { 14434 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14435 // This service has seen some activity within 14436 // recent memory, so we will keep its process ahead 14437 // of the background processes. 14438 if (adj > ProcessList.SERVICE_ADJ) { 14439 adj = ProcessList.SERVICE_ADJ; 14440 app.adjType = "started-services"; 14441 app.cached = false; 14442 } 14443 } 14444 // If we have let the service slide into the background 14445 // state, still have some text describing what it is doing 14446 // even though the service no longer has an impact. 14447 if (adj > ProcessList.SERVICE_ADJ) { 14448 app.adjType = "cch-started-services"; 14449 } 14450 } 14451 // Don't kill this process because it is doing work; it 14452 // has said it is doing work. 14453 app.keeping = true; 14454 } 14455 for (int conni = s.connections.size()-1; 14456 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14457 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14458 || procState > ActivityManager.PROCESS_STATE_TOP); 14459 conni--) { 14460 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14461 for (int i = 0; 14462 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14463 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14464 || procState > ActivityManager.PROCESS_STATE_TOP); 14465 i++) { 14466 // XXX should compute this based on the max of 14467 // all connected clients. 14468 ConnectionRecord cr = clist.get(i); 14469 if (cr.binding.client == app) { 14470 // Binding to ourself is not interesting. 14471 continue; 14472 } 14473 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14474 ProcessRecord client = cr.binding.client; 14475 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14476 TOP_APP, doingAll, now); 14477 int clientProcState = client.curProcState; 14478 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14479 // If the other app is cached for any reason, for purposes here 14480 // we are going to consider it empty. The specific cached state 14481 // doesn't propagate except under certain conditions. 14482 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14483 } 14484 String adjType = null; 14485 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14486 // Not doing bind OOM management, so treat 14487 // this guy more like a started service. 14488 if (app.hasShownUi && app != mHomeProcess) { 14489 // If this process has shown some UI, let it immediately 14490 // go to the LRU list because it may be pretty heavy with 14491 // UI stuff. We'll tag it with a label just to help 14492 // debug and understand what is going on. 14493 if (adj > clientAdj) { 14494 adjType = "cch-bound-ui-services"; 14495 } 14496 app.cached = false; 14497 clientAdj = adj; 14498 clientProcState = procState; 14499 } else { 14500 if (now >= (s.lastActivity 14501 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14502 // This service has not seen activity within 14503 // recent memory, so allow it to drop to the 14504 // LRU list if there is no other reason to keep 14505 // it around. We'll also tag it with a label just 14506 // to help debug and undertand what is going on. 14507 if (adj > clientAdj) { 14508 adjType = "cch-bound-services"; 14509 } 14510 clientAdj = adj; 14511 } 14512 } 14513 } 14514 if (adj > clientAdj) { 14515 // If this process has recently shown UI, and 14516 // the process that is binding to it is less 14517 // important than being visible, then we don't 14518 // care about the binding as much as we care 14519 // about letting this process get into the LRU 14520 // list to be killed and restarted if needed for 14521 // memory. 14522 if (app.hasShownUi && app != mHomeProcess 14523 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14524 adjType = "cch-bound-ui-services"; 14525 } else { 14526 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14527 |Context.BIND_IMPORTANT)) != 0) { 14528 adj = clientAdj; 14529 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14530 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14531 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14532 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14533 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14534 adj = clientAdj; 14535 } else { 14536 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14537 adj = ProcessList.VISIBLE_APP_ADJ; 14538 } 14539 } 14540 if (!client.cached) { 14541 app.cached = false; 14542 } 14543 if (client.keeping) { 14544 app.keeping = true; 14545 } 14546 adjType = "service"; 14547 } 14548 } 14549 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14550 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14551 schedGroup = Process.THREAD_GROUP_DEFAULT; 14552 } 14553 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14554 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14555 // Special handling of clients who are in the top state. 14556 // We *may* want to consider this process to be in the 14557 // top state as well, but only if there is not another 14558 // reason for it to be running. Being on the top is a 14559 // special state, meaning you are specifically running 14560 // for the current top app. If the process is already 14561 // running in the background for some other reason, it 14562 // is more important to continue considering it to be 14563 // in the background state. 14564 mayBeTop = true; 14565 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14566 } else { 14567 // Special handling for above-top states (persistent 14568 // processes). These should not bring the current process 14569 // into the top state, since they are not on top. Instead 14570 // give them the best state after that. 14571 clientProcState = 14572 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14573 } 14574 } 14575 } else { 14576 if (clientProcState < 14577 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14578 clientProcState = 14579 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14580 } 14581 } 14582 if (procState > clientProcState) { 14583 procState = clientProcState; 14584 } 14585 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14586 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14587 app.pendingUiClean = true; 14588 } 14589 if (adjType != null) { 14590 app.adjType = adjType; 14591 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14592 .REASON_SERVICE_IN_USE; 14593 app.adjSource = cr.binding.client; 14594 app.adjSourceOom = clientAdj; 14595 app.adjTarget = s.name; 14596 } 14597 } 14598 final ActivityRecord a = cr.activity; 14599 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14600 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14601 (a.visible || a.state == ActivityState.RESUMED 14602 || a.state == ActivityState.PAUSING)) { 14603 adj = ProcessList.FOREGROUND_APP_ADJ; 14604 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14605 schedGroup = Process.THREAD_GROUP_DEFAULT; 14606 } 14607 app.cached = false; 14608 app.adjType = "service"; 14609 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14610 .REASON_SERVICE_IN_USE; 14611 app.adjSource = a; 14612 app.adjSourceOom = adj; 14613 app.adjTarget = s.name; 14614 } 14615 } 14616 } 14617 } 14618 } 14619 14620 for (int provi = app.pubProviders.size()-1; 14621 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14622 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14623 || procState > ActivityManager.PROCESS_STATE_TOP); 14624 provi--) { 14625 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14626 for (int i = cpr.connections.size()-1; 14627 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14628 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14629 || procState > ActivityManager.PROCESS_STATE_TOP); 14630 i--) { 14631 ContentProviderConnection conn = cpr.connections.get(i); 14632 ProcessRecord client = conn.client; 14633 if (client == app) { 14634 // Being our own client is not interesting. 14635 continue; 14636 } 14637 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14638 int clientProcState = client.curProcState; 14639 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14640 // If the other app is cached for any reason, for purposes here 14641 // we are going to consider it empty. 14642 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14643 } 14644 if (adj > clientAdj) { 14645 if (app.hasShownUi && app != mHomeProcess 14646 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14647 app.adjType = "cch-ui-provider"; 14648 } else { 14649 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14650 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14651 app.adjType = "provider"; 14652 } 14653 app.cached &= client.cached; 14654 app.keeping |= client.keeping; 14655 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14656 .REASON_PROVIDER_IN_USE; 14657 app.adjSource = client; 14658 app.adjSourceOom = clientAdj; 14659 app.adjTarget = cpr.name; 14660 } 14661 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14662 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14663 // Special handling of clients who are in the top state. 14664 // We *may* want to consider this process to be in the 14665 // top state as well, but only if there is not another 14666 // reason for it to be running. Being on the top is a 14667 // special state, meaning you are specifically running 14668 // for the current top app. If the process is already 14669 // running in the background for some other reason, it 14670 // is more important to continue considering it to be 14671 // in the background state. 14672 mayBeTop = true; 14673 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14674 } else { 14675 // Special handling for above-top states (persistent 14676 // processes). These should not bring the current process 14677 // into the top state, since they are not on top. Instead 14678 // give them the best state after that. 14679 clientProcState = 14680 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14681 } 14682 } 14683 if (procState > clientProcState) { 14684 procState = clientProcState; 14685 } 14686 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14687 schedGroup = Process.THREAD_GROUP_DEFAULT; 14688 } 14689 } 14690 // If the provider has external (non-framework) process 14691 // dependencies, ensure that its adjustment is at least 14692 // FOREGROUND_APP_ADJ. 14693 if (cpr.hasExternalProcessHandles()) { 14694 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14695 adj = ProcessList.FOREGROUND_APP_ADJ; 14696 schedGroup = Process.THREAD_GROUP_DEFAULT; 14697 app.cached = false; 14698 app.keeping = true; 14699 app.adjType = "provider"; 14700 app.adjTarget = cpr.name; 14701 } 14702 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14703 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14704 } 14705 } 14706 } 14707 14708 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14709 // A client of one of our services or providers is in the top state. We 14710 // *may* want to be in the top state, but not if we are already running in 14711 // the background for some other reason. For the decision here, we are going 14712 // to pick out a few specific states that we want to remain in when a client 14713 // is top (states that tend to be longer-term) and otherwise allow it to go 14714 // to the top state. 14715 switch (procState) { 14716 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14717 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14718 case ActivityManager.PROCESS_STATE_SERVICE: 14719 // These all are longer-term states, so pull them up to the top 14720 // of the background states, but not all the way to the top state. 14721 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14722 break; 14723 default: 14724 // Otherwise, top is a better choice, so take it. 14725 procState = ActivityManager.PROCESS_STATE_TOP; 14726 break; 14727 } 14728 } 14729 14730 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14731 // This is a cached process, but with client activities. Mark it so. 14732 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14733 app.adjType = "cch-client-act"; 14734 } 14735 14736 if (adj == ProcessList.SERVICE_ADJ) { 14737 if (doingAll) { 14738 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14739 mNewNumServiceProcs++; 14740 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14741 if (!app.serviceb) { 14742 // This service isn't far enough down on the LRU list to 14743 // normally be a B service, but if we are low on RAM and it 14744 // is large we want to force it down since we would prefer to 14745 // keep launcher over it. 14746 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 14747 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 14748 app.serviceHighRam = true; 14749 app.serviceb = true; 14750 //Slog.i(TAG, "ADJ " + app + " high ram!"); 14751 } else { 14752 mNewNumAServiceProcs++; 14753 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 14754 } 14755 } else { 14756 app.serviceHighRam = false; 14757 } 14758 } 14759 if (app.serviceb) { 14760 adj = ProcessList.SERVICE_B_ADJ; 14761 } 14762 } 14763 14764 app.curRawAdj = adj; 14765 14766 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14767 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14768 if (adj > app.maxAdj) { 14769 adj = app.maxAdj; 14770 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14771 schedGroup = Process.THREAD_GROUP_DEFAULT; 14772 } 14773 } 14774 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 14775 app.keeping = true; 14776 } 14777 14778 // Do final modification to adj. Everything we do between here and applying 14779 // the final setAdj must be done in this function, because we will also use 14780 // it when computing the final cached adj later. Note that we don't need to 14781 // worry about this for max adj above, since max adj will always be used to 14782 // keep it out of the cached vaues. 14783 adj = app.modifyRawOomAdj(adj); 14784 14785 app.curProcState = procState; 14786 14787 int importance = app.memImportance; 14788 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14789 app.curAdj = adj; 14790 app.curSchedGroup = schedGroup; 14791 if (!interesting) { 14792 // For this reporting, if there is not something explicitly 14793 // interesting in this process then we will push it to the 14794 // background importance. 14795 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14796 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 14797 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14798 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14799 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14800 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14801 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14802 } else if (adj >= ProcessList.SERVICE_ADJ) { 14803 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14804 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14805 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14806 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14807 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14808 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14809 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14810 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14811 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14812 } else { 14813 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14814 } 14815 } 14816 14817 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14818 if (foregroundActivities != app.foregroundActivities) { 14819 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14820 } 14821 if (changes != 0) { 14822 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14823 app.memImportance = importance; 14824 app.foregroundActivities = foregroundActivities; 14825 int i = mPendingProcessChanges.size()-1; 14826 ProcessChangeItem item = null; 14827 while (i >= 0) { 14828 item = mPendingProcessChanges.get(i); 14829 if (item.pid == app.pid) { 14830 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14831 break; 14832 } 14833 i--; 14834 } 14835 if (i < 0) { 14836 // No existing item in pending changes; need a new one. 14837 final int NA = mAvailProcessChanges.size(); 14838 if (NA > 0) { 14839 item = mAvailProcessChanges.remove(NA-1); 14840 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14841 } else { 14842 item = new ProcessChangeItem(); 14843 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14844 } 14845 item.changes = 0; 14846 item.pid = app.pid; 14847 item.uid = app.info.uid; 14848 if (mPendingProcessChanges.size() == 0) { 14849 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14850 "*** Enqueueing dispatch processes changed!"); 14851 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14852 } 14853 mPendingProcessChanges.add(item); 14854 } 14855 item.changes |= changes; 14856 item.importance = importance; 14857 item.foregroundActivities = foregroundActivities; 14858 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14859 + Integer.toHexString(System.identityHashCode(item)) 14860 + " " + app.toShortString() + ": changes=" + item.changes 14861 + " importance=" + item.importance 14862 + " foreground=" + item.foregroundActivities 14863 + " type=" + app.adjType + " source=" + app.adjSource 14864 + " target=" + app.adjTarget); 14865 } 14866 14867 return app.curRawAdj; 14868 } 14869 14870 /** 14871 * Schedule PSS collection of a process. 14872 */ 14873 void requestPssLocked(ProcessRecord proc, int procState) { 14874 if (mPendingPssProcesses.contains(proc)) { 14875 return; 14876 } 14877 if (mPendingPssProcesses.size() == 0) { 14878 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14879 } 14880 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 14881 proc.pssProcState = procState; 14882 mPendingPssProcesses.add(proc); 14883 } 14884 14885 /** 14886 * Schedule PSS collection of all processes. 14887 */ 14888 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 14889 if (!always) { 14890 if (now < (mLastFullPssTime + 14891 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 14892 return; 14893 } 14894 } 14895 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 14896 mLastFullPssTime = now; 14897 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 14898 mPendingPssProcesses.clear(); 14899 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14900 ProcessRecord app = mLruProcesses.get(i); 14901 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 14902 app.pssProcState = app.setProcState; 14903 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 14904 mSleeping, now); 14905 mPendingPssProcesses.add(app); 14906 } 14907 } 14908 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14909 } 14910 14911 /** 14912 * Ask a given process to GC right now. 14913 */ 14914 final void performAppGcLocked(ProcessRecord app) { 14915 try { 14916 app.lastRequestedGc = SystemClock.uptimeMillis(); 14917 if (app.thread != null) { 14918 if (app.reportLowMemory) { 14919 app.reportLowMemory = false; 14920 app.thread.scheduleLowMemory(); 14921 } else { 14922 app.thread.processInBackground(); 14923 } 14924 } 14925 } catch (Exception e) { 14926 // whatever. 14927 } 14928 } 14929 14930 /** 14931 * Returns true if things are idle enough to perform GCs. 14932 */ 14933 private final boolean canGcNowLocked() { 14934 boolean processingBroadcasts = false; 14935 for (BroadcastQueue q : mBroadcastQueues) { 14936 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 14937 processingBroadcasts = true; 14938 } 14939 } 14940 return !processingBroadcasts 14941 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 14942 } 14943 14944 /** 14945 * Perform GCs on all processes that are waiting for it, but only 14946 * if things are idle. 14947 */ 14948 final void performAppGcsLocked() { 14949 final int N = mProcessesToGc.size(); 14950 if (N <= 0) { 14951 return; 14952 } 14953 if (canGcNowLocked()) { 14954 while (mProcessesToGc.size() > 0) { 14955 ProcessRecord proc = mProcessesToGc.remove(0); 14956 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 14957 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 14958 <= SystemClock.uptimeMillis()) { 14959 // To avoid spamming the system, we will GC processes one 14960 // at a time, waiting a few seconds between each. 14961 performAppGcLocked(proc); 14962 scheduleAppGcsLocked(); 14963 return; 14964 } else { 14965 // It hasn't been long enough since we last GCed this 14966 // process... put it in the list to wait for its time. 14967 addProcessToGcListLocked(proc); 14968 break; 14969 } 14970 } 14971 } 14972 14973 scheduleAppGcsLocked(); 14974 } 14975 } 14976 14977 /** 14978 * If all looks good, perform GCs on all processes waiting for them. 14979 */ 14980 final void performAppGcsIfAppropriateLocked() { 14981 if (canGcNowLocked()) { 14982 performAppGcsLocked(); 14983 return; 14984 } 14985 // Still not idle, wait some more. 14986 scheduleAppGcsLocked(); 14987 } 14988 14989 /** 14990 * Schedule the execution of all pending app GCs. 14991 */ 14992 final void scheduleAppGcsLocked() { 14993 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 14994 14995 if (mProcessesToGc.size() > 0) { 14996 // Schedule a GC for the time to the next process. 14997 ProcessRecord proc = mProcessesToGc.get(0); 14998 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 14999 15000 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15001 long now = SystemClock.uptimeMillis(); 15002 if (when < (now+GC_TIMEOUT)) { 15003 when = now + GC_TIMEOUT; 15004 } 15005 mHandler.sendMessageAtTime(msg, when); 15006 } 15007 } 15008 15009 /** 15010 * Add a process to the array of processes waiting to be GCed. Keeps the 15011 * list in sorted order by the last GC time. The process can't already be 15012 * on the list. 15013 */ 15014 final void addProcessToGcListLocked(ProcessRecord proc) { 15015 boolean added = false; 15016 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15017 if (mProcessesToGc.get(i).lastRequestedGc < 15018 proc.lastRequestedGc) { 15019 added = true; 15020 mProcessesToGc.add(i+1, proc); 15021 break; 15022 } 15023 } 15024 if (!added) { 15025 mProcessesToGc.add(0, proc); 15026 } 15027 } 15028 15029 /** 15030 * Set up to ask a process to GC itself. This will either do it 15031 * immediately, or put it on the list of processes to gc the next 15032 * time things are idle. 15033 */ 15034 final void scheduleAppGcLocked(ProcessRecord app) { 15035 long now = SystemClock.uptimeMillis(); 15036 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15037 return; 15038 } 15039 if (!mProcessesToGc.contains(app)) { 15040 addProcessToGcListLocked(app); 15041 scheduleAppGcsLocked(); 15042 } 15043 } 15044 15045 final void checkExcessivePowerUsageLocked(boolean doKills) { 15046 updateCpuStatsNow(); 15047 15048 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15049 boolean doWakeKills = doKills; 15050 boolean doCpuKills = doKills; 15051 if (mLastPowerCheckRealtime == 0) { 15052 doWakeKills = false; 15053 } 15054 if (mLastPowerCheckUptime == 0) { 15055 doCpuKills = false; 15056 } 15057 if (stats.isScreenOn()) { 15058 doWakeKills = false; 15059 } 15060 final long curRealtime = SystemClock.elapsedRealtime(); 15061 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15062 final long curUptime = SystemClock.uptimeMillis(); 15063 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15064 mLastPowerCheckRealtime = curRealtime; 15065 mLastPowerCheckUptime = curUptime; 15066 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15067 doWakeKills = false; 15068 } 15069 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15070 doCpuKills = false; 15071 } 15072 int i = mLruProcesses.size(); 15073 while (i > 0) { 15074 i--; 15075 ProcessRecord app = mLruProcesses.get(i); 15076 if (!app.keeping) { 15077 long wtime; 15078 synchronized (stats) { 15079 wtime = stats.getProcessWakeTime(app.info.uid, 15080 app.pid, curRealtime); 15081 } 15082 long wtimeUsed = wtime - app.lastWakeTime; 15083 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15084 if (DEBUG_POWER) { 15085 StringBuilder sb = new StringBuilder(128); 15086 sb.append("Wake for "); 15087 app.toShortString(sb); 15088 sb.append(": over "); 15089 TimeUtils.formatDuration(realtimeSince, sb); 15090 sb.append(" used "); 15091 TimeUtils.formatDuration(wtimeUsed, sb); 15092 sb.append(" ("); 15093 sb.append((wtimeUsed*100)/realtimeSince); 15094 sb.append("%)"); 15095 Slog.i(TAG, sb.toString()); 15096 sb.setLength(0); 15097 sb.append("CPU for "); 15098 app.toShortString(sb); 15099 sb.append(": over "); 15100 TimeUtils.formatDuration(uptimeSince, sb); 15101 sb.append(" used "); 15102 TimeUtils.formatDuration(cputimeUsed, sb); 15103 sb.append(" ("); 15104 sb.append((cputimeUsed*100)/uptimeSince); 15105 sb.append("%)"); 15106 Slog.i(TAG, sb.toString()); 15107 } 15108 // If a process has held a wake lock for more 15109 // than 50% of the time during this period, 15110 // that sounds bad. Kill! 15111 if (doWakeKills && realtimeSince > 0 15112 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15113 synchronized (stats) { 15114 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15115 realtimeSince, wtimeUsed); 15116 } 15117 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15118 + " during " + realtimeSince); 15119 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15120 } else if (doCpuKills && uptimeSince > 0 15121 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15122 synchronized (stats) { 15123 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15124 uptimeSince, cputimeUsed); 15125 } 15126 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15127 + " during " + uptimeSince); 15128 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15129 } else { 15130 app.lastWakeTime = wtime; 15131 app.lastCpuTime = app.curCpuTime; 15132 } 15133 } 15134 } 15135 } 15136 15137 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15138 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15139 boolean success = true; 15140 15141 if (app.curRawAdj != app.setRawAdj) { 15142 if (wasKeeping && !app.keeping) { 15143 // This app is no longer something we want to keep. Note 15144 // its current wake lock time to later know to kill it if 15145 // it is not behaving well. 15146 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15147 synchronized (stats) { 15148 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15149 app.pid, SystemClock.elapsedRealtime()); 15150 } 15151 app.lastCpuTime = app.curCpuTime; 15152 } 15153 15154 app.setRawAdj = app.curRawAdj; 15155 } 15156 15157 if (app.curAdj != app.setAdj) { 15158 ProcessList.setOomAdj(app.pid, app.curAdj); 15159 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15160 TAG, "Set " + app.pid + " " + app.processName + 15161 " adj " + app.curAdj + ": " + app.adjType); 15162 app.setAdj = app.curAdj; 15163 } 15164 15165 if (app.setSchedGroup != app.curSchedGroup) { 15166 app.setSchedGroup = app.curSchedGroup; 15167 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15168 "Setting process group of " + app.processName 15169 + " to " + app.curSchedGroup); 15170 if (app.waitingToKill != null && 15171 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15172 killUnneededProcessLocked(app, app.waitingToKill); 15173 success = false; 15174 } else { 15175 if (true) { 15176 long oldId = Binder.clearCallingIdentity(); 15177 try { 15178 Process.setProcessGroup(app.pid, app.curSchedGroup); 15179 } catch (Exception e) { 15180 Slog.w(TAG, "Failed setting process group of " + app.pid 15181 + " to " + app.curSchedGroup); 15182 e.printStackTrace(); 15183 } finally { 15184 Binder.restoreCallingIdentity(oldId); 15185 } 15186 } else { 15187 if (app.thread != null) { 15188 try { 15189 app.thread.setSchedulingGroup(app.curSchedGroup); 15190 } catch (RemoteException e) { 15191 } 15192 } 15193 } 15194 Process.setSwappiness(app.pid, 15195 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15196 } 15197 } 15198 if (app.repProcState != app.curProcState) { 15199 app.repProcState = app.curProcState; 15200 if (!reportingProcessState && app.thread != null) { 15201 try { 15202 if (false) { 15203 //RuntimeException h = new RuntimeException("here"); 15204 Slog.i(TAG, "Sending new process state " + app.repProcState 15205 + " to " + app /*, h*/); 15206 } 15207 app.thread.setProcessState(app.repProcState); 15208 } catch (RemoteException e) { 15209 } 15210 } 15211 } 15212 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15213 app.setProcState)) { 15214 app.lastStateTime = now; 15215 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15216 mSleeping, now); 15217 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15218 + ProcessList.makeProcStateString(app.setProcState) + " to " 15219 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15220 + (app.nextPssTime-now) + ": " + app); 15221 } else { 15222 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15223 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15224 requestPssLocked(app, app.setProcState); 15225 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15226 mSleeping, now); 15227 } else if (false && DEBUG_PSS) { 15228 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15229 } 15230 } 15231 if (app.setProcState != app.curProcState) { 15232 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15233 "Proc state change of " + app.processName 15234 + " to " + app.curProcState); 15235 app.setProcState = app.curProcState; 15236 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15237 app.notCachedSinceIdle = false; 15238 } 15239 if (!doingAll) { 15240 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15241 } else { 15242 app.procStateChanged = true; 15243 } 15244 } 15245 return success; 15246 } 15247 15248 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15249 if (proc.thread != null && proc.baseProcessTracker != null) { 15250 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15251 } 15252 } 15253 15254 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15255 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15256 if (app.thread == null) { 15257 return false; 15258 } 15259 15260 final boolean wasKeeping = app.keeping; 15261 15262 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15263 15264 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15265 reportingProcessState, now); 15266 } 15267 15268 private final ActivityRecord resumedAppLocked() { 15269 return mStackSupervisor.resumedAppLocked(); 15270 } 15271 15272 final boolean updateOomAdjLocked(ProcessRecord app) { 15273 return updateOomAdjLocked(app, false); 15274 } 15275 15276 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15277 final ActivityRecord TOP_ACT = resumedAppLocked(); 15278 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15279 final boolean wasCached = app.cached; 15280 15281 mAdjSeq++; 15282 15283 // This is the desired cached adjusment we want to tell it to use. 15284 // If our app is currently cached, we know it, and that is it. Otherwise, 15285 // we don't know it yet, and it needs to now be cached we will then 15286 // need to do a complete oom adj. 15287 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15288 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15289 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15290 SystemClock.uptimeMillis()); 15291 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15292 // Changed to/from cached state, so apps after it in the LRU 15293 // list may also be changed. 15294 updateOomAdjLocked(); 15295 } 15296 return success; 15297 } 15298 15299 final void updateOomAdjLocked() { 15300 final ActivityRecord TOP_ACT = resumedAppLocked(); 15301 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15302 final long now = SystemClock.uptimeMillis(); 15303 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15304 final int N = mLruProcesses.size(); 15305 15306 if (false) { 15307 RuntimeException e = new RuntimeException(); 15308 e.fillInStackTrace(); 15309 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15310 } 15311 15312 mAdjSeq++; 15313 mNewNumServiceProcs = 0; 15314 mNewNumAServiceProcs = 0; 15315 15316 final int emptyProcessLimit; 15317 final int cachedProcessLimit; 15318 if (mProcessLimit <= 0) { 15319 emptyProcessLimit = cachedProcessLimit = 0; 15320 } else if (mProcessLimit == 1) { 15321 emptyProcessLimit = 1; 15322 cachedProcessLimit = 0; 15323 } else { 15324 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15325 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15326 } 15327 15328 // Let's determine how many processes we have running vs. 15329 // how many slots we have for background processes; we may want 15330 // to put multiple processes in a slot of there are enough of 15331 // them. 15332 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15333 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15334 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15335 if (numEmptyProcs > cachedProcessLimit) { 15336 // If there are more empty processes than our limit on cached 15337 // processes, then use the cached process limit for the factor. 15338 // This ensures that the really old empty processes get pushed 15339 // down to the bottom, so if we are running low on memory we will 15340 // have a better chance at keeping around more cached processes 15341 // instead of a gazillion empty processes. 15342 numEmptyProcs = cachedProcessLimit; 15343 } 15344 int emptyFactor = numEmptyProcs/numSlots; 15345 if (emptyFactor < 1) emptyFactor = 1; 15346 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15347 if (cachedFactor < 1) cachedFactor = 1; 15348 int stepCached = 0; 15349 int stepEmpty = 0; 15350 int numCached = 0; 15351 int numEmpty = 0; 15352 int numTrimming = 0; 15353 15354 mNumNonCachedProcs = 0; 15355 mNumCachedHiddenProcs = 0; 15356 15357 // First update the OOM adjustment for each of the 15358 // application processes based on their current state. 15359 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15360 int nextCachedAdj = curCachedAdj+1; 15361 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15362 int nextEmptyAdj = curEmptyAdj+2; 15363 for (int i=N-1; i>=0; i--) { 15364 ProcessRecord app = mLruProcesses.get(i); 15365 if (!app.killedByAm && app.thread != null) { 15366 app.procStateChanged = false; 15367 final boolean wasKeeping = app.keeping; 15368 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15369 15370 // If we haven't yet assigned the final cached adj 15371 // to the process, do that now. 15372 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15373 switch (app.curProcState) { 15374 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15375 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15376 // This process is a cached process holding activities... 15377 // assign it the next cached value for that type, and then 15378 // step that cached level. 15379 app.curRawAdj = curCachedAdj; 15380 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15381 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15382 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15383 + ")"); 15384 if (curCachedAdj != nextCachedAdj) { 15385 stepCached++; 15386 if (stepCached >= cachedFactor) { 15387 stepCached = 0; 15388 curCachedAdj = nextCachedAdj; 15389 nextCachedAdj += 2; 15390 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15391 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15392 } 15393 } 15394 } 15395 break; 15396 default: 15397 // For everything else, assign next empty cached process 15398 // level and bump that up. Note that this means that 15399 // long-running services that have dropped down to the 15400 // cached level will be treated as empty (since their process 15401 // state is still as a service), which is what we want. 15402 app.curRawAdj = curEmptyAdj; 15403 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15404 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15405 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15406 + ")"); 15407 if (curEmptyAdj != nextEmptyAdj) { 15408 stepEmpty++; 15409 if (stepEmpty >= emptyFactor) { 15410 stepEmpty = 0; 15411 curEmptyAdj = nextEmptyAdj; 15412 nextEmptyAdj += 2; 15413 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15414 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15415 } 15416 } 15417 } 15418 break; 15419 } 15420 } 15421 15422 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15423 15424 // Count the number of process types. 15425 switch (app.curProcState) { 15426 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15427 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15428 mNumCachedHiddenProcs++; 15429 numCached++; 15430 if (numCached > cachedProcessLimit) { 15431 killUnneededProcessLocked(app, "cached #" + numCached); 15432 } 15433 break; 15434 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15435 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15436 && app.lastActivityTime < oldTime) { 15437 killUnneededProcessLocked(app, "empty for " 15438 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15439 / 1000) + "s"); 15440 } else { 15441 numEmpty++; 15442 if (numEmpty > emptyProcessLimit) { 15443 killUnneededProcessLocked(app, "empty #" + numEmpty); 15444 } 15445 } 15446 break; 15447 default: 15448 mNumNonCachedProcs++; 15449 break; 15450 } 15451 15452 if (app.isolated && app.services.size() <= 0) { 15453 // If this is an isolated process, and there are no 15454 // services running in it, then the process is no longer 15455 // needed. We agressively kill these because we can by 15456 // definition not re-use the same process again, and it is 15457 // good to avoid having whatever code was running in them 15458 // left sitting around after no longer needed. 15459 killUnneededProcessLocked(app, "isolated not needed"); 15460 } 15461 15462 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15463 && !app.killedByAm) { 15464 numTrimming++; 15465 } 15466 } 15467 } 15468 15469 mNumServiceProcs = mNewNumServiceProcs; 15470 15471 // Now determine the memory trimming level of background processes. 15472 // Unfortunately we need to start at the back of the list to do this 15473 // properly. We only do this if the number of background apps we 15474 // are managing to keep around is less than half the maximum we desire; 15475 // if we are keeping a good number around, we'll let them use whatever 15476 // memory they want. 15477 final int numCachedAndEmpty = numCached + numEmpty; 15478 int memFactor; 15479 if (numCached <= ProcessList.TRIM_CACHED_APPS 15480 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15481 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15482 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15483 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15484 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15485 } else { 15486 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15487 } 15488 } else { 15489 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15490 } 15491 // We always allow the memory level to go up (better). We only allow it to go 15492 // down if we are in a state where that is allowed, *and* the total number of processes 15493 // has gone down since last time. 15494 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15495 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15496 + " last=" + mLastNumProcesses); 15497 if (memFactor > mLastMemoryLevel) { 15498 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15499 memFactor = mLastMemoryLevel; 15500 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15501 } 15502 } 15503 mLastMemoryLevel = memFactor; 15504 mLastNumProcesses = mLruProcesses.size(); 15505 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15506 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15507 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15508 if (mLowRamStartTime == 0) { 15509 mLowRamStartTime = now; 15510 } 15511 int step = 0; 15512 int fgTrimLevel; 15513 switch (memFactor) { 15514 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15515 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15516 break; 15517 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15518 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15519 break; 15520 default: 15521 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15522 break; 15523 } 15524 int factor = numTrimming/3; 15525 int minFactor = 2; 15526 if (mHomeProcess != null) minFactor++; 15527 if (mPreviousProcess != null) minFactor++; 15528 if (factor < minFactor) factor = minFactor; 15529 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15530 for (int i=N-1; i>=0; i--) { 15531 ProcessRecord app = mLruProcesses.get(i); 15532 if (allChanged || app.procStateChanged) { 15533 setProcessTrackerState(app, trackerMemFactor, now); 15534 app.procStateChanged = false; 15535 } 15536 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15537 && !app.killedByAm) { 15538 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15539 try { 15540 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15541 "Trimming memory of " + app.processName 15542 + " to " + curLevel); 15543 app.thread.scheduleTrimMemory(curLevel); 15544 } catch (RemoteException e) { 15545 } 15546 if (false) { 15547 // For now we won't do this; our memory trimming seems 15548 // to be good enough at this point that destroying 15549 // activities causes more harm than good. 15550 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15551 && app != mHomeProcess && app != mPreviousProcess) { 15552 // Need to do this on its own message because the stack may not 15553 // be in a consistent state at this point. 15554 // For these apps we will also finish their activities 15555 // to help them free memory. 15556 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15557 } 15558 } 15559 } 15560 app.trimMemoryLevel = curLevel; 15561 step++; 15562 if (step >= factor) { 15563 step = 0; 15564 switch (curLevel) { 15565 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15566 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15567 break; 15568 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15569 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15570 break; 15571 } 15572 } 15573 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15574 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15575 && app.thread != null) { 15576 try { 15577 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15578 "Trimming memory of heavy-weight " + app.processName 15579 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15580 app.thread.scheduleTrimMemory( 15581 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15582 } catch (RemoteException e) { 15583 } 15584 } 15585 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15586 } else { 15587 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15588 || app.systemNoUi) && app.pendingUiClean) { 15589 // If this application is now in the background and it 15590 // had done UI, then give it the special trim level to 15591 // have it free UI resources. 15592 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15593 if (app.trimMemoryLevel < level && app.thread != null) { 15594 try { 15595 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15596 "Trimming memory of bg-ui " + app.processName 15597 + " to " + level); 15598 app.thread.scheduleTrimMemory(level); 15599 } catch (RemoteException e) { 15600 } 15601 } 15602 app.pendingUiClean = false; 15603 } 15604 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15605 try { 15606 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15607 "Trimming memory of fg " + app.processName 15608 + " to " + fgTrimLevel); 15609 app.thread.scheduleTrimMemory(fgTrimLevel); 15610 } catch (RemoteException e) { 15611 } 15612 } 15613 app.trimMemoryLevel = fgTrimLevel; 15614 } 15615 } 15616 } else { 15617 if (mLowRamStartTime != 0) { 15618 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15619 mLowRamStartTime = 0; 15620 } 15621 for (int i=N-1; i>=0; i--) { 15622 ProcessRecord app = mLruProcesses.get(i); 15623 if (allChanged || app.procStateChanged) { 15624 setProcessTrackerState(app, trackerMemFactor, now); 15625 app.procStateChanged = false; 15626 } 15627 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15628 || app.systemNoUi) && app.pendingUiClean) { 15629 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15630 && app.thread != null) { 15631 try { 15632 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15633 "Trimming memory of ui hidden " + app.processName 15634 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15635 app.thread.scheduleTrimMemory( 15636 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15637 } catch (RemoteException e) { 15638 } 15639 } 15640 app.pendingUiClean = false; 15641 } 15642 app.trimMemoryLevel = 0; 15643 } 15644 } 15645 15646 if (mAlwaysFinishActivities) { 15647 // Need to do this on its own message because the stack may not 15648 // be in a consistent state at this point. 15649 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15650 } 15651 15652 if (allChanged) { 15653 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15654 } 15655 15656 if (mProcessStats.shouldWriteNowLocked(now)) { 15657 mHandler.post(new Runnable() { 15658 @Override public void run() { 15659 synchronized (ActivityManagerService.this) { 15660 mProcessStats.writeStateAsyncLocked(); 15661 } 15662 } 15663 }); 15664 } 15665 15666 if (DEBUG_OOM_ADJ) { 15667 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15668 } 15669 } 15670 15671 final void trimApplications() { 15672 synchronized (this) { 15673 int i; 15674 15675 // First remove any unused application processes whose package 15676 // has been removed. 15677 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15678 final ProcessRecord app = mRemovedProcesses.get(i); 15679 if (app.activities.size() == 0 15680 && app.curReceiver == null && app.services.size() == 0) { 15681 Slog.i( 15682 TAG, "Exiting empty application process " 15683 + app.processName + " (" 15684 + (app.thread != null ? app.thread.asBinder() : null) 15685 + ")\n"); 15686 if (app.pid > 0 && app.pid != MY_PID) { 15687 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 15688 app.processName, app.setAdj, "empty"); 15689 app.killedByAm = true; 15690 Process.killProcessQuiet(app.pid); 15691 } else { 15692 try { 15693 app.thread.scheduleExit(); 15694 } catch (Exception e) { 15695 // Ignore exceptions. 15696 } 15697 } 15698 cleanUpApplicationRecordLocked(app, false, true, -1); 15699 mRemovedProcesses.remove(i); 15700 15701 if (app.persistent) { 15702 if (app.persistent) { 15703 addAppLocked(app.info, false); 15704 } 15705 } 15706 } 15707 } 15708 15709 // Now update the oom adj for all processes. 15710 updateOomAdjLocked(); 15711 } 15712 } 15713 15714 /** This method sends the specified signal to each of the persistent apps */ 15715 public void signalPersistentProcesses(int sig) throws RemoteException { 15716 if (sig != Process.SIGNAL_USR1) { 15717 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 15718 } 15719 15720 synchronized (this) { 15721 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 15722 != PackageManager.PERMISSION_GRANTED) { 15723 throw new SecurityException("Requires permission " 15724 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 15725 } 15726 15727 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15728 ProcessRecord r = mLruProcesses.get(i); 15729 if (r.thread != null && r.persistent) { 15730 Process.sendSignal(r.pid, sig); 15731 } 15732 } 15733 } 15734 } 15735 15736 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 15737 if (proc == null || proc == mProfileProc) { 15738 proc = mProfileProc; 15739 path = mProfileFile; 15740 profileType = mProfileType; 15741 clearProfilerLocked(); 15742 } 15743 if (proc == null) { 15744 return; 15745 } 15746 try { 15747 proc.thread.profilerControl(false, path, null, profileType); 15748 } catch (RemoteException e) { 15749 throw new IllegalStateException("Process disappeared"); 15750 } 15751 } 15752 15753 private void clearProfilerLocked() { 15754 if (mProfileFd != null) { 15755 try { 15756 mProfileFd.close(); 15757 } catch (IOException e) { 15758 } 15759 } 15760 mProfileApp = null; 15761 mProfileProc = null; 15762 mProfileFile = null; 15763 mProfileType = 0; 15764 mAutoStopProfiler = false; 15765 } 15766 15767 public boolean profileControl(String process, int userId, boolean start, 15768 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 15769 15770 try { 15771 synchronized (this) { 15772 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15773 // its own permission. 15774 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15775 != PackageManager.PERMISSION_GRANTED) { 15776 throw new SecurityException("Requires permission " 15777 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15778 } 15779 15780 if (start && fd == null) { 15781 throw new IllegalArgumentException("null fd"); 15782 } 15783 15784 ProcessRecord proc = null; 15785 if (process != null) { 15786 proc = findProcessLocked(process, userId, "profileControl"); 15787 } 15788 15789 if (start && (proc == null || proc.thread == null)) { 15790 throw new IllegalArgumentException("Unknown process: " + process); 15791 } 15792 15793 if (start) { 15794 stopProfilerLocked(null, null, 0); 15795 setProfileApp(proc.info, proc.processName, path, fd, false); 15796 mProfileProc = proc; 15797 mProfileType = profileType; 15798 try { 15799 fd = fd.dup(); 15800 } catch (IOException e) { 15801 fd = null; 15802 } 15803 proc.thread.profilerControl(start, path, fd, profileType); 15804 fd = null; 15805 mProfileFd = null; 15806 } else { 15807 stopProfilerLocked(proc, path, profileType); 15808 if (fd != null) { 15809 try { 15810 fd.close(); 15811 } catch (IOException e) { 15812 } 15813 } 15814 } 15815 15816 return true; 15817 } 15818 } catch (RemoteException e) { 15819 throw new IllegalStateException("Process disappeared"); 15820 } finally { 15821 if (fd != null) { 15822 try { 15823 fd.close(); 15824 } catch (IOException e) { 15825 } 15826 } 15827 } 15828 } 15829 15830 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 15831 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15832 userId, true, true, callName, null); 15833 ProcessRecord proc = null; 15834 try { 15835 int pid = Integer.parseInt(process); 15836 synchronized (mPidsSelfLocked) { 15837 proc = mPidsSelfLocked.get(pid); 15838 } 15839 } catch (NumberFormatException e) { 15840 } 15841 15842 if (proc == null) { 15843 ArrayMap<String, SparseArray<ProcessRecord>> all 15844 = mProcessNames.getMap(); 15845 SparseArray<ProcessRecord> procs = all.get(process); 15846 if (procs != null && procs.size() > 0) { 15847 proc = procs.valueAt(0); 15848 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 15849 for (int i=1; i<procs.size(); i++) { 15850 ProcessRecord thisProc = procs.valueAt(i); 15851 if (thisProc.userId == userId) { 15852 proc = thisProc; 15853 break; 15854 } 15855 } 15856 } 15857 } 15858 } 15859 15860 return proc; 15861 } 15862 15863 public boolean dumpHeap(String process, int userId, boolean managed, 15864 String path, ParcelFileDescriptor fd) throws RemoteException { 15865 15866 try { 15867 synchronized (this) { 15868 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15869 // its own permission (same as profileControl). 15870 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15871 != PackageManager.PERMISSION_GRANTED) { 15872 throw new SecurityException("Requires permission " 15873 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15874 } 15875 15876 if (fd == null) { 15877 throw new IllegalArgumentException("null fd"); 15878 } 15879 15880 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 15881 if (proc == null || proc.thread == null) { 15882 throw new IllegalArgumentException("Unknown process: " + process); 15883 } 15884 15885 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 15886 if (!isDebuggable) { 15887 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 15888 throw new SecurityException("Process not debuggable: " + proc); 15889 } 15890 } 15891 15892 proc.thread.dumpHeap(managed, path, fd); 15893 fd = null; 15894 return true; 15895 } 15896 } catch (RemoteException e) { 15897 throw new IllegalStateException("Process disappeared"); 15898 } finally { 15899 if (fd != null) { 15900 try { 15901 fd.close(); 15902 } catch (IOException e) { 15903 } 15904 } 15905 } 15906 } 15907 15908 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 15909 public void monitor() { 15910 synchronized (this) { } 15911 } 15912 15913 void onCoreSettingsChange(Bundle settings) { 15914 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 15915 ProcessRecord processRecord = mLruProcesses.get(i); 15916 try { 15917 if (processRecord.thread != null) { 15918 processRecord.thread.setCoreSettings(settings); 15919 } 15920 } catch (RemoteException re) { 15921 /* ignore */ 15922 } 15923 } 15924 } 15925 15926 // Multi-user methods 15927 15928 @Override 15929 public boolean switchUser(final int userId) { 15930 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 15931 != PackageManager.PERMISSION_GRANTED) { 15932 String msg = "Permission Denial: switchUser() from pid=" 15933 + Binder.getCallingPid() 15934 + ", uid=" + Binder.getCallingUid() 15935 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 15936 Slog.w(TAG, msg); 15937 throw new SecurityException(msg); 15938 } 15939 15940 final long ident = Binder.clearCallingIdentity(); 15941 try { 15942 synchronized (this) { 15943 final int oldUserId = mCurrentUserId; 15944 if (oldUserId == userId) { 15945 return true; 15946 } 15947 15948 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 15949 if (userInfo == null) { 15950 Slog.w(TAG, "No user info for user #" + userId); 15951 return false; 15952 } 15953 15954 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 15955 R.anim.screen_user_enter); 15956 15957 boolean needStart = false; 15958 15959 // If the user we are switching to is not currently started, then 15960 // we need to start it now. 15961 if (mStartedUsers.get(userId) == null) { 15962 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 15963 updateStartedUserArrayLocked(); 15964 needStart = true; 15965 } 15966 15967 mCurrentUserId = userId; 15968 final Integer userIdInt = Integer.valueOf(userId); 15969 mUserLru.remove(userIdInt); 15970 mUserLru.add(userIdInt); 15971 15972 mWindowManager.setCurrentUser(userId); 15973 15974 // Once the internal notion of the active user has switched, we lock the device 15975 // with the option to show the user switcher on the keyguard. 15976 mWindowManager.lockNow(null); 15977 15978 final UserStartedState uss = mStartedUsers.get(userId); 15979 15980 // Make sure user is in the started state. If it is currently 15981 // stopping, we need to knock that off. 15982 if (uss.mState == UserStartedState.STATE_STOPPING) { 15983 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 15984 // so we can just fairly silently bring the user back from 15985 // the almost-dead. 15986 uss.mState = UserStartedState.STATE_RUNNING; 15987 updateStartedUserArrayLocked(); 15988 needStart = true; 15989 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 15990 // This means ACTION_SHUTDOWN has been sent, so we will 15991 // need to treat this as a new boot of the user. 15992 uss.mState = UserStartedState.STATE_BOOTING; 15993 updateStartedUserArrayLocked(); 15994 needStart = true; 15995 } 15996 15997 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 15998 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 15999 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16000 oldUserId, userId, uss)); 16001 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16002 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16003 if (needStart) { 16004 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16005 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16006 | Intent.FLAG_RECEIVER_FOREGROUND); 16007 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16008 broadcastIntentLocked(null, null, intent, 16009 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16010 false, false, MY_PID, Process.SYSTEM_UID, userId); 16011 } 16012 16013 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16014 if (userId != 0) { 16015 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16016 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16017 broadcastIntentLocked(null, null, intent, null, 16018 new IIntentReceiver.Stub() { 16019 public void performReceive(Intent intent, int resultCode, 16020 String data, Bundle extras, boolean ordered, 16021 boolean sticky, int sendingUser) { 16022 userInitialized(uss, userId); 16023 } 16024 }, 0, null, null, null, AppOpsManager.OP_NONE, 16025 true, false, MY_PID, Process.SYSTEM_UID, 16026 userId); 16027 uss.initializing = true; 16028 } else { 16029 getUserManagerLocked().makeInitialized(userInfo.id); 16030 } 16031 } 16032 16033 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16034 if (homeInFront) { 16035 startHomeActivityLocked(userId); 16036 } else { 16037 mStackSupervisor.resumeTopActivitiesLocked(); 16038 } 16039 16040 EventLogTags.writeAmSwitchUser(userId); 16041 getUserManagerLocked().userForeground(userId); 16042 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16043 if (needStart) { 16044 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16045 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16046 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16047 broadcastIntentLocked(null, null, intent, 16048 null, new IIntentReceiver.Stub() { 16049 @Override 16050 public void performReceive(Intent intent, int resultCode, String data, 16051 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16052 throws RemoteException { 16053 } 16054 }, 0, null, null, 16055 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16056 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16057 } 16058 } 16059 } finally { 16060 Binder.restoreCallingIdentity(ident); 16061 } 16062 16063 return true; 16064 } 16065 16066 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16067 long ident = Binder.clearCallingIdentity(); 16068 try { 16069 Intent intent; 16070 if (oldUserId >= 0) { 16071 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16072 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16073 | Intent.FLAG_RECEIVER_FOREGROUND); 16074 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16075 broadcastIntentLocked(null, null, intent, 16076 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16077 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16078 } 16079 if (newUserId >= 0) { 16080 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16081 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16082 | Intent.FLAG_RECEIVER_FOREGROUND); 16083 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16084 broadcastIntentLocked(null, null, intent, 16085 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16086 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16087 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16088 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16089 | Intent.FLAG_RECEIVER_FOREGROUND); 16090 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16091 broadcastIntentLocked(null, null, intent, 16092 null, null, 0, null, null, 16093 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16094 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16095 } 16096 } finally { 16097 Binder.restoreCallingIdentity(ident); 16098 } 16099 } 16100 16101 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16102 final int newUserId) { 16103 final int N = mUserSwitchObservers.beginBroadcast(); 16104 if (N > 0) { 16105 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16106 int mCount = 0; 16107 @Override 16108 public void sendResult(Bundle data) throws RemoteException { 16109 synchronized (ActivityManagerService.this) { 16110 if (mCurUserSwitchCallback == this) { 16111 mCount++; 16112 if (mCount == N) { 16113 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16114 } 16115 } 16116 } 16117 } 16118 }; 16119 synchronized (this) { 16120 uss.switching = true; 16121 mCurUserSwitchCallback = callback; 16122 } 16123 for (int i=0; i<N; i++) { 16124 try { 16125 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16126 newUserId, callback); 16127 } catch (RemoteException e) { 16128 } 16129 } 16130 } else { 16131 synchronized (this) { 16132 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16133 } 16134 } 16135 mUserSwitchObservers.finishBroadcast(); 16136 } 16137 16138 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16139 synchronized (this) { 16140 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16141 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16142 } 16143 } 16144 16145 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16146 mCurUserSwitchCallback = null; 16147 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16148 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16149 oldUserId, newUserId, uss)); 16150 } 16151 16152 void userInitialized(UserStartedState uss, int newUserId) { 16153 completeSwitchAndInitalize(uss, newUserId, true, false); 16154 } 16155 16156 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16157 completeSwitchAndInitalize(uss, newUserId, false, true); 16158 } 16159 16160 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16161 boolean clearInitializing, boolean clearSwitching) { 16162 boolean unfrozen = false; 16163 synchronized (this) { 16164 if (clearInitializing) { 16165 uss.initializing = false; 16166 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16167 } 16168 if (clearSwitching) { 16169 uss.switching = false; 16170 } 16171 if (!uss.switching && !uss.initializing) { 16172 mWindowManager.stopFreezingScreen(); 16173 unfrozen = true; 16174 } 16175 } 16176 if (unfrozen) { 16177 final int N = mUserSwitchObservers.beginBroadcast(); 16178 for (int i=0; i<N; i++) { 16179 try { 16180 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16181 } catch (RemoteException e) { 16182 } 16183 } 16184 mUserSwitchObservers.finishBroadcast(); 16185 } 16186 } 16187 16188 void finishUserSwitch(UserStartedState uss) { 16189 synchronized (this) { 16190 if (uss.mState == UserStartedState.STATE_BOOTING 16191 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16192 uss.mState = UserStartedState.STATE_RUNNING; 16193 final int userId = uss.mHandle.getIdentifier(); 16194 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16195 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16196 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16197 broadcastIntentLocked(null, null, intent, 16198 null, null, 0, null, null, 16199 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16200 true, false, MY_PID, Process.SYSTEM_UID, userId); 16201 } 16202 int num = mUserLru.size(); 16203 int i = 0; 16204 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16205 Integer oldUserId = mUserLru.get(i); 16206 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16207 if (oldUss == null) { 16208 // Shouldn't happen, but be sane if it does. 16209 mUserLru.remove(i); 16210 num--; 16211 continue; 16212 } 16213 if (oldUss.mState == UserStartedState.STATE_STOPPING 16214 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16215 // This user is already stopping, doesn't count. 16216 num--; 16217 i++; 16218 continue; 16219 } 16220 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16221 // Owner and current can't be stopped, but count as running. 16222 i++; 16223 continue; 16224 } 16225 // This is a user to be stopped. 16226 stopUserLocked(oldUserId, null); 16227 num--; 16228 i++; 16229 } 16230 } 16231 } 16232 16233 @Override 16234 public int stopUser(final int userId, final IStopUserCallback callback) { 16235 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16236 != PackageManager.PERMISSION_GRANTED) { 16237 String msg = "Permission Denial: switchUser() from pid=" 16238 + Binder.getCallingPid() 16239 + ", uid=" + Binder.getCallingUid() 16240 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16241 Slog.w(TAG, msg); 16242 throw new SecurityException(msg); 16243 } 16244 if (userId <= 0) { 16245 throw new IllegalArgumentException("Can't stop primary user " + userId); 16246 } 16247 synchronized (this) { 16248 return stopUserLocked(userId, callback); 16249 } 16250 } 16251 16252 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16253 if (mCurrentUserId == userId) { 16254 return ActivityManager.USER_OP_IS_CURRENT; 16255 } 16256 16257 final UserStartedState uss = mStartedUsers.get(userId); 16258 if (uss == null) { 16259 // User is not started, nothing to do... but we do need to 16260 // callback if requested. 16261 if (callback != null) { 16262 mHandler.post(new Runnable() { 16263 @Override 16264 public void run() { 16265 try { 16266 callback.userStopped(userId); 16267 } catch (RemoteException e) { 16268 } 16269 } 16270 }); 16271 } 16272 return ActivityManager.USER_OP_SUCCESS; 16273 } 16274 16275 if (callback != null) { 16276 uss.mStopCallbacks.add(callback); 16277 } 16278 16279 if (uss.mState != UserStartedState.STATE_STOPPING 16280 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16281 uss.mState = UserStartedState.STATE_STOPPING; 16282 updateStartedUserArrayLocked(); 16283 16284 long ident = Binder.clearCallingIdentity(); 16285 try { 16286 // We are going to broadcast ACTION_USER_STOPPING and then 16287 // once that is done send a final ACTION_SHUTDOWN and then 16288 // stop the user. 16289 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16290 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16291 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16292 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16293 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16294 // This is the result receiver for the final shutdown broadcast. 16295 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16296 @Override 16297 public void performReceive(Intent intent, int resultCode, String data, 16298 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16299 finishUserStop(uss); 16300 } 16301 }; 16302 // This is the result receiver for the initial stopping broadcast. 16303 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16304 @Override 16305 public void performReceive(Intent intent, int resultCode, String data, 16306 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16307 // On to the next. 16308 synchronized (ActivityManagerService.this) { 16309 if (uss.mState != UserStartedState.STATE_STOPPING) { 16310 // Whoops, we are being started back up. Abort, abort! 16311 return; 16312 } 16313 uss.mState = UserStartedState.STATE_SHUTDOWN; 16314 } 16315 broadcastIntentLocked(null, null, shutdownIntent, 16316 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16317 true, false, MY_PID, Process.SYSTEM_UID, userId); 16318 } 16319 }; 16320 // Kick things off. 16321 broadcastIntentLocked(null, null, stoppingIntent, 16322 null, stoppingReceiver, 0, null, null, 16323 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16324 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16325 } finally { 16326 Binder.restoreCallingIdentity(ident); 16327 } 16328 } 16329 16330 return ActivityManager.USER_OP_SUCCESS; 16331 } 16332 16333 void finishUserStop(UserStartedState uss) { 16334 final int userId = uss.mHandle.getIdentifier(); 16335 boolean stopped; 16336 ArrayList<IStopUserCallback> callbacks; 16337 synchronized (this) { 16338 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16339 if (mStartedUsers.get(userId) != uss) { 16340 stopped = false; 16341 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16342 stopped = false; 16343 } else { 16344 stopped = true; 16345 // User can no longer run. 16346 mStartedUsers.remove(userId); 16347 mUserLru.remove(Integer.valueOf(userId)); 16348 updateStartedUserArrayLocked(); 16349 16350 // Clean up all state and processes associated with the user. 16351 // Kill all the processes for the user. 16352 forceStopUserLocked(userId, "finish user"); 16353 } 16354 } 16355 16356 for (int i=0; i<callbacks.size(); i++) { 16357 try { 16358 if (stopped) callbacks.get(i).userStopped(userId); 16359 else callbacks.get(i).userStopAborted(userId); 16360 } catch (RemoteException e) { 16361 } 16362 } 16363 16364 mStackSupervisor.removeUserLocked(userId); 16365 } 16366 16367 @Override 16368 public UserInfo getCurrentUser() { 16369 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16370 != PackageManager.PERMISSION_GRANTED) && ( 16371 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16372 != PackageManager.PERMISSION_GRANTED)) { 16373 String msg = "Permission Denial: getCurrentUser() from pid=" 16374 + Binder.getCallingPid() 16375 + ", uid=" + Binder.getCallingUid() 16376 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16377 Slog.w(TAG, msg); 16378 throw new SecurityException(msg); 16379 } 16380 synchronized (this) { 16381 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16382 } 16383 } 16384 16385 int getCurrentUserIdLocked() { 16386 return mCurrentUserId; 16387 } 16388 16389 @Override 16390 public boolean isUserRunning(int userId, boolean orStopped) { 16391 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16392 != PackageManager.PERMISSION_GRANTED) { 16393 String msg = "Permission Denial: isUserRunning() from pid=" 16394 + Binder.getCallingPid() 16395 + ", uid=" + Binder.getCallingUid() 16396 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16397 Slog.w(TAG, msg); 16398 throw new SecurityException(msg); 16399 } 16400 synchronized (this) { 16401 return isUserRunningLocked(userId, orStopped); 16402 } 16403 } 16404 16405 boolean isUserRunningLocked(int userId, boolean orStopped) { 16406 UserStartedState state = mStartedUsers.get(userId); 16407 if (state == null) { 16408 return false; 16409 } 16410 if (orStopped) { 16411 return true; 16412 } 16413 return state.mState != UserStartedState.STATE_STOPPING 16414 && state.mState != UserStartedState.STATE_SHUTDOWN; 16415 } 16416 16417 @Override 16418 public int[] getRunningUserIds() { 16419 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16420 != PackageManager.PERMISSION_GRANTED) { 16421 String msg = "Permission Denial: isUserRunning() from pid=" 16422 + Binder.getCallingPid() 16423 + ", uid=" + Binder.getCallingUid() 16424 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16425 Slog.w(TAG, msg); 16426 throw new SecurityException(msg); 16427 } 16428 synchronized (this) { 16429 return mStartedUserArray; 16430 } 16431 } 16432 16433 private void updateStartedUserArrayLocked() { 16434 int num = 0; 16435 for (int i=0; i<mStartedUsers.size(); i++) { 16436 UserStartedState uss = mStartedUsers.valueAt(i); 16437 // This list does not include stopping users. 16438 if (uss.mState != UserStartedState.STATE_STOPPING 16439 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16440 num++; 16441 } 16442 } 16443 mStartedUserArray = new int[num]; 16444 num = 0; 16445 for (int i=0; i<mStartedUsers.size(); i++) { 16446 UserStartedState uss = mStartedUsers.valueAt(i); 16447 if (uss.mState != UserStartedState.STATE_STOPPING 16448 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16449 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16450 num++; 16451 } 16452 } 16453 } 16454 16455 @Override 16456 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16457 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16458 != PackageManager.PERMISSION_GRANTED) { 16459 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16460 + Binder.getCallingPid() 16461 + ", uid=" + Binder.getCallingUid() 16462 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16463 Slog.w(TAG, msg); 16464 throw new SecurityException(msg); 16465 } 16466 16467 mUserSwitchObservers.register(observer); 16468 } 16469 16470 @Override 16471 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16472 mUserSwitchObservers.unregister(observer); 16473 } 16474 16475 private boolean userExists(int userId) { 16476 if (userId == 0) { 16477 return true; 16478 } 16479 UserManagerService ums = getUserManagerLocked(); 16480 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16481 } 16482 16483 int[] getUsersLocked() { 16484 UserManagerService ums = getUserManagerLocked(); 16485 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16486 } 16487 16488 UserManagerService getUserManagerLocked() { 16489 if (mUserManager == null) { 16490 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16491 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16492 } 16493 return mUserManager; 16494 } 16495 16496 private int applyUserId(int uid, int userId) { 16497 return UserHandle.getUid(userId, uid); 16498 } 16499 16500 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16501 if (info == null) return null; 16502 ApplicationInfo newInfo = new ApplicationInfo(info); 16503 newInfo.uid = applyUserId(info.uid, userId); 16504 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16505 + info.packageName; 16506 return newInfo; 16507 } 16508 16509 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16510 if (aInfo == null 16511 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16512 return aInfo; 16513 } 16514 16515 ActivityInfo info = new ActivityInfo(aInfo); 16516 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16517 return info; 16518 } 16519} 16520