ActivityManagerService.java revision 898c13df7b9b12ff10062f3542593e12fbe0c119
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.SystemService; 54import com.android.server.Watchdog; 55import com.android.server.am.ActivityStack.ActivityState; 56import com.android.server.firewall.IntentFirewall; 57import com.android.server.pm.UserManagerService; 58import com.android.server.wm.AppTransition; 59import com.android.server.wm.WindowManagerService; 60import com.google.android.collect.Lists; 61import com.google.android.collect.Maps; 62 63import dalvik.system.Zygote; 64 65import libcore.io.IoUtils; 66 67import org.xmlpull.v1.XmlPullParser; 68import org.xmlpull.v1.XmlPullParserException; 69import org.xmlpull.v1.XmlSerializer; 70 71import android.app.Activity; 72import android.app.ActivityManager; 73import android.app.ActivityManager.RunningTaskInfo; 74import android.app.ActivityManager.StackInfo; 75import android.app.ActivityManagerNative; 76import android.app.ActivityOptions; 77import android.app.ActivityThread; 78import android.app.AlertDialog; 79import android.app.AppGlobals; 80import android.app.ApplicationErrorReport; 81import android.app.Dialog; 82import android.app.IActivityController; 83import android.app.IApplicationThread; 84import android.app.IInstrumentationWatcher; 85import android.app.INotificationManager; 86import android.app.IProcessObserver; 87import android.app.IServiceConnection; 88import android.app.IStopUserCallback; 89import android.app.IThumbnailReceiver; 90import android.app.IUiAutomationConnection; 91import android.app.IUserSwitchObserver; 92import android.app.Instrumentation; 93import android.app.Notification; 94import android.app.NotificationManager; 95import android.app.PendingIntent; 96import android.app.backup.IBackupManager; 97import android.content.ActivityNotFoundException; 98import android.content.BroadcastReceiver; 99import android.content.ClipData; 100import android.content.ComponentCallbacks2; 101import android.content.ComponentName; 102import android.content.ContentProvider; 103import android.content.ContentResolver; 104import android.content.Context; 105import android.content.DialogInterface; 106import android.content.IContentProvider; 107import android.content.IIntentReceiver; 108import android.content.IIntentSender; 109import android.content.Intent; 110import android.content.IntentFilter; 111import android.content.IntentSender; 112import android.content.pm.ActivityInfo; 113import android.content.pm.ApplicationInfo; 114import android.content.pm.ConfigurationInfo; 115import android.content.pm.IPackageDataObserver; 116import android.content.pm.IPackageManager; 117import android.content.pm.InstrumentationInfo; 118import android.content.pm.PackageInfo; 119import android.content.pm.PackageManager; 120import android.content.pm.ParceledListSlice; 121import android.content.pm.UserInfo; 122import android.content.pm.PackageManager.NameNotFoundException; 123import android.content.pm.PathPermission; 124import android.content.pm.ProviderInfo; 125import android.content.pm.ResolveInfo; 126import android.content.pm.ServiceInfo; 127import android.content.res.CompatibilityInfo; 128import android.content.res.Configuration; 129import android.graphics.Bitmap; 130import android.net.Proxy; 131import android.net.ProxyProperties; 132import android.net.Uri; 133import android.os.Binder; 134import android.os.Build; 135import android.os.Bundle; 136import android.os.Debug; 137import android.os.DropBoxManager; 138import android.os.Environment; 139import android.os.FactoryTest; 140import android.os.FileObserver; 141import android.os.FileUtils; 142import android.os.Handler; 143import android.os.IBinder; 144import android.os.IPermissionController; 145import android.os.IRemoteCallback; 146import android.os.IUserManager; 147import android.os.Looper; 148import android.os.Message; 149import android.os.Parcel; 150import android.os.ParcelFileDescriptor; 151import android.os.Process; 152import android.os.RemoteCallbackList; 153import android.os.RemoteException; 154import android.os.SELinux; 155import android.os.ServiceManager; 156import android.os.StrictMode; 157import android.os.SystemClock; 158import android.os.SystemProperties; 159import android.os.UpdateLock; 160import android.os.UserHandle; 161import android.provider.Settings; 162import android.text.format.DateUtils; 163import android.text.format.Time; 164import android.util.AtomicFile; 165import android.util.EventLog; 166import android.util.Log; 167import android.util.Pair; 168import android.util.PrintWriterPrinter; 169import android.util.Slog; 170import android.util.SparseArray; 171import android.util.TimeUtils; 172import android.util.Xml; 173import android.view.Gravity; 174import android.view.LayoutInflater; 175import android.view.View; 176import android.view.WindowManager; 177 178import java.io.BufferedInputStream; 179import java.io.BufferedOutputStream; 180import java.io.DataInputStream; 181import java.io.DataOutputStream; 182import java.io.File; 183import java.io.FileDescriptor; 184import java.io.FileInputStream; 185import java.io.FileNotFoundException; 186import java.io.FileOutputStream; 187import java.io.IOException; 188import java.io.InputStreamReader; 189import java.io.PrintWriter; 190import java.io.StringWriter; 191import java.lang.ref.WeakReference; 192import java.util.ArrayList; 193import java.util.Arrays; 194import java.util.Collections; 195import java.util.Comparator; 196import java.util.HashMap; 197import java.util.HashSet; 198import java.util.Iterator; 199import java.util.List; 200import java.util.Locale; 201import java.util.Map; 202import java.util.Set; 203import java.util.concurrent.atomic.AtomicBoolean; 204import java.util.concurrent.atomic.AtomicLong; 205 206public final class ActivityManagerService extends ActivityManagerNative 207 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 208 private static final String USER_DATA_DIR = "/data/user/"; 209 static final String TAG = "ActivityManager"; 210 static final String TAG_MU = "ActivityManagerServiceMU"; 211 static final boolean DEBUG = false; 212 static final boolean localLOGV = DEBUG; 213 static final boolean DEBUG_BACKUP = localLOGV || false; 214 static final boolean DEBUG_BROADCAST = localLOGV || false; 215 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 216 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 217 static final boolean DEBUG_CLEANUP = localLOGV || false; 218 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 219 static final boolean DEBUG_FOCUS = false; 220 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 221 static final boolean DEBUG_MU = localLOGV || false; 222 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 223 static final boolean DEBUG_LRU = localLOGV || false; 224 static final boolean DEBUG_PAUSE = localLOGV || false; 225 static final boolean DEBUG_POWER = localLOGV || false; 226 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 227 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 228 static final boolean DEBUG_PROCESSES = localLOGV || false; 229 static final boolean DEBUG_PROVIDER = localLOGV || false; 230 static final boolean DEBUG_RESULTS = localLOGV || false; 231 static final boolean DEBUG_SERVICE = localLOGV || false; 232 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 233 static final boolean DEBUG_STACK = localLOGV || false; 234 static final boolean DEBUG_SWITCH = localLOGV || false; 235 static final boolean DEBUG_TASKS = localLOGV || false; 236 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 237 static final boolean DEBUG_TRANSITION = localLOGV || false; 238 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 239 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 240 static final boolean DEBUG_VISBILITY = localLOGV || false; 241 static final boolean DEBUG_PSS = localLOGV || false; 242 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 243 static final boolean VALIDATE_TOKENS = false; 244 static final boolean SHOW_ACTIVITY_START_TIME = true; 245 246 // Control over CPU and battery monitoring. 247 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 248 static final boolean MONITOR_CPU_USAGE = true; 249 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 250 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 251 static final boolean MONITOR_THREAD_CPU_USAGE = false; 252 253 // The flags that are set for all calls we make to the package manager. 254 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 255 256 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 257 258 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 259 260 // Maximum number of recent tasks that we can remember. 261 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 262 263 // Amount of time after a call to stopAppSwitches() during which we will 264 // prevent further untrusted switches from happening. 265 static final long APP_SWITCH_DELAY_TIME = 5*1000; 266 267 // How long we wait for a launched process to attach to the activity manager 268 // before we decide it's never going to come up for real. 269 static final int PROC_START_TIMEOUT = 10*1000; 270 271 // How long we wait for a launched process to attach to the activity manager 272 // before we decide it's never going to come up for real, when the process was 273 // started with a wrapper for instrumentation (such as Valgrind) because it 274 // could take much longer than usual. 275 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 276 277 // How long to wait after going idle before forcing apps to GC. 278 static final int GC_TIMEOUT = 5*1000; 279 280 // The minimum amount of time between successive GC requests for a process. 281 static final int GC_MIN_INTERVAL = 60*1000; 282 283 // The minimum amount of time between successive PSS requests for a process. 284 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 285 286 // The minimum amount of time between successive PSS requests for a process 287 // when the request is due to the memory state being lowered. 288 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 289 290 // The rate at which we check for apps using excessive power -- 15 mins. 291 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 292 293 // The minimum sample duration we will allow before deciding we have 294 // enough data on wake locks to start killing things. 295 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 296 297 // The minimum sample duration we will allow before deciding we have 298 // enough data on CPU usage to start killing things. 299 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 300 301 // How long we allow a receiver to run before giving up on it. 302 static final int BROADCAST_FG_TIMEOUT = 10*1000; 303 static final int BROADCAST_BG_TIMEOUT = 60*1000; 304 305 // How long we wait until we timeout on key dispatching. 306 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 307 308 // How long we wait until we timeout on key dispatching during instrumentation. 309 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 310 311 // Amount of time we wait for observers to handle a user switch before 312 // giving up on them and unfreezing the screen. 313 static final int USER_SWITCH_TIMEOUT = 2*1000; 314 315 // Maximum number of users we allow to be running at a time. 316 static final int MAX_RUNNING_USERS = 3; 317 318 // How long to wait in getAssistContextExtras for the activity and foreground services 319 // to respond with the result. 320 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 321 322 // Maximum number of persisted Uri grants a package is allowed 323 static final int MAX_PERSISTED_URI_GRANTS = 128; 324 325 static final int MY_PID = Process.myPid(); 326 327 static final String[] EMPTY_STRING_ARRAY = new String[0]; 328 329 // How many bytes to write into the dropbox log before truncating 330 static final int DROPBOX_MAX_SIZE = 256 * 1024; 331 332 /** Run all ActivityStacks through this */ 333 ActivityStackSupervisor mStackSupervisor; 334 335 public IntentFirewall mIntentFirewall; 336 337 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 338 // default actuion automatically. Important for devices without direct input 339 // devices. 340 private boolean mShowDialogs = true; 341 342 /** 343 * Description of a request to start a new activity, which has been held 344 * due to app switches being disabled. 345 */ 346 static class PendingActivityLaunch { 347 final ActivityRecord r; 348 final ActivityRecord sourceRecord; 349 final int startFlags; 350 final ActivityStack stack; 351 352 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 353 int _startFlags, ActivityStack _stack) { 354 r = _r; 355 sourceRecord = _sourceRecord; 356 startFlags = _startFlags; 357 stack = _stack; 358 } 359 } 360 361 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 362 = new ArrayList<PendingActivityLaunch>(); 363 364 BroadcastQueue mFgBroadcastQueue; 365 BroadcastQueue mBgBroadcastQueue; 366 // Convenient for easy iteration over the queues. Foreground is first 367 // so that dispatch of foreground broadcasts gets precedence. 368 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 369 370 BroadcastQueue broadcastQueueForIntent(Intent intent) { 371 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 372 if (DEBUG_BACKGROUND_BROADCAST) { 373 Slog.i(TAG, "Broadcast intent " + intent + " on " 374 + (isFg ? "foreground" : "background") 375 + " queue"); 376 } 377 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 378 } 379 380 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 381 for (BroadcastQueue queue : mBroadcastQueues) { 382 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 383 if (r != null) { 384 return r; 385 } 386 } 387 return null; 388 } 389 390 /** 391 * Activity we have told the window manager to have key focus. 392 */ 393 ActivityRecord mFocusedActivity = null; 394 395 /** 396 * List of intents that were used to start the most recent tasks. 397 */ 398 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 399 400 public class PendingAssistExtras extends Binder implements Runnable { 401 public final ActivityRecord activity; 402 public boolean haveResult = false; 403 public Bundle result = null; 404 public PendingAssistExtras(ActivityRecord _activity) { 405 activity = _activity; 406 } 407 @Override 408 public void run() { 409 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 410 synchronized (this) { 411 haveResult = true; 412 notifyAll(); 413 } 414 } 415 } 416 417 final ArrayList<PendingAssistExtras> mPendingAssistExtras 418 = new ArrayList<PendingAssistExtras>(); 419 420 /** 421 * Process management. 422 */ 423 final ProcessList mProcessList = new ProcessList(); 424 425 /** 426 * All of the applications we currently have running organized by name. 427 * The keys are strings of the application package name (as 428 * returned by the package manager), and the keys are ApplicationRecord 429 * objects. 430 */ 431 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 432 433 /** 434 * Tracking long-term execution of processes to look for abuse and other 435 * bad app behavior. 436 */ 437 final ProcessStatsService mProcessStats; 438 439 /** 440 * The currently running isolated processes. 441 */ 442 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 443 444 /** 445 * Counter for assigning isolated process uids, to avoid frequently reusing the 446 * same ones. 447 */ 448 int mNextIsolatedProcessUid = 0; 449 450 /** 451 * The currently running heavy-weight process, if any. 452 */ 453 ProcessRecord mHeavyWeightProcess = null; 454 455 /** 456 * The last time that various processes have crashed. 457 */ 458 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 459 460 /** 461 * Information about a process that is currently marked as bad. 462 */ 463 static final class BadProcessInfo { 464 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 465 this.time = time; 466 this.shortMsg = shortMsg; 467 this.longMsg = longMsg; 468 this.stack = stack; 469 } 470 471 final long time; 472 final String shortMsg; 473 final String longMsg; 474 final String stack; 475 } 476 477 /** 478 * Set of applications that we consider to be bad, and will reject 479 * incoming broadcasts from (which the user has no control over). 480 * Processes are added to this set when they have crashed twice within 481 * a minimum amount of time; they are removed from it when they are 482 * later restarted (hopefully due to some user action). The value is the 483 * time it was added to the list. 484 */ 485 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 486 487 /** 488 * All of the processes we currently have running organized by pid. 489 * The keys are the pid running the application. 490 * 491 * <p>NOTE: This object is protected by its own lock, NOT the global 492 * activity manager lock! 493 */ 494 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 495 496 /** 497 * All of the processes that have been forced to be foreground. The key 498 * is the pid of the caller who requested it (we hold a death 499 * link on it). 500 */ 501 abstract class ForegroundToken implements IBinder.DeathRecipient { 502 int pid; 503 IBinder token; 504 } 505 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 506 507 /** 508 * List of records for processes that someone had tried to start before the 509 * system was ready. We don't start them at that point, but ensure they 510 * are started by the time booting is complete. 511 */ 512 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 513 514 /** 515 * List of persistent applications that are in the process 516 * of being started. 517 */ 518 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 519 520 /** 521 * Processes that are being forcibly torn down. 522 */ 523 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 524 525 /** 526 * List of running applications, sorted by recent usage. 527 * The first entry in the list is the least recently used. 528 */ 529 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 530 531 /** 532 * Where in mLruProcesses that the processes hosting activities start. 533 */ 534 int mLruProcessActivityStart = 0; 535 536 /** 537 * Where in mLruProcesses that the processes hosting services start. 538 * This is after (lower index) than mLruProcessesActivityStart. 539 */ 540 int mLruProcessServiceStart = 0; 541 542 /** 543 * List of processes that should gc as soon as things are idle. 544 */ 545 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 546 547 /** 548 * Processes we want to collect PSS data from. 549 */ 550 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 551 552 /** 553 * Last time we requested PSS data of all processes. 554 */ 555 long mLastFullPssTime = SystemClock.uptimeMillis(); 556 557 /** 558 * This is the process holding what we currently consider to be 559 * the "home" activity. 560 */ 561 ProcessRecord mHomeProcess; 562 563 /** 564 * This is the process holding the activity the user last visited that 565 * is in a different process from the one they are currently in. 566 */ 567 ProcessRecord mPreviousProcess; 568 569 /** 570 * The time at which the previous process was last visible. 571 */ 572 long mPreviousProcessVisibleTime; 573 574 /** 575 * Which uses have been started, so are allowed to run code. 576 */ 577 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 578 579 /** 580 * LRU list of history of current users. Most recently current is at the end. 581 */ 582 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 583 584 /** 585 * Constant array of the users that are currently started. 586 */ 587 int[] mStartedUserArray = new int[] { 0 }; 588 589 /** 590 * Registered observers of the user switching mechanics. 591 */ 592 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 593 = new RemoteCallbackList<IUserSwitchObserver>(); 594 595 /** 596 * Currently active user switch. 597 */ 598 Object mCurUserSwitchCallback; 599 600 /** 601 * Packages that the user has asked to have run in screen size 602 * compatibility mode instead of filling the screen. 603 */ 604 final CompatModePackages mCompatModePackages; 605 606 /** 607 * Set of IntentSenderRecord objects that are currently active. 608 */ 609 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 610 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 611 612 /** 613 * Fingerprints (hashCode()) of stack traces that we've 614 * already logged DropBox entries for. Guarded by itself. If 615 * something (rogue user app) forces this over 616 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 617 */ 618 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 619 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 620 621 /** 622 * Strict Mode background batched logging state. 623 * 624 * The string buffer is guarded by itself, and its lock is also 625 * used to determine if another batched write is already 626 * in-flight. 627 */ 628 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 629 630 /** 631 * Keeps track of all IIntentReceivers that have been registered for 632 * broadcasts. Hash keys are the receiver IBinder, hash value is 633 * a ReceiverList. 634 */ 635 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 636 new HashMap<IBinder, ReceiverList>(); 637 638 /** 639 * Resolver for broadcast intents to registered receivers. 640 * Holds BroadcastFilter (subclass of IntentFilter). 641 */ 642 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 643 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 644 @Override 645 protected boolean allowFilterResult( 646 BroadcastFilter filter, List<BroadcastFilter> dest) { 647 IBinder target = filter.receiverList.receiver.asBinder(); 648 for (int i=dest.size()-1; i>=0; i--) { 649 if (dest.get(i).receiverList.receiver.asBinder() == target) { 650 return false; 651 } 652 } 653 return true; 654 } 655 656 @Override 657 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 658 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 659 || userId == filter.owningUserId) { 660 return super.newResult(filter, match, userId); 661 } 662 return null; 663 } 664 665 @Override 666 protected BroadcastFilter[] newArray(int size) { 667 return new BroadcastFilter[size]; 668 } 669 670 @Override 671 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 672 return packageName.equals(filter.packageName); 673 } 674 }; 675 676 /** 677 * State of all active sticky broadcasts per user. Keys are the action of the 678 * sticky Intent, values are an ArrayList of all broadcasted intents with 679 * that action (which should usually be one). The SparseArray is keyed 680 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 681 * for stickies that are sent to all users. 682 */ 683 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 684 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 685 686 final ActiveServices mServices; 687 688 /** 689 * Backup/restore process management 690 */ 691 String mBackupAppName = null; 692 BackupRecord mBackupTarget = null; 693 694 /** 695 * List of PendingThumbnailsRecord objects of clients who are still 696 * waiting to receive all of the thumbnails for a task. 697 */ 698 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 699 new ArrayList<PendingThumbnailsRecord>(); 700 701 final ProviderMap mProviderMap; 702 703 /** 704 * List of content providers who have clients waiting for them. The 705 * application is currently being launched and the provider will be 706 * removed from this list once it is published. 707 */ 708 final ArrayList<ContentProviderRecord> mLaunchingProviders 709 = new ArrayList<ContentProviderRecord>(); 710 711 /** 712 * File storing persisted {@link #mGrantedUriPermissions}. 713 */ 714 private final AtomicFile mGrantFile; 715 716 /** XML constants used in {@link #mGrantFile} */ 717 private static final String TAG_URI_GRANTS = "uri-grants"; 718 private static final String TAG_URI_GRANT = "uri-grant"; 719 private static final String ATTR_USER_HANDLE = "userHandle"; 720 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 721 private static final String ATTR_TARGET_PKG = "targetPkg"; 722 private static final String ATTR_URI = "uri"; 723 private static final String ATTR_MODE_FLAGS = "modeFlags"; 724 private static final String ATTR_CREATED_TIME = "createdTime"; 725 726 /** 727 * Global set of specific {@link Uri} permissions that have been granted. 728 * This optimized lookup structure maps from {@link UriPermission#targetUid} 729 * to {@link UriPermission#uri} to {@link UriPermission}. 730 */ 731 @GuardedBy("this") 732 private final SparseArray<ArrayMap<Uri, UriPermission>> 733 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 734 735 CoreSettingsObserver mCoreSettingsObserver; 736 737 /** 738 * Thread-local storage used to carry caller permissions over through 739 * indirect content-provider access. 740 */ 741 private class Identity { 742 public int pid; 743 public int uid; 744 745 Identity(int _pid, int _uid) { 746 pid = _pid; 747 uid = _uid; 748 } 749 } 750 751 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 752 753 /** 754 * All information we have collected about the runtime performance of 755 * any user id that can impact battery performance. 756 */ 757 final BatteryStatsService mBatteryStatsService; 758 759 /** 760 * Information about component usage 761 */ 762 final UsageStatsService mUsageStatsService; 763 764 /** 765 * Information about and control over application operations 766 */ 767 final AppOpsService mAppOpsService; 768 769 /** 770 * Current configuration information. HistoryRecord objects are given 771 * a reference to this object to indicate which configuration they are 772 * currently running in, so this object must be kept immutable. 773 */ 774 Configuration mConfiguration = new Configuration(); 775 776 /** 777 * Current sequencing integer of the configuration, for skipping old 778 * configurations. 779 */ 780 int mConfigurationSeq = 0; 781 782 /** 783 * Hardware-reported OpenGLES version. 784 */ 785 final int GL_ES_VERSION; 786 787 /** 788 * List of initialization arguments to pass to all processes when binding applications to them. 789 * For example, references to the commonly used services. 790 */ 791 HashMap<String, IBinder> mAppBindArgs; 792 793 /** 794 * Temporary to avoid allocations. Protected by main lock. 795 */ 796 final StringBuilder mStringBuilder = new StringBuilder(256); 797 798 /** 799 * Used to control how we initialize the service. 800 */ 801 boolean mStartRunning = false; 802 ComponentName mTopComponent; 803 String mTopAction; 804 String mTopData; 805 boolean mProcessesReady = false; 806 boolean mSystemReady = false; 807 boolean mBooting = false; 808 boolean mWaitingUpdate = false; 809 boolean mDidUpdate = false; 810 boolean mOnBattery = false; 811 boolean mLaunchWarningShown = false; 812 813 Context mContext; 814 815 int mFactoryTest; 816 817 boolean mCheckedForSetup; 818 819 /** 820 * The time at which we will allow normal application switches again, 821 * after a call to {@link #stopAppSwitches()}. 822 */ 823 long mAppSwitchesAllowedTime; 824 825 /** 826 * This is set to true after the first switch after mAppSwitchesAllowedTime 827 * is set; any switches after that will clear the time. 828 */ 829 boolean mDidAppSwitch; 830 831 /** 832 * Last time (in realtime) at which we checked for power usage. 833 */ 834 long mLastPowerCheckRealtime; 835 836 /** 837 * Last time (in uptime) at which we checked for power usage. 838 */ 839 long mLastPowerCheckUptime; 840 841 /** 842 * Set while we are wanting to sleep, to prevent any 843 * activities from being started/resumed. 844 */ 845 boolean mSleeping = false; 846 847 /** 848 * State of external calls telling us if the device is asleep. 849 */ 850 boolean mWentToSleep = false; 851 852 /** 853 * State of external call telling us if the lock screen is shown. 854 */ 855 boolean mLockScreenShown = false; 856 857 /** 858 * Set if we are shutting down the system, similar to sleeping. 859 */ 860 boolean mShuttingDown = false; 861 862 /** 863 * Current sequence id for oom_adj computation traversal. 864 */ 865 int mAdjSeq = 0; 866 867 /** 868 * Current sequence id for process LRU updating. 869 */ 870 int mLruSeq = 0; 871 872 /** 873 * Keep track of the non-cached/empty process we last found, to help 874 * determine how to distribute cached/empty processes next time. 875 */ 876 int mNumNonCachedProcs = 0; 877 878 /** 879 * Keep track of the number of cached hidden procs, to balance oom adj 880 * distribution between those and empty procs. 881 */ 882 int mNumCachedHiddenProcs = 0; 883 884 /** 885 * Keep track of the number of service processes we last found, to 886 * determine on the next iteration which should be B services. 887 */ 888 int mNumServiceProcs = 0; 889 int mNewNumAServiceProcs = 0; 890 int mNewNumServiceProcs = 0; 891 892 /** 893 * Allow the current computed overall memory level of the system to go down? 894 * This is set to false when we are killing processes for reasons other than 895 * memory management, so that the now smaller process list will not be taken as 896 * an indication that memory is tighter. 897 */ 898 boolean mAllowLowerMemLevel = false; 899 900 /** 901 * The last computed memory level, for holding when we are in a state that 902 * processes are going away for other reasons. 903 */ 904 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 905 906 /** 907 * The last total number of process we have, to determine if changes actually look 908 * like a shrinking number of process due to lower RAM. 909 */ 910 int mLastNumProcesses; 911 912 /** 913 * The uptime of the last time we performed idle maintenance. 914 */ 915 long mLastIdleTime = SystemClock.uptimeMillis(); 916 917 /** 918 * Total time spent with RAM that has been added in the past since the last idle time. 919 */ 920 long mLowRamTimeSinceLastIdle = 0; 921 922 /** 923 * If RAM is currently low, when that horrible situatin started. 924 */ 925 long mLowRamStartTime = 0; 926 927 /** 928 * This is set if we had to do a delayed dexopt of an app before launching 929 * it, to increasing the ANR timeouts in that case. 930 */ 931 boolean mDidDexOpt; 932 933 String mDebugApp = null; 934 boolean mWaitForDebugger = false; 935 boolean mDebugTransient = false; 936 String mOrigDebugApp = null; 937 boolean mOrigWaitForDebugger = false; 938 boolean mAlwaysFinishActivities = false; 939 IActivityController mController = null; 940 String mProfileApp = null; 941 ProcessRecord mProfileProc = null; 942 String mProfileFile; 943 ParcelFileDescriptor mProfileFd; 944 int mProfileType = 0; 945 boolean mAutoStopProfiler = false; 946 String mOpenGlTraceApp = null; 947 948 static class ProcessChangeItem { 949 static final int CHANGE_ACTIVITIES = 1<<0; 950 static final int CHANGE_IMPORTANCE= 1<<1; 951 int changes; 952 int uid; 953 int pid; 954 int importance; 955 boolean foregroundActivities; 956 } 957 958 final RemoteCallbackList<IProcessObserver> mProcessObservers 959 = new RemoteCallbackList<IProcessObserver>(); 960 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 961 962 final ArrayList<ProcessChangeItem> mPendingProcessChanges 963 = new ArrayList<ProcessChangeItem>(); 964 final ArrayList<ProcessChangeItem> mAvailProcessChanges 965 = new ArrayList<ProcessChangeItem>(); 966 967 /** 968 * Runtime CPU use collection thread. This object's lock is used to 969 * protect all related state. 970 */ 971 final Thread mProcessCpuThread; 972 973 /** 974 * Used to collect process stats when showing not responding dialog. 975 * Protected by mProcessCpuThread. 976 */ 977 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 978 MONITOR_THREAD_CPU_USAGE); 979 final AtomicLong mLastCpuTime = new AtomicLong(0); 980 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 981 982 long mLastWriteTime = 0; 983 984 /** 985 * Used to retain an update lock when the foreground activity is in 986 * immersive mode. 987 */ 988 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 989 990 /** 991 * Set to true after the system has finished booting. 992 */ 993 boolean mBooted = false; 994 995 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 996 int mProcessLimitOverride = -1; 997 998 WindowManagerService mWindowManager; 999 1000 final ActivityThread mSystemThread; 1001 1002 int mCurrentUserId = 0; 1003 private UserManagerService mUserManager; 1004 1005 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1006 final ProcessRecord mApp; 1007 final int mPid; 1008 final IApplicationThread mAppThread; 1009 1010 AppDeathRecipient(ProcessRecord app, int pid, 1011 IApplicationThread thread) { 1012 if (localLOGV) Slog.v( 1013 TAG, "New death recipient " + this 1014 + " for thread " + thread.asBinder()); 1015 mApp = app; 1016 mPid = pid; 1017 mAppThread = thread; 1018 } 1019 1020 @Override 1021 public void binderDied() { 1022 if (localLOGV) Slog.v( 1023 TAG, "Death received in " + this 1024 + " for thread " + mAppThread.asBinder()); 1025 synchronized(ActivityManagerService.this) { 1026 appDiedLocked(mApp, mPid, mAppThread); 1027 } 1028 } 1029 } 1030 1031 static final int SHOW_ERROR_MSG = 1; 1032 static final int SHOW_NOT_RESPONDING_MSG = 2; 1033 static final int SHOW_FACTORY_ERROR_MSG = 3; 1034 static final int UPDATE_CONFIGURATION_MSG = 4; 1035 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1036 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1037 static final int SERVICE_TIMEOUT_MSG = 12; 1038 static final int UPDATE_TIME_ZONE = 13; 1039 static final int SHOW_UID_ERROR_MSG = 14; 1040 static final int IM_FEELING_LUCKY_MSG = 15; 1041 static final int PROC_START_TIMEOUT_MSG = 20; 1042 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1043 static final int KILL_APPLICATION_MSG = 22; 1044 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1045 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1046 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1047 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1048 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1049 static final int CLEAR_DNS_CACHE_MSG = 28; 1050 static final int UPDATE_HTTP_PROXY_MSG = 29; 1051 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1052 static final int DISPATCH_PROCESSES_CHANGED = 31; 1053 static final int DISPATCH_PROCESS_DIED = 32; 1054 static final int REPORT_MEM_USAGE_MSG = 33; 1055 static final int REPORT_USER_SWITCH_MSG = 34; 1056 static final int CONTINUE_USER_SWITCH_MSG = 35; 1057 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1058 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1059 static final int PERSIST_URI_GRANTS_MSG = 38; 1060 static final int REQUEST_ALL_PSS_MSG = 39; 1061 1062 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1063 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1064 static final int FIRST_COMPAT_MODE_MSG = 300; 1065 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1066 1067 AlertDialog mUidAlert; 1068 CompatModeDialog mCompatModeDialog; 1069 long mLastMemUsageReportTime = 0; 1070 1071 /** 1072 * Flag whether the current user is a "monkey", i.e. whether 1073 * the UI is driven by a UI automation tool. 1074 */ 1075 private boolean mUserIsMonkey; 1076 1077 final ServiceThread mHandlerThread; 1078 final MainHandler mHandler; 1079 1080 final class MainHandler extends Handler { 1081 public MainHandler(Looper looper) { 1082 super(looper, null, true); 1083 } 1084 1085 @Override 1086 public void handleMessage(Message msg) { 1087 switch (msg.what) { 1088 case SHOW_ERROR_MSG: { 1089 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1090 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1091 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1092 synchronized (ActivityManagerService.this) { 1093 ProcessRecord proc = (ProcessRecord)data.get("app"); 1094 AppErrorResult res = (AppErrorResult) data.get("result"); 1095 if (proc != null && proc.crashDialog != null) { 1096 Slog.e(TAG, "App already has crash dialog: " + proc); 1097 if (res != null) { 1098 res.set(0); 1099 } 1100 return; 1101 } 1102 if (!showBackground && UserHandle.getAppId(proc.uid) 1103 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1104 && proc.pid != MY_PID) { 1105 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1106 if (res != null) { 1107 res.set(0); 1108 } 1109 return; 1110 } 1111 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1112 Dialog d = new AppErrorDialog(mContext, 1113 ActivityManagerService.this, res, proc); 1114 d.show(); 1115 proc.crashDialog = d; 1116 } else { 1117 // The device is asleep, so just pretend that the user 1118 // saw a crash dialog and hit "force quit". 1119 if (res != null) { 1120 res.set(0); 1121 } 1122 } 1123 } 1124 1125 ensureBootCompleted(); 1126 } break; 1127 case SHOW_NOT_RESPONDING_MSG: { 1128 synchronized (ActivityManagerService.this) { 1129 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1130 ProcessRecord proc = (ProcessRecord)data.get("app"); 1131 if (proc != null && proc.anrDialog != null) { 1132 Slog.e(TAG, "App already has anr dialog: " + proc); 1133 return; 1134 } 1135 1136 Intent intent = new Intent("android.intent.action.ANR"); 1137 if (!mProcessesReady) { 1138 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1139 | Intent.FLAG_RECEIVER_FOREGROUND); 1140 } 1141 broadcastIntentLocked(null, null, intent, 1142 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1143 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1144 1145 if (mShowDialogs) { 1146 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1147 mContext, proc, (ActivityRecord)data.get("activity"), 1148 msg.arg1 != 0); 1149 d.show(); 1150 proc.anrDialog = d; 1151 } else { 1152 // Just kill the app if there is no dialog to be shown. 1153 killAppAtUsersRequest(proc, null); 1154 } 1155 } 1156 1157 ensureBootCompleted(); 1158 } break; 1159 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1160 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1161 synchronized (ActivityManagerService.this) { 1162 ProcessRecord proc = (ProcessRecord) data.get("app"); 1163 if (proc == null) { 1164 Slog.e(TAG, "App not found when showing strict mode dialog."); 1165 break; 1166 } 1167 if (proc.crashDialog != null) { 1168 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1169 return; 1170 } 1171 AppErrorResult res = (AppErrorResult) data.get("result"); 1172 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1173 Dialog d = new StrictModeViolationDialog(mContext, 1174 ActivityManagerService.this, res, proc); 1175 d.show(); 1176 proc.crashDialog = d; 1177 } else { 1178 // The device is asleep, so just pretend that the user 1179 // saw a crash dialog and hit "force quit". 1180 res.set(0); 1181 } 1182 } 1183 ensureBootCompleted(); 1184 } break; 1185 case SHOW_FACTORY_ERROR_MSG: { 1186 Dialog d = new FactoryErrorDialog( 1187 mContext, msg.getData().getCharSequence("msg")); 1188 d.show(); 1189 ensureBootCompleted(); 1190 } break; 1191 case UPDATE_CONFIGURATION_MSG: { 1192 final ContentResolver resolver = mContext.getContentResolver(); 1193 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1194 } break; 1195 case GC_BACKGROUND_PROCESSES_MSG: { 1196 synchronized (ActivityManagerService.this) { 1197 performAppGcsIfAppropriateLocked(); 1198 } 1199 } break; 1200 case WAIT_FOR_DEBUGGER_MSG: { 1201 synchronized (ActivityManagerService.this) { 1202 ProcessRecord app = (ProcessRecord)msg.obj; 1203 if (msg.arg1 != 0) { 1204 if (!app.waitedForDebugger) { 1205 Dialog d = new AppWaitingForDebuggerDialog( 1206 ActivityManagerService.this, 1207 mContext, app); 1208 app.waitDialog = d; 1209 app.waitedForDebugger = true; 1210 d.show(); 1211 } 1212 } else { 1213 if (app.waitDialog != null) { 1214 app.waitDialog.dismiss(); 1215 app.waitDialog = null; 1216 } 1217 } 1218 } 1219 } break; 1220 case SERVICE_TIMEOUT_MSG: { 1221 if (mDidDexOpt) { 1222 mDidDexOpt = false; 1223 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1224 nmsg.obj = msg.obj; 1225 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1226 return; 1227 } 1228 mServices.serviceTimeout((ProcessRecord)msg.obj); 1229 } break; 1230 case UPDATE_TIME_ZONE: { 1231 synchronized (ActivityManagerService.this) { 1232 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1233 ProcessRecord r = mLruProcesses.get(i); 1234 if (r.thread != null) { 1235 try { 1236 r.thread.updateTimeZone(); 1237 } catch (RemoteException ex) { 1238 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1239 } 1240 } 1241 } 1242 } 1243 } break; 1244 case CLEAR_DNS_CACHE_MSG: { 1245 synchronized (ActivityManagerService.this) { 1246 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1247 ProcessRecord r = mLruProcesses.get(i); 1248 if (r.thread != null) { 1249 try { 1250 r.thread.clearDnsCache(); 1251 } catch (RemoteException ex) { 1252 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1253 } 1254 } 1255 } 1256 } 1257 } break; 1258 case UPDATE_HTTP_PROXY_MSG: { 1259 ProxyProperties proxy = (ProxyProperties)msg.obj; 1260 String host = ""; 1261 String port = ""; 1262 String exclList = ""; 1263 String pacFileUrl = null; 1264 if (proxy != null) { 1265 host = proxy.getHost(); 1266 port = Integer.toString(proxy.getPort()); 1267 exclList = proxy.getExclusionList(); 1268 pacFileUrl = proxy.getPacFileUrl(); 1269 } 1270 synchronized (ActivityManagerService.this) { 1271 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1272 ProcessRecord r = mLruProcesses.get(i); 1273 if (r.thread != null) { 1274 try { 1275 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1276 } catch (RemoteException ex) { 1277 Slog.w(TAG, "Failed to update http proxy for: " + 1278 r.info.processName); 1279 } 1280 } 1281 } 1282 } 1283 } break; 1284 case SHOW_UID_ERROR_MSG: { 1285 String title = "System UIDs Inconsistent"; 1286 String text = "UIDs on the system are inconsistent, you need to wipe your" 1287 + " data partition or your device will be unstable."; 1288 Log.e(TAG, title + ": " + text); 1289 if (mShowDialogs) { 1290 // XXX This is a temporary dialog, no need to localize. 1291 AlertDialog d = new BaseErrorDialog(mContext); 1292 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1293 d.setCancelable(false); 1294 d.setTitle(title); 1295 d.setMessage(text); 1296 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1297 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1298 mUidAlert = d; 1299 d.show(); 1300 } 1301 } break; 1302 case IM_FEELING_LUCKY_MSG: { 1303 if (mUidAlert != null) { 1304 mUidAlert.dismiss(); 1305 mUidAlert = null; 1306 } 1307 } break; 1308 case PROC_START_TIMEOUT_MSG: { 1309 if (mDidDexOpt) { 1310 mDidDexOpt = false; 1311 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1312 nmsg.obj = msg.obj; 1313 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1314 return; 1315 } 1316 ProcessRecord app = (ProcessRecord)msg.obj; 1317 synchronized (ActivityManagerService.this) { 1318 processStartTimedOutLocked(app); 1319 } 1320 } break; 1321 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1322 synchronized (ActivityManagerService.this) { 1323 doPendingActivityLaunchesLocked(true); 1324 } 1325 } break; 1326 case KILL_APPLICATION_MSG: { 1327 synchronized (ActivityManagerService.this) { 1328 int appid = msg.arg1; 1329 boolean restart = (msg.arg2 == 1); 1330 Bundle bundle = (Bundle)msg.obj; 1331 String pkg = bundle.getString("pkg"); 1332 String reason = bundle.getString("reason"); 1333 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1334 UserHandle.USER_ALL, reason); 1335 } 1336 } break; 1337 case FINALIZE_PENDING_INTENT_MSG: { 1338 ((PendingIntentRecord)msg.obj).completeFinalize(); 1339 } break; 1340 case POST_HEAVY_NOTIFICATION_MSG: { 1341 INotificationManager inm = NotificationManager.getService(); 1342 if (inm == null) { 1343 return; 1344 } 1345 1346 ActivityRecord root = (ActivityRecord)msg.obj; 1347 ProcessRecord process = root.app; 1348 if (process == null) { 1349 return; 1350 } 1351 1352 try { 1353 Context context = mContext.createPackageContext(process.info.packageName, 0); 1354 String text = mContext.getString(R.string.heavy_weight_notification, 1355 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1356 Notification notification = new Notification(); 1357 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1358 notification.when = 0; 1359 notification.flags = Notification.FLAG_ONGOING_EVENT; 1360 notification.tickerText = text; 1361 notification.defaults = 0; // please be quiet 1362 notification.sound = null; 1363 notification.vibrate = null; 1364 notification.setLatestEventInfo(context, text, 1365 mContext.getText(R.string.heavy_weight_notification_detail), 1366 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1367 PendingIntent.FLAG_CANCEL_CURRENT, null, 1368 new UserHandle(root.userId))); 1369 1370 try { 1371 int[] outId = new int[1]; 1372 inm.enqueueNotificationWithTag("android", "android", null, 1373 R.string.heavy_weight_notification, 1374 notification, outId, root.userId); 1375 } catch (RuntimeException e) { 1376 Slog.w(ActivityManagerService.TAG, 1377 "Error showing notification for heavy-weight app", e); 1378 } catch (RemoteException e) { 1379 } 1380 } catch (NameNotFoundException e) { 1381 Slog.w(TAG, "Unable to create context for heavy notification", e); 1382 } 1383 } break; 1384 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1385 INotificationManager inm = NotificationManager.getService(); 1386 if (inm == null) { 1387 return; 1388 } 1389 try { 1390 inm.cancelNotificationWithTag("android", null, 1391 R.string.heavy_weight_notification, msg.arg1); 1392 } catch (RuntimeException e) { 1393 Slog.w(ActivityManagerService.TAG, 1394 "Error canceling notification for service", e); 1395 } catch (RemoteException e) { 1396 } 1397 } break; 1398 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1399 synchronized (ActivityManagerService.this) { 1400 checkExcessivePowerUsageLocked(true); 1401 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1402 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1403 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1404 } 1405 } break; 1406 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1407 synchronized (ActivityManagerService.this) { 1408 ActivityRecord ar = (ActivityRecord)msg.obj; 1409 if (mCompatModeDialog != null) { 1410 if (mCompatModeDialog.mAppInfo.packageName.equals( 1411 ar.info.applicationInfo.packageName)) { 1412 return; 1413 } 1414 mCompatModeDialog.dismiss(); 1415 mCompatModeDialog = null; 1416 } 1417 if (ar != null && false) { 1418 if (mCompatModePackages.getPackageAskCompatModeLocked( 1419 ar.packageName)) { 1420 int mode = mCompatModePackages.computeCompatModeLocked( 1421 ar.info.applicationInfo); 1422 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1423 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1424 mCompatModeDialog = new CompatModeDialog( 1425 ActivityManagerService.this, mContext, 1426 ar.info.applicationInfo); 1427 mCompatModeDialog.show(); 1428 } 1429 } 1430 } 1431 } 1432 break; 1433 } 1434 case DISPATCH_PROCESSES_CHANGED: { 1435 dispatchProcessesChanged(); 1436 break; 1437 } 1438 case DISPATCH_PROCESS_DIED: { 1439 final int pid = msg.arg1; 1440 final int uid = msg.arg2; 1441 dispatchProcessDied(pid, uid); 1442 break; 1443 } 1444 case REPORT_MEM_USAGE_MSG: { 1445 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1446 Thread thread = new Thread() { 1447 @Override public void run() { 1448 final SparseArray<ProcessMemInfo> infoMap 1449 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1450 for (int i=0, N=memInfos.size(); i<N; i++) { 1451 ProcessMemInfo mi = memInfos.get(i); 1452 infoMap.put(mi.pid, mi); 1453 } 1454 updateCpuStatsNow(); 1455 synchronized (mProcessCpuThread) { 1456 final int N = mProcessCpuTracker.countStats(); 1457 for (int i=0; i<N; i++) { 1458 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1459 if (st.vsize > 0) { 1460 long pss = Debug.getPss(st.pid, null); 1461 if (pss > 0) { 1462 if (infoMap.indexOfKey(st.pid) < 0) { 1463 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1464 ProcessList.NATIVE_ADJ, -1, "native", null); 1465 mi.pss = pss; 1466 memInfos.add(mi); 1467 } 1468 } 1469 } 1470 } 1471 } 1472 1473 long totalPss = 0; 1474 for (int i=0, N=memInfos.size(); i<N; i++) { 1475 ProcessMemInfo mi = memInfos.get(i); 1476 if (mi.pss == 0) { 1477 mi.pss = Debug.getPss(mi.pid, null); 1478 } 1479 totalPss += mi.pss; 1480 } 1481 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1482 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1483 if (lhs.oomAdj != rhs.oomAdj) { 1484 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1485 } 1486 if (lhs.pss != rhs.pss) { 1487 return lhs.pss < rhs.pss ? 1 : -1; 1488 } 1489 return 0; 1490 } 1491 }); 1492 1493 StringBuilder tag = new StringBuilder(128); 1494 StringBuilder stack = new StringBuilder(128); 1495 tag.append("Low on memory -- "); 1496 appendMemBucket(tag, totalPss, "total", false); 1497 appendMemBucket(stack, totalPss, "total", true); 1498 1499 StringBuilder logBuilder = new StringBuilder(1024); 1500 logBuilder.append("Low on memory:\n"); 1501 1502 boolean firstLine = true; 1503 int lastOomAdj = Integer.MIN_VALUE; 1504 for (int i=0, N=memInfos.size(); i<N; i++) { 1505 ProcessMemInfo mi = memInfos.get(i); 1506 1507 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1508 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1509 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1510 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1511 if (lastOomAdj != mi.oomAdj) { 1512 lastOomAdj = mi.oomAdj; 1513 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1514 tag.append(" / "); 1515 } 1516 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1517 if (firstLine) { 1518 stack.append(":"); 1519 firstLine = false; 1520 } 1521 stack.append("\n\t at "); 1522 } else { 1523 stack.append("$"); 1524 } 1525 } else { 1526 tag.append(" "); 1527 stack.append("$"); 1528 } 1529 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1530 appendMemBucket(tag, mi.pss, mi.name, false); 1531 } 1532 appendMemBucket(stack, mi.pss, mi.name, true); 1533 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1534 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1535 stack.append("("); 1536 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1537 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1538 stack.append(DUMP_MEM_OOM_LABEL[k]); 1539 stack.append(":"); 1540 stack.append(DUMP_MEM_OOM_ADJ[k]); 1541 } 1542 } 1543 stack.append(")"); 1544 } 1545 } 1546 1547 logBuilder.append(" "); 1548 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1549 logBuilder.append(' '); 1550 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1551 logBuilder.append(' '); 1552 ProcessList.appendRamKb(logBuilder, mi.pss); 1553 logBuilder.append(" kB: "); 1554 logBuilder.append(mi.name); 1555 logBuilder.append(" ("); 1556 logBuilder.append(mi.pid); 1557 logBuilder.append(") "); 1558 logBuilder.append(mi.adjType); 1559 logBuilder.append('\n'); 1560 if (mi.adjReason != null) { 1561 logBuilder.append(" "); 1562 logBuilder.append(mi.adjReason); 1563 logBuilder.append('\n'); 1564 } 1565 } 1566 1567 logBuilder.append(" "); 1568 ProcessList.appendRamKb(logBuilder, totalPss); 1569 logBuilder.append(" kB: TOTAL\n"); 1570 1571 long[] infos = new long[Debug.MEMINFO_COUNT]; 1572 Debug.getMemInfo(infos); 1573 logBuilder.append(" MemInfo: "); 1574 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1575 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1576 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1577 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1578 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1579 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1580 logBuilder.append(" ZRAM: "); 1581 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1582 logBuilder.append(" kB RAM, "); 1583 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1584 logBuilder.append(" kB swap total, "); 1585 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1586 logBuilder.append(" kB swap free\n"); 1587 } 1588 Slog.i(TAG, logBuilder.toString()); 1589 1590 StringBuilder dropBuilder = new StringBuilder(1024); 1591 /* 1592 StringWriter oomSw = new StringWriter(); 1593 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1594 StringWriter catSw = new StringWriter(); 1595 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1596 String[] emptyArgs = new String[] { }; 1597 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1598 oomPw.flush(); 1599 String oomString = oomSw.toString(); 1600 */ 1601 dropBuilder.append(stack); 1602 dropBuilder.append('\n'); 1603 dropBuilder.append('\n'); 1604 dropBuilder.append(logBuilder); 1605 dropBuilder.append('\n'); 1606 /* 1607 dropBuilder.append(oomString); 1608 dropBuilder.append('\n'); 1609 */ 1610 StringWriter catSw = new StringWriter(); 1611 synchronized (ActivityManagerService.this) { 1612 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1613 String[] emptyArgs = new String[] { }; 1614 catPw.println(); 1615 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1616 catPw.println(); 1617 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1618 false, false, null); 1619 catPw.println(); 1620 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1621 catPw.flush(); 1622 } 1623 dropBuilder.append(catSw.toString()); 1624 addErrorToDropBox("lowmem", null, "system_server", null, 1625 null, tag.toString(), dropBuilder.toString(), null, null); 1626 //Slog.i(TAG, "Sent to dropbox:"); 1627 //Slog.i(TAG, dropBuilder.toString()); 1628 synchronized (ActivityManagerService.this) { 1629 long now = SystemClock.uptimeMillis(); 1630 if (mLastMemUsageReportTime < now) { 1631 mLastMemUsageReportTime = now; 1632 } 1633 } 1634 } 1635 }; 1636 thread.start(); 1637 break; 1638 } 1639 case REPORT_USER_SWITCH_MSG: { 1640 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1641 break; 1642 } 1643 case CONTINUE_USER_SWITCH_MSG: { 1644 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1645 break; 1646 } 1647 case USER_SWITCH_TIMEOUT_MSG: { 1648 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1649 break; 1650 } 1651 case IMMERSIVE_MODE_LOCK_MSG: { 1652 final boolean nextState = (msg.arg1 != 0); 1653 if (mUpdateLock.isHeld() != nextState) { 1654 if (DEBUG_IMMERSIVE) { 1655 final ActivityRecord r = (ActivityRecord) msg.obj; 1656 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1657 } 1658 if (nextState) { 1659 mUpdateLock.acquire(); 1660 } else { 1661 mUpdateLock.release(); 1662 } 1663 } 1664 break; 1665 } 1666 case PERSIST_URI_GRANTS_MSG: { 1667 writeGrantedUriPermissions(); 1668 break; 1669 } 1670 case REQUEST_ALL_PSS_MSG: { 1671 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1672 break; 1673 } 1674 } 1675 } 1676 }; 1677 1678 static final int COLLECT_PSS_BG_MSG = 1; 1679 1680 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1681 @Override 1682 public void handleMessage(Message msg) { 1683 switch (msg.what) { 1684 case COLLECT_PSS_BG_MSG: { 1685 int i=0, num=0; 1686 long start = SystemClock.uptimeMillis(); 1687 long[] tmp = new long[1]; 1688 do { 1689 ProcessRecord proc; 1690 int procState; 1691 int pid; 1692 synchronized (ActivityManagerService.this) { 1693 if (i >= mPendingPssProcesses.size()) { 1694 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1695 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1696 mPendingPssProcesses.clear(); 1697 return; 1698 } 1699 proc = mPendingPssProcesses.get(i); 1700 procState = proc.pssProcState; 1701 if (proc.thread != null && procState == proc.setProcState) { 1702 pid = proc.pid; 1703 } else { 1704 proc = null; 1705 pid = 0; 1706 } 1707 i++; 1708 } 1709 if (proc != null) { 1710 long pss = Debug.getPss(pid, tmp); 1711 synchronized (ActivityManagerService.this) { 1712 if (proc.thread != null && proc.setProcState == procState 1713 && proc.pid == pid) { 1714 num++; 1715 proc.lastPssTime = SystemClock.uptimeMillis(); 1716 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1717 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1718 + ": " + pss + " lastPss=" + proc.lastPss 1719 + " state=" + ProcessList.makeProcStateString(procState)); 1720 if (proc.initialIdlePss == 0) { 1721 proc.initialIdlePss = pss; 1722 } 1723 proc.lastPss = pss; 1724 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1725 proc.lastCachedPss = pss; 1726 } 1727 } 1728 } 1729 } 1730 } while (true); 1731 } 1732 } 1733 } 1734 }; 1735 1736 public void setSystemProcess() { 1737 try { 1738 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1739 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1740 ServiceManager.addService("meminfo", new MemBinder(this)); 1741 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1742 ServiceManager.addService("dbinfo", new DbBinder(this)); 1743 if (MONITOR_CPU_USAGE) { 1744 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1745 } 1746 ServiceManager.addService("permission", new PermissionController(this)); 1747 1748 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1749 "android", STOCK_PM_FLAGS); 1750 mSystemThread.installSystemApplicationInfo(info); 1751 1752 synchronized (this) { 1753 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1754 app.persistent = true; 1755 app.pid = MY_PID; 1756 app.maxAdj = ProcessList.SYSTEM_ADJ; 1757 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1758 mProcessNames.put(app.processName, app.uid, app); 1759 synchronized (mPidsSelfLocked) { 1760 mPidsSelfLocked.put(app.pid, app); 1761 } 1762 updateLruProcessLocked(app, false, null); 1763 updateOomAdjLocked(); 1764 } 1765 } catch (PackageManager.NameNotFoundException e) { 1766 throw new RuntimeException( 1767 "Unable to find android system package", e); 1768 } 1769 } 1770 1771 public void setWindowManager(WindowManagerService wm) { 1772 mWindowManager = wm; 1773 mStackSupervisor.setWindowManager(wm); 1774 } 1775 1776 public void startObservingNativeCrashes() { 1777 final NativeCrashListener ncl = new NativeCrashListener(this); 1778 ncl.start(); 1779 } 1780 1781 public IAppOpsService getAppOpsService() { 1782 return mAppOpsService; 1783 } 1784 1785 static class MemBinder extends Binder { 1786 ActivityManagerService mActivityManagerService; 1787 MemBinder(ActivityManagerService activityManagerService) { 1788 mActivityManagerService = activityManagerService; 1789 } 1790 1791 @Override 1792 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1793 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1794 != PackageManager.PERMISSION_GRANTED) { 1795 pw.println("Permission Denial: can't dump meminfo from from pid=" 1796 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1797 + " without permission " + android.Manifest.permission.DUMP); 1798 return; 1799 } 1800 1801 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1802 } 1803 } 1804 1805 static class GraphicsBinder extends Binder { 1806 ActivityManagerService mActivityManagerService; 1807 GraphicsBinder(ActivityManagerService activityManagerService) { 1808 mActivityManagerService = activityManagerService; 1809 } 1810 1811 @Override 1812 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1813 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1814 != PackageManager.PERMISSION_GRANTED) { 1815 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1816 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1817 + " without permission " + android.Manifest.permission.DUMP); 1818 return; 1819 } 1820 1821 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1822 } 1823 } 1824 1825 static class DbBinder extends Binder { 1826 ActivityManagerService mActivityManagerService; 1827 DbBinder(ActivityManagerService activityManagerService) { 1828 mActivityManagerService = activityManagerService; 1829 } 1830 1831 @Override 1832 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1833 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1834 != PackageManager.PERMISSION_GRANTED) { 1835 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1836 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1837 + " without permission " + android.Manifest.permission.DUMP); 1838 return; 1839 } 1840 1841 mActivityManagerService.dumpDbInfo(fd, pw, args); 1842 } 1843 } 1844 1845 static class CpuBinder extends Binder { 1846 ActivityManagerService mActivityManagerService; 1847 CpuBinder(ActivityManagerService activityManagerService) { 1848 mActivityManagerService = activityManagerService; 1849 } 1850 1851 @Override 1852 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1853 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1854 != PackageManager.PERMISSION_GRANTED) { 1855 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1856 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1857 + " without permission " + android.Manifest.permission.DUMP); 1858 return; 1859 } 1860 1861 synchronized (mActivityManagerService.mProcessCpuThread) { 1862 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1863 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1864 SystemClock.uptimeMillis())); 1865 } 1866 } 1867 } 1868 1869 public static class Lifecycle extends SystemService { 1870 private ActivityManagerService mService; 1871 1872 @Override 1873 public void onCreate(Context context) { 1874 mService = new ActivityManagerService(context); 1875 } 1876 1877 @Override 1878 public void onStart() { 1879 mService.start(); 1880 } 1881 1882 public ActivityManagerService getService() { 1883 return mService; 1884 } 1885 } 1886 1887 // Note: This method is invoked on the main thread but may need to attach various 1888 // handlers to other threads. So take care to be explicit about the looper. 1889 public ActivityManagerService(Context systemContext) { 1890 mContext = systemContext; 1891 mFactoryTest = FactoryTest.getMode(); 1892 mSystemThread = ActivityThread.currentActivityThread(); 1893 1894 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1895 1896 mHandlerThread = new ServiceThread(TAG, 1897 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1898 mHandlerThread.start(); 1899 mHandler = new MainHandler(mHandlerThread.getLooper()); 1900 1901 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1902 "foreground", BROADCAST_FG_TIMEOUT, false); 1903 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1904 "background", BROADCAST_BG_TIMEOUT, true); 1905 mBroadcastQueues[0] = mFgBroadcastQueue; 1906 mBroadcastQueues[1] = mBgBroadcastQueue; 1907 1908 mServices = new ActiveServices(this); 1909 mProviderMap = new ProviderMap(this); 1910 1911 // TODO: Move creation of battery stats service outside of activity manager service. 1912 File dataDir = Environment.getDataDirectory(); 1913 File systemDir = new File(dataDir, "system"); 1914 systemDir.mkdirs(); 1915 mBatteryStatsService = new BatteryStatsService(new File( 1916 systemDir, "batterystats.bin").toString(), mHandler); 1917 mBatteryStatsService.getActiveStatistics().readLocked(); 1918 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1919 mOnBattery = DEBUG_POWER ? true 1920 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1921 mBatteryStatsService.getActiveStatistics().setCallback(this); 1922 1923 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1924 1925 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1926 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1927 1928 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1929 1930 // User 0 is the first and only user that runs at boot. 1931 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1932 mUserLru.add(Integer.valueOf(0)); 1933 updateStartedUserArrayLocked(); 1934 1935 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1936 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1937 1938 mConfiguration.setToDefaults(); 1939 mConfiguration.setLocale(Locale.getDefault()); 1940 1941 mConfigurationSeq = mConfiguration.seq = 1; 1942 mProcessCpuTracker.init(); 1943 1944 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1945 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1946 mStackSupervisor = new ActivityStackSupervisor(this); 1947 1948 mProcessCpuThread = new Thread("CpuTracker") { 1949 @Override 1950 public void run() { 1951 while (true) { 1952 try { 1953 try { 1954 synchronized(this) { 1955 final long now = SystemClock.uptimeMillis(); 1956 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1957 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1958 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1959 // + ", write delay=" + nextWriteDelay); 1960 if (nextWriteDelay < nextCpuDelay) { 1961 nextCpuDelay = nextWriteDelay; 1962 } 1963 if (nextCpuDelay > 0) { 1964 mProcessCpuMutexFree.set(true); 1965 this.wait(nextCpuDelay); 1966 } 1967 } 1968 } catch (InterruptedException e) { 1969 } 1970 updateCpuStatsNow(); 1971 } catch (Exception e) { 1972 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1973 } 1974 } 1975 } 1976 }; 1977 1978 Watchdog.getInstance().addMonitor(this); 1979 Watchdog.getInstance().addThread(mHandler); 1980 } 1981 1982 private void start() { 1983 mProcessCpuThread.start(); 1984 1985 mBatteryStatsService.publish(mContext); 1986 mUsageStatsService.publish(mContext); 1987 mAppOpsService.publish(mContext); 1988 startRunning(null, null, null, null); 1989 } 1990 1991 @Override 1992 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1993 throws RemoteException { 1994 if (code == SYSPROPS_TRANSACTION) { 1995 // We need to tell all apps about the system property change. 1996 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1997 synchronized(this) { 1998 final int NP = mProcessNames.getMap().size(); 1999 for (int ip=0; ip<NP; ip++) { 2000 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2001 final int NA = apps.size(); 2002 for (int ia=0; ia<NA; ia++) { 2003 ProcessRecord app = apps.valueAt(ia); 2004 if (app.thread != null) { 2005 procs.add(app.thread.asBinder()); 2006 } 2007 } 2008 } 2009 } 2010 2011 int N = procs.size(); 2012 for (int i=0; i<N; i++) { 2013 Parcel data2 = Parcel.obtain(); 2014 try { 2015 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2016 } catch (RemoteException e) { 2017 } 2018 data2.recycle(); 2019 } 2020 } 2021 try { 2022 return super.onTransact(code, data, reply, flags); 2023 } catch (RuntimeException e) { 2024 // The activity manager only throws security exceptions, so let's 2025 // log all others. 2026 if (!(e instanceof SecurityException)) { 2027 Slog.wtf(TAG, "Activity Manager Crash", e); 2028 } 2029 throw e; 2030 } 2031 } 2032 2033 void updateCpuStats() { 2034 final long now = SystemClock.uptimeMillis(); 2035 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2036 return; 2037 } 2038 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2039 synchronized (mProcessCpuThread) { 2040 mProcessCpuThread.notify(); 2041 } 2042 } 2043 } 2044 2045 void updateCpuStatsNow() { 2046 synchronized (mProcessCpuThread) { 2047 mProcessCpuMutexFree.set(false); 2048 final long now = SystemClock.uptimeMillis(); 2049 boolean haveNewCpuStats = false; 2050 2051 if (MONITOR_CPU_USAGE && 2052 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2053 mLastCpuTime.set(now); 2054 haveNewCpuStats = true; 2055 mProcessCpuTracker.update(); 2056 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2057 //Slog.i(TAG, "Total CPU usage: " 2058 // + mProcessCpu.getTotalCpuPercent() + "%"); 2059 2060 // Slog the cpu usage if the property is set. 2061 if ("true".equals(SystemProperties.get("events.cpu"))) { 2062 int user = mProcessCpuTracker.getLastUserTime(); 2063 int system = mProcessCpuTracker.getLastSystemTime(); 2064 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2065 int irq = mProcessCpuTracker.getLastIrqTime(); 2066 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2067 int idle = mProcessCpuTracker.getLastIdleTime(); 2068 2069 int total = user + system + iowait + irq + softIrq + idle; 2070 if (total == 0) total = 1; 2071 2072 EventLog.writeEvent(EventLogTags.CPU, 2073 ((user+system+iowait+irq+softIrq) * 100) / total, 2074 (user * 100) / total, 2075 (system * 100) / total, 2076 (iowait * 100) / total, 2077 (irq * 100) / total, 2078 (softIrq * 100) / total); 2079 } 2080 } 2081 2082 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2083 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2084 synchronized(bstats) { 2085 synchronized(mPidsSelfLocked) { 2086 if (haveNewCpuStats) { 2087 if (mOnBattery) { 2088 int perc = bstats.startAddingCpuLocked(); 2089 int totalUTime = 0; 2090 int totalSTime = 0; 2091 final int N = mProcessCpuTracker.countStats(); 2092 for (int i=0; i<N; i++) { 2093 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2094 if (!st.working) { 2095 continue; 2096 } 2097 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2098 int otherUTime = (st.rel_utime*perc)/100; 2099 int otherSTime = (st.rel_stime*perc)/100; 2100 totalUTime += otherUTime; 2101 totalSTime += otherSTime; 2102 if (pr != null) { 2103 BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked( 2104 st.name, st.pid); 2105 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2106 st.rel_stime-otherSTime); 2107 ps.addSpeedStepTimes(cpuSpeedTimes); 2108 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2109 } else if (st.uid >= Process.FIRST_APPLICATION_UID) { 2110 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2111 if (ps == null) { 2112 st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid, 2113 "(Unknown)"); 2114 } 2115 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2116 st.rel_stime-otherSTime); 2117 ps.addSpeedStepTimes(cpuSpeedTimes); 2118 } else { 2119 BatteryStatsImpl.Uid.Proc ps = 2120 bstats.getProcessStatsLocked(st.name, st.pid); 2121 if (ps != null) { 2122 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2123 st.rel_stime-otherSTime); 2124 ps.addSpeedStepTimes(cpuSpeedTimes); 2125 } 2126 } 2127 } 2128 bstats.finishAddingCpuLocked(perc, totalUTime, 2129 totalSTime, cpuSpeedTimes); 2130 } 2131 } 2132 } 2133 2134 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2135 mLastWriteTime = now; 2136 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2137 } 2138 } 2139 } 2140 } 2141 2142 @Override 2143 public void batteryNeedsCpuUpdate() { 2144 updateCpuStatsNow(); 2145 } 2146 2147 @Override 2148 public void batteryPowerChanged(boolean onBattery) { 2149 // When plugging in, update the CPU stats first before changing 2150 // the plug state. 2151 updateCpuStatsNow(); 2152 synchronized (this) { 2153 synchronized(mPidsSelfLocked) { 2154 mOnBattery = DEBUG_POWER ? true : onBattery; 2155 } 2156 } 2157 } 2158 2159 /** 2160 * Initialize the application bind args. These are passed to each 2161 * process when the bindApplication() IPC is sent to the process. They're 2162 * lazily setup to make sure the services are running when they're asked for. 2163 */ 2164 private HashMap<String, IBinder> getCommonServicesLocked() { 2165 if (mAppBindArgs == null) { 2166 mAppBindArgs = new HashMap<String, IBinder>(); 2167 2168 // Setup the application init args 2169 mAppBindArgs.put("package", ServiceManager.getService("package")); 2170 mAppBindArgs.put("window", ServiceManager.getService("window")); 2171 mAppBindArgs.put(Context.ALARM_SERVICE, 2172 ServiceManager.getService(Context.ALARM_SERVICE)); 2173 } 2174 return mAppBindArgs; 2175 } 2176 2177 final void setFocusedActivityLocked(ActivityRecord r) { 2178 if (mFocusedActivity != r) { 2179 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2180 mFocusedActivity = r; 2181 mStackSupervisor.setFocusedStack(r); 2182 if (r != null) { 2183 mWindowManager.setFocusedApp(r.appToken, true); 2184 } 2185 applyUpdateLockStateLocked(r); 2186 } 2187 } 2188 2189 @Override 2190 public void setFocusedStack(int stackId) { 2191 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2192 synchronized (ActivityManagerService.this) { 2193 ActivityStack stack = mStackSupervisor.getStack(stackId); 2194 if (stack != null) { 2195 ActivityRecord r = stack.topRunningActivityLocked(null); 2196 if (r != null) { 2197 setFocusedActivityLocked(r); 2198 } 2199 } 2200 } 2201 } 2202 2203 @Override 2204 public void notifyActivityDrawn(IBinder token) { 2205 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2206 synchronized (this) { 2207 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2208 if (r != null) { 2209 r.task.stack.notifyActivityDrawnLocked(r); 2210 } 2211 } 2212 } 2213 2214 final void applyUpdateLockStateLocked(ActivityRecord r) { 2215 // Modifications to the UpdateLock state are done on our handler, outside 2216 // the activity manager's locks. The new state is determined based on the 2217 // state *now* of the relevant activity record. The object is passed to 2218 // the handler solely for logging detail, not to be consulted/modified. 2219 final boolean nextState = r != null && r.immersive; 2220 mHandler.sendMessage( 2221 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2222 } 2223 2224 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2225 Message msg = Message.obtain(); 2226 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2227 msg.obj = r.task.askedCompatMode ? null : r; 2228 mHandler.sendMessage(msg); 2229 } 2230 2231 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2232 String what, Object obj, ProcessRecord srcApp) { 2233 app.lastActivityTime = now; 2234 2235 if (app.activities.size() > 0) { 2236 // Don't want to touch dependent processes that are hosting activities. 2237 return index; 2238 } 2239 2240 int lrui = mLruProcesses.lastIndexOf(app); 2241 if (lrui < 0) { 2242 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2243 + what + " " + obj + " from " + srcApp); 2244 return index; 2245 } 2246 2247 if (lrui >= index) { 2248 // Don't want to cause this to move dependent processes *back* in the 2249 // list as if they were less frequently used. 2250 return index; 2251 } 2252 2253 if (lrui >= mLruProcessActivityStart) { 2254 // Don't want to touch dependent processes that are hosting activities. 2255 return index; 2256 } 2257 2258 mLruProcesses.remove(lrui); 2259 if (index > 0) { 2260 index--; 2261 } 2262 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2263 + " in LRU list: " + app); 2264 mLruProcesses.add(index, app); 2265 return index; 2266 } 2267 2268 final void removeLruProcessLocked(ProcessRecord app) { 2269 int lrui = mLruProcesses.lastIndexOf(app); 2270 if (lrui >= 0) { 2271 if (lrui <= mLruProcessActivityStart) { 2272 mLruProcessActivityStart--; 2273 } 2274 if (lrui <= mLruProcessServiceStart) { 2275 mLruProcessServiceStart--; 2276 } 2277 mLruProcesses.remove(lrui); 2278 } 2279 } 2280 2281 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2282 ProcessRecord client) { 2283 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities; 2284 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2285 if (!activityChange && hasActivity) { 2286 // The process has activties, so we are only going to allow activity-based 2287 // adjustments move it. It should be kept in the front of the list with other 2288 // processes that have activities, and we don't want those to change their 2289 // order except due to activity operations. 2290 return; 2291 } 2292 2293 mLruSeq++; 2294 final long now = SystemClock.uptimeMillis(); 2295 app.lastActivityTime = now; 2296 2297 // First a quick reject: if the app is already at the position we will 2298 // put it, then there is nothing to do. 2299 if (hasActivity) { 2300 final int N = mLruProcesses.size(); 2301 if (N > 0 && mLruProcesses.get(N-1) == app) { 2302 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2303 return; 2304 } 2305 } else { 2306 if (mLruProcessServiceStart > 0 2307 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2308 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2309 return; 2310 } 2311 } 2312 2313 int lrui = mLruProcesses.lastIndexOf(app); 2314 2315 if (app.persistent && lrui >= 0) { 2316 // We don't care about the position of persistent processes, as long as 2317 // they are in the list. 2318 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2319 return; 2320 } 2321 2322 /* In progress: compute new position first, so we can avoid doing work 2323 if the process is not actually going to move. Not yet working. 2324 int addIndex; 2325 int nextIndex; 2326 boolean inActivity = false, inService = false; 2327 if (hasActivity) { 2328 // Process has activities, put it at the very tipsy-top. 2329 addIndex = mLruProcesses.size(); 2330 nextIndex = mLruProcessServiceStart; 2331 inActivity = true; 2332 } else if (hasService) { 2333 // Process has services, put it at the top of the service list. 2334 addIndex = mLruProcessActivityStart; 2335 nextIndex = mLruProcessServiceStart; 2336 inActivity = true; 2337 inService = true; 2338 } else { 2339 // Process not otherwise of interest, it goes to the top of the non-service area. 2340 addIndex = mLruProcessServiceStart; 2341 if (client != null) { 2342 int clientIndex = mLruProcesses.lastIndexOf(client); 2343 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2344 + app); 2345 if (clientIndex >= 0 && addIndex > clientIndex) { 2346 addIndex = clientIndex; 2347 } 2348 } 2349 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2350 } 2351 2352 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2353 + mLruProcessActivityStart + "): " + app); 2354 */ 2355 2356 if (lrui >= 0) { 2357 if (lrui < mLruProcessActivityStart) { 2358 mLruProcessActivityStart--; 2359 } 2360 if (lrui < mLruProcessServiceStart) { 2361 mLruProcessServiceStart--; 2362 } 2363 /* 2364 if (addIndex > lrui) { 2365 addIndex--; 2366 } 2367 if (nextIndex > lrui) { 2368 nextIndex--; 2369 } 2370 */ 2371 mLruProcesses.remove(lrui); 2372 } 2373 2374 /* 2375 mLruProcesses.add(addIndex, app); 2376 if (inActivity) { 2377 mLruProcessActivityStart++; 2378 } 2379 if (inService) { 2380 mLruProcessActivityStart++; 2381 } 2382 */ 2383 2384 int nextIndex; 2385 if (hasActivity) { 2386 final int N = mLruProcesses.size(); 2387 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2388 // Process doesn't have activities, but has clients with 2389 // activities... move it up, but one below the top (the top 2390 // should always have a real activity). 2391 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2392 mLruProcesses.add(N-1, app); 2393 // To keep it from spamming the LRU list (by making a bunch of clients), 2394 // we will push down any other entries owned by the app. 2395 final int uid = app.info.uid; 2396 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2397 ProcessRecord subProc = mLruProcesses.get(i); 2398 if (subProc.info.uid == uid) { 2399 // We want to push this one down the list. If the process after 2400 // it is for the same uid, however, don't do so, because we don't 2401 // want them internally to be re-ordered. 2402 if (mLruProcesses.get(i-1).info.uid != uid) { 2403 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2404 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2405 ProcessRecord tmp = mLruProcesses.get(i); 2406 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2407 mLruProcesses.set(i-1, tmp); 2408 i--; 2409 } 2410 } else { 2411 // A gap, we can stop here. 2412 break; 2413 } 2414 } 2415 } else { 2416 // Process has activities, put it at the very tipsy-top. 2417 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2418 mLruProcesses.add(app); 2419 } 2420 nextIndex = mLruProcessServiceStart; 2421 } else if (hasService) { 2422 // Process has services, put it at the top of the service list. 2423 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2424 mLruProcesses.add(mLruProcessActivityStart, app); 2425 nextIndex = mLruProcessServiceStart; 2426 mLruProcessActivityStart++; 2427 } else { 2428 // Process not otherwise of interest, it goes to the top of the non-service area. 2429 int index = mLruProcessServiceStart; 2430 if (client != null) { 2431 // If there is a client, don't allow the process to be moved up higher 2432 // in the list than that client. 2433 int clientIndex = mLruProcesses.lastIndexOf(client); 2434 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2435 + " when updating " + app); 2436 if (clientIndex <= lrui) { 2437 // Don't allow the client index restriction to push it down farther in the 2438 // list than it already is. 2439 clientIndex = lrui; 2440 } 2441 if (clientIndex >= 0 && index > clientIndex) { 2442 index = clientIndex; 2443 } 2444 } 2445 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2446 mLruProcesses.add(index, app); 2447 nextIndex = index-1; 2448 mLruProcessActivityStart++; 2449 mLruProcessServiceStart++; 2450 } 2451 2452 // If the app is currently using a content provider or service, 2453 // bump those processes as well. 2454 for (int j=app.connections.size()-1; j>=0; j--) { 2455 ConnectionRecord cr = app.connections.valueAt(j); 2456 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2457 && cr.binding.service.app != null 2458 && cr.binding.service.app.lruSeq != mLruSeq 2459 && !cr.binding.service.app.persistent) { 2460 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2461 "service connection", cr, app); 2462 } 2463 } 2464 for (int j=app.conProviders.size()-1; j>=0; j--) { 2465 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2466 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2467 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2468 "provider reference", cpr, app); 2469 } 2470 } 2471 } 2472 2473 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2474 if (uid == Process.SYSTEM_UID) { 2475 // The system gets to run in any process. If there are multiple 2476 // processes with the same uid, just pick the first (this 2477 // should never happen). 2478 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2479 if (procs == null) return null; 2480 final int N = procs.size(); 2481 for (int i = 0; i < N; i++) { 2482 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2483 } 2484 } 2485 ProcessRecord proc = mProcessNames.get(processName, uid); 2486 if (false && proc != null && !keepIfLarge 2487 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2488 && proc.lastCachedPss >= 4000) { 2489 // Turn this condition on to cause killing to happen regularly, for testing. 2490 if (proc.baseProcessTracker != null) { 2491 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2492 } 2493 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2494 + "k from cached"); 2495 } else if (proc != null && !keepIfLarge 2496 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2497 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2498 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2499 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2500 if (proc.baseProcessTracker != null) { 2501 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2502 } 2503 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2504 + "k from cached"); 2505 } 2506 } 2507 return proc; 2508 } 2509 2510 void ensurePackageDexOpt(String packageName) { 2511 IPackageManager pm = AppGlobals.getPackageManager(); 2512 try { 2513 if (pm.performDexOpt(packageName)) { 2514 mDidDexOpt = true; 2515 } 2516 } catch (RemoteException e) { 2517 } 2518 } 2519 2520 boolean isNextTransitionForward() { 2521 int transit = mWindowManager.getPendingAppTransition(); 2522 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2523 || transit == AppTransition.TRANSIT_TASK_OPEN 2524 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2525 } 2526 2527 final ProcessRecord startProcessLocked(String processName, 2528 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2529 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2530 boolean isolated, boolean keepIfLarge) { 2531 ProcessRecord app; 2532 if (!isolated) { 2533 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2534 } else { 2535 // If this is an isolated process, it can't re-use an existing process. 2536 app = null; 2537 } 2538 // We don't have to do anything more if: 2539 // (1) There is an existing application record; and 2540 // (2) The caller doesn't think it is dead, OR there is no thread 2541 // object attached to it so we know it couldn't have crashed; and 2542 // (3) There is a pid assigned to it, so it is either starting or 2543 // already running. 2544 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2545 + " app=" + app + " knownToBeDead=" + knownToBeDead 2546 + " thread=" + (app != null ? app.thread : null) 2547 + " pid=" + (app != null ? app.pid : -1)); 2548 if (app != null && app.pid > 0) { 2549 if (!knownToBeDead || app.thread == null) { 2550 // We already have the app running, or are waiting for it to 2551 // come up (we have a pid but not yet its thread), so keep it. 2552 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2553 // If this is a new package in the process, add the package to the list 2554 app.addPackage(info.packageName, mProcessStats); 2555 return app; 2556 } 2557 2558 // An application record is attached to a previous process, 2559 // clean it up now. 2560 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2561 handleAppDiedLocked(app, true, true); 2562 } 2563 2564 String hostingNameStr = hostingName != null 2565 ? hostingName.flattenToShortString() : null; 2566 2567 if (!isolated) { 2568 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2569 // If we are in the background, then check to see if this process 2570 // is bad. If so, we will just silently fail. 2571 if (mBadProcesses.get(info.processName, info.uid) != null) { 2572 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2573 + "/" + info.processName); 2574 return null; 2575 } 2576 } else { 2577 // When the user is explicitly starting a process, then clear its 2578 // crash count so that we won't make it bad until they see at 2579 // least one crash dialog again, and make the process good again 2580 // if it had been bad. 2581 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2582 + "/" + info.processName); 2583 mProcessCrashTimes.remove(info.processName, info.uid); 2584 if (mBadProcesses.get(info.processName, info.uid) != null) { 2585 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2586 UserHandle.getUserId(info.uid), info.uid, 2587 info.processName); 2588 mBadProcesses.remove(info.processName, info.uid); 2589 if (app != null) { 2590 app.bad = false; 2591 } 2592 } 2593 } 2594 } 2595 2596 if (app == null) { 2597 app = newProcessRecordLocked(info, processName, isolated); 2598 if (app == null) { 2599 Slog.w(TAG, "Failed making new process record for " 2600 + processName + "/" + info.uid + " isolated=" + isolated); 2601 return null; 2602 } 2603 mProcessNames.put(processName, app.uid, app); 2604 if (isolated) { 2605 mIsolatedProcesses.put(app.uid, app); 2606 } 2607 } else { 2608 // If this is a new package in the process, add the package to the list 2609 app.addPackage(info.packageName, mProcessStats); 2610 } 2611 2612 // If the system is not ready yet, then hold off on starting this 2613 // process until it is. 2614 if (!mProcessesReady 2615 && !isAllowedWhileBooting(info) 2616 && !allowWhileBooting) { 2617 if (!mProcessesOnHold.contains(app)) { 2618 mProcessesOnHold.add(app); 2619 } 2620 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2621 return app; 2622 } 2623 2624 startProcessLocked(app, hostingType, hostingNameStr); 2625 return (app.pid != 0) ? app : null; 2626 } 2627 2628 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2629 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2630 } 2631 2632 private final void startProcessLocked(ProcessRecord app, 2633 String hostingType, String hostingNameStr) { 2634 if (app.pid > 0 && app.pid != MY_PID) { 2635 synchronized (mPidsSelfLocked) { 2636 mPidsSelfLocked.remove(app.pid); 2637 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2638 } 2639 app.setPid(0); 2640 } 2641 2642 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2643 "startProcessLocked removing on hold: " + app); 2644 mProcessesOnHold.remove(app); 2645 2646 updateCpuStats(); 2647 2648 try { 2649 int uid = app.uid; 2650 2651 int[] gids = null; 2652 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2653 if (!app.isolated) { 2654 int[] permGids = null; 2655 try { 2656 final PackageManager pm = mContext.getPackageManager(); 2657 permGids = pm.getPackageGids(app.info.packageName); 2658 2659 if (Environment.isExternalStorageEmulated()) { 2660 if (pm.checkPermission( 2661 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2662 app.info.packageName) == PERMISSION_GRANTED) { 2663 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2664 } else { 2665 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2666 } 2667 } 2668 } catch (PackageManager.NameNotFoundException e) { 2669 Slog.w(TAG, "Unable to retrieve gids", e); 2670 } 2671 2672 /* 2673 * Add shared application GID so applications can share some 2674 * resources like shared libraries 2675 */ 2676 if (permGids == null) { 2677 gids = new int[1]; 2678 } else { 2679 gids = new int[permGids.length + 1]; 2680 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2681 } 2682 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2683 } 2684 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2685 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2686 && mTopComponent != null 2687 && app.processName.equals(mTopComponent.getPackageName())) { 2688 uid = 0; 2689 } 2690 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2691 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2692 uid = 0; 2693 } 2694 } 2695 int debugFlags = 0; 2696 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2697 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2698 // Also turn on CheckJNI for debuggable apps. It's quite 2699 // awkward to turn on otherwise. 2700 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2701 } 2702 // Run the app in safe mode if its manifest requests so or the 2703 // system is booted in safe mode. 2704 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2705 Zygote.systemInSafeMode == true) { 2706 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2707 } 2708 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2709 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2710 } 2711 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2712 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2713 } 2714 if ("1".equals(SystemProperties.get("debug.assert"))) { 2715 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2716 } 2717 2718 // Start the process. It will either succeed and return a result containing 2719 // the PID of the new process, or else throw a RuntimeException. 2720 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2721 app.processName, uid, uid, gids, debugFlags, mountExternal, 2722 app.info.targetSdkVersion, app.info.seinfo, null); 2723 2724 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2725 synchronized (bs) { 2726 if (bs.isOnBattery()) { 2727 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2728 } 2729 } 2730 2731 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2732 UserHandle.getUserId(uid), startResult.pid, uid, 2733 app.processName, hostingType, 2734 hostingNameStr != null ? hostingNameStr : ""); 2735 2736 if (app.persistent) { 2737 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2738 } 2739 2740 StringBuilder buf = mStringBuilder; 2741 buf.setLength(0); 2742 buf.append("Start proc "); 2743 buf.append(app.processName); 2744 buf.append(" for "); 2745 buf.append(hostingType); 2746 if (hostingNameStr != null) { 2747 buf.append(" "); 2748 buf.append(hostingNameStr); 2749 } 2750 buf.append(": pid="); 2751 buf.append(startResult.pid); 2752 buf.append(" uid="); 2753 buf.append(uid); 2754 buf.append(" gids={"); 2755 if (gids != null) { 2756 for (int gi=0; gi<gids.length; gi++) { 2757 if (gi != 0) buf.append(", "); 2758 buf.append(gids[gi]); 2759 2760 } 2761 } 2762 buf.append("}"); 2763 Slog.i(TAG, buf.toString()); 2764 app.setPid(startResult.pid); 2765 app.usingWrapper = startResult.usingWrapper; 2766 app.removed = false; 2767 synchronized (mPidsSelfLocked) { 2768 this.mPidsSelfLocked.put(startResult.pid, app); 2769 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2770 msg.obj = app; 2771 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2772 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2773 } 2774 } catch (RuntimeException e) { 2775 // XXX do better error recovery. 2776 app.setPid(0); 2777 Slog.e(TAG, "Failure starting process " + app.processName, e); 2778 } 2779 } 2780 2781 void updateUsageStats(ActivityRecord component, boolean resumed) { 2782 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2783 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2784 if (resumed) { 2785 mUsageStatsService.noteResumeComponent(component.realActivity); 2786 synchronized (stats) { 2787 stats.noteActivityResumedLocked(component.app.uid); 2788 } 2789 } else { 2790 mUsageStatsService.notePauseComponent(component.realActivity); 2791 synchronized (stats) { 2792 stats.noteActivityPausedLocked(component.app.uid); 2793 } 2794 } 2795 } 2796 2797 Intent getHomeIntent() { 2798 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2799 intent.setComponent(mTopComponent); 2800 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2801 intent.addCategory(Intent.CATEGORY_HOME); 2802 } 2803 return intent; 2804 } 2805 2806 boolean startHomeActivityLocked(int userId) { 2807 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2808 && mTopAction == null) { 2809 // We are running in factory test mode, but unable to find 2810 // the factory test app, so just sit around displaying the 2811 // error message and don't try to start anything. 2812 return false; 2813 } 2814 Intent intent = getHomeIntent(); 2815 ActivityInfo aInfo = 2816 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2817 if (aInfo != null) { 2818 intent.setComponent(new ComponentName( 2819 aInfo.applicationInfo.packageName, aInfo.name)); 2820 // Don't do this if the home app is currently being 2821 // instrumented. 2822 aInfo = new ActivityInfo(aInfo); 2823 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2824 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2825 aInfo.applicationInfo.uid, true); 2826 if (app == null || app.instrumentationClass == null) { 2827 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2828 mStackSupervisor.startHomeActivity(intent, aInfo); 2829 } 2830 } 2831 2832 return true; 2833 } 2834 2835 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2836 ActivityInfo ai = null; 2837 ComponentName comp = intent.getComponent(); 2838 try { 2839 if (comp != null) { 2840 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2841 } else { 2842 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2843 intent, 2844 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2845 flags, userId); 2846 2847 if (info != null) { 2848 ai = info.activityInfo; 2849 } 2850 } 2851 } catch (RemoteException e) { 2852 // ignore 2853 } 2854 2855 return ai; 2856 } 2857 2858 /** 2859 * Starts the "new version setup screen" if appropriate. 2860 */ 2861 void startSetupActivityLocked() { 2862 // Only do this once per boot. 2863 if (mCheckedForSetup) { 2864 return; 2865 } 2866 2867 // We will show this screen if the current one is a different 2868 // version than the last one shown, and we are not running in 2869 // low-level factory test mode. 2870 final ContentResolver resolver = mContext.getContentResolver(); 2871 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2872 Settings.Global.getInt(resolver, 2873 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2874 mCheckedForSetup = true; 2875 2876 // See if we should be showing the platform update setup UI. 2877 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2878 List<ResolveInfo> ris = mContext.getPackageManager() 2879 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2880 2881 // We don't allow third party apps to replace this. 2882 ResolveInfo ri = null; 2883 for (int i=0; ris != null && i<ris.size(); i++) { 2884 if ((ris.get(i).activityInfo.applicationInfo.flags 2885 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2886 ri = ris.get(i); 2887 break; 2888 } 2889 } 2890 2891 if (ri != null) { 2892 String vers = ri.activityInfo.metaData != null 2893 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2894 : null; 2895 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2896 vers = ri.activityInfo.applicationInfo.metaData.getString( 2897 Intent.METADATA_SETUP_VERSION); 2898 } 2899 String lastVers = Settings.Secure.getString( 2900 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2901 if (vers != null && !vers.equals(lastVers)) { 2902 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2903 intent.setComponent(new ComponentName( 2904 ri.activityInfo.packageName, ri.activityInfo.name)); 2905 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2906 null, null, 0, 0, 0, null, 0, null, false, null, null); 2907 } 2908 } 2909 } 2910 } 2911 2912 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2913 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2914 } 2915 2916 void enforceNotIsolatedCaller(String caller) { 2917 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2918 throw new SecurityException("Isolated process not allowed to call " + caller); 2919 } 2920 } 2921 2922 @Override 2923 public int getFrontActivityScreenCompatMode() { 2924 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2925 synchronized (this) { 2926 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2927 } 2928 } 2929 2930 @Override 2931 public void setFrontActivityScreenCompatMode(int mode) { 2932 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2933 "setFrontActivityScreenCompatMode"); 2934 synchronized (this) { 2935 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2936 } 2937 } 2938 2939 @Override 2940 public int getPackageScreenCompatMode(String packageName) { 2941 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2942 synchronized (this) { 2943 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2944 } 2945 } 2946 2947 @Override 2948 public void setPackageScreenCompatMode(String packageName, int mode) { 2949 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2950 "setPackageScreenCompatMode"); 2951 synchronized (this) { 2952 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2953 } 2954 } 2955 2956 @Override 2957 public boolean getPackageAskScreenCompat(String packageName) { 2958 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2959 synchronized (this) { 2960 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2961 } 2962 } 2963 2964 @Override 2965 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2966 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2967 "setPackageAskScreenCompat"); 2968 synchronized (this) { 2969 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2970 } 2971 } 2972 2973 private void dispatchProcessesChanged() { 2974 int N; 2975 synchronized (this) { 2976 N = mPendingProcessChanges.size(); 2977 if (mActiveProcessChanges.length < N) { 2978 mActiveProcessChanges = new ProcessChangeItem[N]; 2979 } 2980 mPendingProcessChanges.toArray(mActiveProcessChanges); 2981 mAvailProcessChanges.addAll(mPendingProcessChanges); 2982 mPendingProcessChanges.clear(); 2983 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2984 } 2985 2986 int i = mProcessObservers.beginBroadcast(); 2987 while (i > 0) { 2988 i--; 2989 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2990 if (observer != null) { 2991 try { 2992 for (int j=0; j<N; j++) { 2993 ProcessChangeItem item = mActiveProcessChanges[j]; 2994 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2995 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2996 + item.pid + " uid=" + item.uid + ": " 2997 + item.foregroundActivities); 2998 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2999 item.foregroundActivities); 3000 } 3001 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3002 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3003 + item.pid + " uid=" + item.uid + ": " + item.importance); 3004 observer.onImportanceChanged(item.pid, item.uid, 3005 item.importance); 3006 } 3007 } 3008 } catch (RemoteException e) { 3009 } 3010 } 3011 } 3012 mProcessObservers.finishBroadcast(); 3013 } 3014 3015 private void dispatchProcessDied(int pid, int uid) { 3016 int i = mProcessObservers.beginBroadcast(); 3017 while (i > 0) { 3018 i--; 3019 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3020 if (observer != null) { 3021 try { 3022 observer.onProcessDied(pid, uid); 3023 } catch (RemoteException e) { 3024 } 3025 } 3026 } 3027 mProcessObservers.finishBroadcast(); 3028 } 3029 3030 final void doPendingActivityLaunchesLocked(boolean doResume) { 3031 final int N = mPendingActivityLaunches.size(); 3032 if (N <= 0) { 3033 return; 3034 } 3035 for (int i=0; i<N; i++) { 3036 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3037 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3038 doResume && i == (N-1), null); 3039 } 3040 mPendingActivityLaunches.clear(); 3041 } 3042 3043 @Override 3044 public final int startActivity(IApplicationThread caller, String callingPackage, 3045 Intent intent, String resolvedType, IBinder resultTo, 3046 String resultWho, int requestCode, int startFlags, 3047 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3048 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3049 resultWho, requestCode, 3050 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3051 } 3052 3053 @Override 3054 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3055 Intent intent, String resolvedType, IBinder resultTo, 3056 String resultWho, int requestCode, int startFlags, 3057 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3058 enforceNotIsolatedCaller("startActivity"); 3059 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3060 false, true, "startActivity", null); 3061 // TODO: Switch to user app stacks here. 3062 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3063 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3064 null, null, options, userId, null); 3065 } 3066 3067 @Override 3068 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3069 Intent intent, String resolvedType, IBinder resultTo, 3070 String resultWho, int requestCode, int startFlags, String profileFile, 3071 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3072 enforceNotIsolatedCaller("startActivityAndWait"); 3073 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3074 false, true, "startActivityAndWait", null); 3075 WaitResult res = new WaitResult(); 3076 // TODO: Switch to user app stacks here. 3077 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3078 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3079 res, null, options, UserHandle.getCallingUserId(), null); 3080 return res; 3081 } 3082 3083 @Override 3084 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3085 Intent intent, String resolvedType, IBinder resultTo, 3086 String resultWho, int requestCode, int startFlags, Configuration config, 3087 Bundle options, int userId) { 3088 enforceNotIsolatedCaller("startActivityWithConfig"); 3089 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3090 false, true, "startActivityWithConfig", null); 3091 // TODO: Switch to user app stacks here. 3092 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3093 resolvedType, resultTo, resultWho, requestCode, startFlags, 3094 null, null, null, config, options, userId, null); 3095 return ret; 3096 } 3097 3098 @Override 3099 public int startActivityIntentSender(IApplicationThread caller, 3100 IntentSender intent, Intent fillInIntent, String resolvedType, 3101 IBinder resultTo, String resultWho, int requestCode, 3102 int flagsMask, int flagsValues, Bundle options) { 3103 enforceNotIsolatedCaller("startActivityIntentSender"); 3104 // Refuse possible leaked file descriptors 3105 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3106 throw new IllegalArgumentException("File descriptors passed in Intent"); 3107 } 3108 3109 IIntentSender sender = intent.getTarget(); 3110 if (!(sender instanceof PendingIntentRecord)) { 3111 throw new IllegalArgumentException("Bad PendingIntent object"); 3112 } 3113 3114 PendingIntentRecord pir = (PendingIntentRecord)sender; 3115 3116 synchronized (this) { 3117 // If this is coming from the currently resumed activity, it is 3118 // effectively saying that app switches are allowed at this point. 3119 final ActivityStack stack = getFocusedStack(); 3120 if (stack.mResumedActivity != null && 3121 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3122 mAppSwitchesAllowedTime = 0; 3123 } 3124 } 3125 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3126 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3127 return ret; 3128 } 3129 3130 @Override 3131 public boolean startNextMatchingActivity(IBinder callingActivity, 3132 Intent intent, Bundle options) { 3133 // Refuse possible leaked file descriptors 3134 if (intent != null && intent.hasFileDescriptors() == true) { 3135 throw new IllegalArgumentException("File descriptors passed in Intent"); 3136 } 3137 3138 synchronized (this) { 3139 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3140 if (r == null) { 3141 ActivityOptions.abort(options); 3142 return false; 3143 } 3144 if (r.app == null || r.app.thread == null) { 3145 // The caller is not running... d'oh! 3146 ActivityOptions.abort(options); 3147 return false; 3148 } 3149 intent = new Intent(intent); 3150 // The caller is not allowed to change the data. 3151 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3152 // And we are resetting to find the next component... 3153 intent.setComponent(null); 3154 3155 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3156 3157 ActivityInfo aInfo = null; 3158 try { 3159 List<ResolveInfo> resolves = 3160 AppGlobals.getPackageManager().queryIntentActivities( 3161 intent, r.resolvedType, 3162 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3163 UserHandle.getCallingUserId()); 3164 3165 // Look for the original activity in the list... 3166 final int N = resolves != null ? resolves.size() : 0; 3167 for (int i=0; i<N; i++) { 3168 ResolveInfo rInfo = resolves.get(i); 3169 if (rInfo.activityInfo.packageName.equals(r.packageName) 3170 && rInfo.activityInfo.name.equals(r.info.name)) { 3171 // We found the current one... the next matching is 3172 // after it. 3173 i++; 3174 if (i<N) { 3175 aInfo = resolves.get(i).activityInfo; 3176 } 3177 if (debug) { 3178 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3179 + "/" + r.info.name); 3180 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3181 + "/" + aInfo.name); 3182 } 3183 break; 3184 } 3185 } 3186 } catch (RemoteException e) { 3187 } 3188 3189 if (aInfo == null) { 3190 // Nobody who is next! 3191 ActivityOptions.abort(options); 3192 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3193 return false; 3194 } 3195 3196 intent.setComponent(new ComponentName( 3197 aInfo.applicationInfo.packageName, aInfo.name)); 3198 intent.setFlags(intent.getFlags()&~( 3199 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3200 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3201 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3202 Intent.FLAG_ACTIVITY_NEW_TASK)); 3203 3204 // Okay now we need to start the new activity, replacing the 3205 // currently running activity. This is a little tricky because 3206 // we want to start the new one as if the current one is finished, 3207 // but not finish the current one first so that there is no flicker. 3208 // And thus... 3209 final boolean wasFinishing = r.finishing; 3210 r.finishing = true; 3211 3212 // Propagate reply information over to the new activity. 3213 final ActivityRecord resultTo = r.resultTo; 3214 final String resultWho = r.resultWho; 3215 final int requestCode = r.requestCode; 3216 r.resultTo = null; 3217 if (resultTo != null) { 3218 resultTo.removeResultsLocked(r, resultWho, requestCode); 3219 } 3220 3221 final long origId = Binder.clearCallingIdentity(); 3222 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3223 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3224 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3225 options, false, null, null); 3226 Binder.restoreCallingIdentity(origId); 3227 3228 r.finishing = wasFinishing; 3229 if (res != ActivityManager.START_SUCCESS) { 3230 return false; 3231 } 3232 return true; 3233 } 3234 } 3235 3236 final int startActivityInPackage(int uid, String callingPackage, 3237 Intent intent, String resolvedType, IBinder resultTo, 3238 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3239 IActivityContainer container) { 3240 3241 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3242 false, true, "startActivityInPackage", null); 3243 3244 // TODO: Switch to user app stacks here. 3245 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3246 resultTo, resultWho, requestCode, startFlags, 3247 null, null, null, null, options, userId, container); 3248 return ret; 3249 } 3250 3251 @Override 3252 public final int startActivities(IApplicationThread caller, String callingPackage, 3253 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3254 int userId) { 3255 enforceNotIsolatedCaller("startActivities"); 3256 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3257 false, true, "startActivity", null); 3258 // TODO: Switch to user app stacks here. 3259 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3260 resolvedTypes, resultTo, options, userId); 3261 return ret; 3262 } 3263 3264 final int startActivitiesInPackage(int uid, String callingPackage, 3265 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3266 Bundle options, int userId) { 3267 3268 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3269 false, true, "startActivityInPackage", null); 3270 // TODO: Switch to user app stacks here. 3271 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3272 resultTo, options, userId); 3273 return ret; 3274 } 3275 3276 final void addRecentTaskLocked(TaskRecord task) { 3277 int N = mRecentTasks.size(); 3278 // Quick case: check if the top-most recent task is the same. 3279 if (N > 0 && mRecentTasks.get(0) == task) { 3280 return; 3281 } 3282 // Remove any existing entries that are the same kind of task. 3283 for (int i=0; i<N; i++) { 3284 TaskRecord tr = mRecentTasks.get(i); 3285 if (task.userId == tr.userId 3286 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 3287 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 3288 tr.disposeThumbnail(); 3289 mRecentTasks.remove(i); 3290 i--; 3291 N--; 3292 if (task.intent == null) { 3293 // If the new recent task we are adding is not fully 3294 // specified, then replace it with the existing recent task. 3295 task = tr; 3296 } 3297 } 3298 } 3299 if (N >= MAX_RECENT_TASKS) { 3300 mRecentTasks.remove(N-1).disposeThumbnail(); 3301 } 3302 mRecentTasks.add(0, task); 3303 } 3304 3305 @Override 3306 public void reportActivityFullyDrawn(IBinder token) { 3307 synchronized (this) { 3308 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3309 if (r == null) { 3310 return; 3311 } 3312 r.reportFullyDrawnLocked(); 3313 } 3314 } 3315 3316 @Override 3317 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3318 synchronized (this) { 3319 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3320 if (r == null) { 3321 return; 3322 } 3323 final long origId = Binder.clearCallingIdentity(); 3324 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3325 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3326 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3327 if (config != null) { 3328 r.frozenBeforeDestroy = true; 3329 if (!updateConfigurationLocked(config, r, false, false)) { 3330 mStackSupervisor.resumeTopActivitiesLocked(); 3331 } 3332 } 3333 Binder.restoreCallingIdentity(origId); 3334 } 3335 } 3336 3337 @Override 3338 public int getRequestedOrientation(IBinder token) { 3339 synchronized (this) { 3340 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3341 if (r == null) { 3342 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3343 } 3344 return mWindowManager.getAppOrientation(r.appToken); 3345 } 3346 } 3347 3348 /** 3349 * This is the internal entry point for handling Activity.finish(). 3350 * 3351 * @param token The Binder token referencing the Activity we want to finish. 3352 * @param resultCode Result code, if any, from this Activity. 3353 * @param resultData Result data (Intent), if any, from this Activity. 3354 * 3355 * @return Returns true if the activity successfully finished, or false if it is still running. 3356 */ 3357 @Override 3358 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3359 // Refuse possible leaked file descriptors 3360 if (resultData != null && resultData.hasFileDescriptors() == true) { 3361 throw new IllegalArgumentException("File descriptors passed in Intent"); 3362 } 3363 3364 synchronized(this) { 3365 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3366 if (r == null) { 3367 return true; 3368 } 3369 if (mController != null) { 3370 // Find the first activity that is not finishing. 3371 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3372 if (next != null) { 3373 // ask watcher if this is allowed 3374 boolean resumeOK = true; 3375 try { 3376 resumeOK = mController.activityResuming(next.packageName); 3377 } catch (RemoteException e) { 3378 mController = null; 3379 Watchdog.getInstance().setActivityController(null); 3380 } 3381 3382 if (!resumeOK) { 3383 return false; 3384 } 3385 } 3386 } 3387 final long origId = Binder.clearCallingIdentity(); 3388 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3389 resultData, "app-request", true); 3390 Binder.restoreCallingIdentity(origId); 3391 return res; 3392 } 3393 } 3394 3395 @Override 3396 public final void finishHeavyWeightApp() { 3397 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3398 != PackageManager.PERMISSION_GRANTED) { 3399 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3400 + Binder.getCallingPid() 3401 + ", uid=" + Binder.getCallingUid() 3402 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3403 Slog.w(TAG, msg); 3404 throw new SecurityException(msg); 3405 } 3406 3407 synchronized(this) { 3408 if (mHeavyWeightProcess == null) { 3409 return; 3410 } 3411 3412 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3413 mHeavyWeightProcess.activities); 3414 for (int i=0; i<activities.size(); i++) { 3415 ActivityRecord r = activities.get(i); 3416 if (!r.finishing) { 3417 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3418 null, "finish-heavy", true); 3419 } 3420 } 3421 3422 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3423 mHeavyWeightProcess.userId, 0)); 3424 mHeavyWeightProcess = null; 3425 } 3426 } 3427 3428 @Override 3429 public void crashApplication(int uid, int initialPid, String packageName, 3430 String message) { 3431 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3432 != PackageManager.PERMISSION_GRANTED) { 3433 String msg = "Permission Denial: crashApplication() from pid=" 3434 + Binder.getCallingPid() 3435 + ", uid=" + Binder.getCallingUid() 3436 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3437 Slog.w(TAG, msg); 3438 throw new SecurityException(msg); 3439 } 3440 3441 synchronized(this) { 3442 ProcessRecord proc = null; 3443 3444 // Figure out which process to kill. We don't trust that initialPid 3445 // still has any relation to current pids, so must scan through the 3446 // list. 3447 synchronized (mPidsSelfLocked) { 3448 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3449 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3450 if (p.uid != uid) { 3451 continue; 3452 } 3453 if (p.pid == initialPid) { 3454 proc = p; 3455 break; 3456 } 3457 if (p.pkgList.containsKey(packageName)) { 3458 proc = p; 3459 } 3460 } 3461 } 3462 3463 if (proc == null) { 3464 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3465 + " initialPid=" + initialPid 3466 + " packageName=" + packageName); 3467 return; 3468 } 3469 3470 if (proc.thread != null) { 3471 if (proc.pid == Process.myPid()) { 3472 Log.w(TAG, "crashApplication: trying to crash self!"); 3473 return; 3474 } 3475 long ident = Binder.clearCallingIdentity(); 3476 try { 3477 proc.thread.scheduleCrash(message); 3478 } catch (RemoteException e) { 3479 } 3480 Binder.restoreCallingIdentity(ident); 3481 } 3482 } 3483 } 3484 3485 @Override 3486 public final void finishSubActivity(IBinder token, String resultWho, 3487 int requestCode) { 3488 synchronized(this) { 3489 final long origId = Binder.clearCallingIdentity(); 3490 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3491 if (r != null) { 3492 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3493 } 3494 Binder.restoreCallingIdentity(origId); 3495 } 3496 } 3497 3498 @Override 3499 public boolean finishActivityAffinity(IBinder token) { 3500 synchronized(this) { 3501 final long origId = Binder.clearCallingIdentity(); 3502 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3503 boolean res = false; 3504 if (r != null) { 3505 res = r.task.stack.finishActivityAffinityLocked(r); 3506 } 3507 Binder.restoreCallingIdentity(origId); 3508 return res; 3509 } 3510 } 3511 3512 @Override 3513 public boolean willActivityBeVisible(IBinder token) { 3514 synchronized(this) { 3515 ActivityStack stack = ActivityRecord.getStackLocked(token); 3516 if (stack != null) { 3517 return stack.willActivityBeVisibleLocked(token); 3518 } 3519 return false; 3520 } 3521 } 3522 3523 @Override 3524 public void overridePendingTransition(IBinder token, String packageName, 3525 int enterAnim, int exitAnim) { 3526 synchronized(this) { 3527 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3528 if (self == null) { 3529 return; 3530 } 3531 3532 final long origId = Binder.clearCallingIdentity(); 3533 3534 if (self.state == ActivityState.RESUMED 3535 || self.state == ActivityState.PAUSING) { 3536 mWindowManager.overridePendingAppTransition(packageName, 3537 enterAnim, exitAnim, null); 3538 } 3539 3540 Binder.restoreCallingIdentity(origId); 3541 } 3542 } 3543 3544 /** 3545 * Main function for removing an existing process from the activity manager 3546 * as a result of that process going away. Clears out all connections 3547 * to the process. 3548 */ 3549 private final void handleAppDiedLocked(ProcessRecord app, 3550 boolean restarting, boolean allowRestart) { 3551 int pid = app.pid; 3552 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3553 if (!restarting) { 3554 removeLruProcessLocked(app); 3555 if (pid > 0) { 3556 ProcessList.remove(pid); 3557 } 3558 } 3559 3560 if (mProfileProc == app) { 3561 clearProfilerLocked(); 3562 } 3563 3564 // Remove this application's activities from active lists. 3565 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3566 3567 app.activities.clear(); 3568 3569 if (app.instrumentationClass != null) { 3570 Slog.w(TAG, "Crash of app " + app.processName 3571 + " running instrumentation " + app.instrumentationClass); 3572 Bundle info = new Bundle(); 3573 info.putString("shortMsg", "Process crashed."); 3574 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3575 } 3576 3577 if (!restarting) { 3578 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3579 // If there was nothing to resume, and we are not already 3580 // restarting this process, but there is a visible activity that 3581 // is hosted by the process... then make sure all visible 3582 // activities are running, taking care of restarting this 3583 // process. 3584 if (hasVisibleActivities) { 3585 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3586 } 3587 } 3588 } 3589 } 3590 3591 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3592 IBinder threadBinder = thread.asBinder(); 3593 // Find the application record. 3594 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3595 ProcessRecord rec = mLruProcesses.get(i); 3596 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3597 return i; 3598 } 3599 } 3600 return -1; 3601 } 3602 3603 final ProcessRecord getRecordForAppLocked( 3604 IApplicationThread thread) { 3605 if (thread == null) { 3606 return null; 3607 } 3608 3609 int appIndex = getLRURecordIndexForAppLocked(thread); 3610 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3611 } 3612 3613 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3614 // If there are no longer any background processes running, 3615 // and the app that died was not running instrumentation, 3616 // then tell everyone we are now low on memory. 3617 boolean haveBg = false; 3618 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3619 ProcessRecord rec = mLruProcesses.get(i); 3620 if (rec.thread != null 3621 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3622 haveBg = true; 3623 break; 3624 } 3625 } 3626 3627 if (!haveBg) { 3628 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3629 if (doReport) { 3630 long now = SystemClock.uptimeMillis(); 3631 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3632 doReport = false; 3633 } else { 3634 mLastMemUsageReportTime = now; 3635 } 3636 } 3637 final ArrayList<ProcessMemInfo> memInfos 3638 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3639 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3640 long now = SystemClock.uptimeMillis(); 3641 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3642 ProcessRecord rec = mLruProcesses.get(i); 3643 if (rec == dyingProc || rec.thread == null) { 3644 continue; 3645 } 3646 if (doReport) { 3647 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3648 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3649 } 3650 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3651 // The low memory report is overriding any current 3652 // state for a GC request. Make sure to do 3653 // heavy/important/visible/foreground processes first. 3654 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3655 rec.lastRequestedGc = 0; 3656 } else { 3657 rec.lastRequestedGc = rec.lastLowMemory; 3658 } 3659 rec.reportLowMemory = true; 3660 rec.lastLowMemory = now; 3661 mProcessesToGc.remove(rec); 3662 addProcessToGcListLocked(rec); 3663 } 3664 } 3665 if (doReport) { 3666 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3667 mHandler.sendMessage(msg); 3668 } 3669 scheduleAppGcsLocked(); 3670 } 3671 } 3672 3673 final void appDiedLocked(ProcessRecord app, int pid, 3674 IApplicationThread thread) { 3675 3676 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3677 synchronized (stats) { 3678 stats.noteProcessDiedLocked(app.info.uid, pid); 3679 } 3680 3681 // Clean up already done if the process has been re-started. 3682 if (app.pid == pid && app.thread != null && 3683 app.thread.asBinder() == thread.asBinder()) { 3684 boolean doLowMem = app.instrumentationClass == null; 3685 boolean doOomAdj = doLowMem; 3686 if (!app.killedByAm) { 3687 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3688 + ") has died."); 3689 mAllowLowerMemLevel = true; 3690 } else { 3691 // Note that we always want to do oom adj to update our state with the 3692 // new number of procs. 3693 mAllowLowerMemLevel = false; 3694 doLowMem = false; 3695 } 3696 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3697 if (DEBUG_CLEANUP) Slog.v( 3698 TAG, "Dying app: " + app + ", pid: " + pid 3699 + ", thread: " + thread.asBinder()); 3700 handleAppDiedLocked(app, false, true); 3701 3702 if (doOomAdj) { 3703 updateOomAdjLocked(); 3704 } 3705 if (doLowMem) { 3706 doLowMemReportIfNeededLocked(app); 3707 } 3708 } else if (app.pid != pid) { 3709 // A new process has already been started. 3710 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3711 + ") has died and restarted (pid " + app.pid + ")."); 3712 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3713 } else if (DEBUG_PROCESSES) { 3714 Slog.d(TAG, "Received spurious death notification for thread " 3715 + thread.asBinder()); 3716 } 3717 } 3718 3719 /** 3720 * If a stack trace dump file is configured, dump process stack traces. 3721 * @param clearTraces causes the dump file to be erased prior to the new 3722 * traces being written, if true; when false, the new traces will be 3723 * appended to any existing file content. 3724 * @param firstPids of dalvik VM processes to dump stack traces for first 3725 * @param lastPids of dalvik VM processes to dump stack traces for last 3726 * @param nativeProcs optional list of native process names to dump stack crawls 3727 * @return file containing stack traces, or null if no dump file is configured 3728 */ 3729 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3730 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3731 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3732 if (tracesPath == null || tracesPath.length() == 0) { 3733 return null; 3734 } 3735 3736 File tracesFile = new File(tracesPath); 3737 try { 3738 File tracesDir = tracesFile.getParentFile(); 3739 if (!tracesDir.exists()) { 3740 tracesFile.mkdirs(); 3741 if (!SELinux.restorecon(tracesDir)) { 3742 return null; 3743 } 3744 } 3745 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3746 3747 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3748 tracesFile.createNewFile(); 3749 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3750 } catch (IOException e) { 3751 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3752 return null; 3753 } 3754 3755 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3756 return tracesFile; 3757 } 3758 3759 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3760 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3761 // Use a FileObserver to detect when traces finish writing. 3762 // The order of traces is considered important to maintain for legibility. 3763 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3764 @Override 3765 public synchronized void onEvent(int event, String path) { notify(); } 3766 }; 3767 3768 try { 3769 observer.startWatching(); 3770 3771 // First collect all of the stacks of the most important pids. 3772 if (firstPids != null) { 3773 try { 3774 int num = firstPids.size(); 3775 for (int i = 0; i < num; i++) { 3776 synchronized (observer) { 3777 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3778 observer.wait(200); // Wait for write-close, give up after 200msec 3779 } 3780 } 3781 } catch (InterruptedException e) { 3782 Log.wtf(TAG, e); 3783 } 3784 } 3785 3786 // Next collect the stacks of the native pids 3787 if (nativeProcs != null) { 3788 int[] pids = Process.getPidsForCommands(nativeProcs); 3789 if (pids != null) { 3790 for (int pid : pids) { 3791 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3792 } 3793 } 3794 } 3795 3796 // Lastly, measure CPU usage. 3797 if (processCpuTracker != null) { 3798 processCpuTracker.init(); 3799 System.gc(); 3800 processCpuTracker.update(); 3801 try { 3802 synchronized (processCpuTracker) { 3803 processCpuTracker.wait(500); // measure over 1/2 second. 3804 } 3805 } catch (InterruptedException e) { 3806 } 3807 processCpuTracker.update(); 3808 3809 // We'll take the stack crawls of just the top apps using CPU. 3810 final int N = processCpuTracker.countWorkingStats(); 3811 int numProcs = 0; 3812 for (int i=0; i<N && numProcs<5; i++) { 3813 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3814 if (lastPids.indexOfKey(stats.pid) >= 0) { 3815 numProcs++; 3816 try { 3817 synchronized (observer) { 3818 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3819 observer.wait(200); // Wait for write-close, give up after 200msec 3820 } 3821 } catch (InterruptedException e) { 3822 Log.wtf(TAG, e); 3823 } 3824 3825 } 3826 } 3827 } 3828 } finally { 3829 observer.stopWatching(); 3830 } 3831 } 3832 3833 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3834 if (true || IS_USER_BUILD) { 3835 return; 3836 } 3837 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3838 if (tracesPath == null || tracesPath.length() == 0) { 3839 return; 3840 } 3841 3842 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3843 StrictMode.allowThreadDiskWrites(); 3844 try { 3845 final File tracesFile = new File(tracesPath); 3846 final File tracesDir = tracesFile.getParentFile(); 3847 final File tracesTmp = new File(tracesDir, "__tmp__"); 3848 try { 3849 if (!tracesDir.exists()) { 3850 tracesFile.mkdirs(); 3851 if (!SELinux.restorecon(tracesDir.getPath())) { 3852 return; 3853 } 3854 } 3855 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3856 3857 if (tracesFile.exists()) { 3858 tracesTmp.delete(); 3859 tracesFile.renameTo(tracesTmp); 3860 } 3861 StringBuilder sb = new StringBuilder(); 3862 Time tobj = new Time(); 3863 tobj.set(System.currentTimeMillis()); 3864 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3865 sb.append(": "); 3866 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3867 sb.append(" since "); 3868 sb.append(msg); 3869 FileOutputStream fos = new FileOutputStream(tracesFile); 3870 fos.write(sb.toString().getBytes()); 3871 if (app == null) { 3872 fos.write("\n*** No application process!".getBytes()); 3873 } 3874 fos.close(); 3875 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3876 } catch (IOException e) { 3877 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3878 return; 3879 } 3880 3881 if (app != null) { 3882 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3883 firstPids.add(app.pid); 3884 dumpStackTraces(tracesPath, firstPids, null, null, null); 3885 } 3886 3887 File lastTracesFile = null; 3888 File curTracesFile = null; 3889 for (int i=9; i>=0; i--) { 3890 String name = String.format(Locale.US, "slow%02d.txt", i); 3891 curTracesFile = new File(tracesDir, name); 3892 if (curTracesFile.exists()) { 3893 if (lastTracesFile != null) { 3894 curTracesFile.renameTo(lastTracesFile); 3895 } else { 3896 curTracesFile.delete(); 3897 } 3898 } 3899 lastTracesFile = curTracesFile; 3900 } 3901 tracesFile.renameTo(curTracesFile); 3902 if (tracesTmp.exists()) { 3903 tracesTmp.renameTo(tracesFile); 3904 } 3905 } finally { 3906 StrictMode.setThreadPolicy(oldPolicy); 3907 } 3908 } 3909 3910 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3911 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3912 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3913 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3914 3915 if (mController != null) { 3916 try { 3917 // 0 == continue, -1 = kill process immediately 3918 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3919 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3920 } catch (RemoteException e) { 3921 mController = null; 3922 Watchdog.getInstance().setActivityController(null); 3923 } 3924 } 3925 3926 long anrTime = SystemClock.uptimeMillis(); 3927 if (MONITOR_CPU_USAGE) { 3928 updateCpuStatsNow(); 3929 } 3930 3931 synchronized (this) { 3932 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3933 if (mShuttingDown) { 3934 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3935 return; 3936 } else if (app.notResponding) { 3937 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3938 return; 3939 } else if (app.crashing) { 3940 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3941 return; 3942 } 3943 3944 // In case we come through here for the same app before completing 3945 // this one, mark as anring now so we will bail out. 3946 app.notResponding = true; 3947 3948 // Log the ANR to the event log. 3949 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3950 app.processName, app.info.flags, annotation); 3951 3952 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3953 firstPids.add(app.pid); 3954 3955 int parentPid = app.pid; 3956 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3957 if (parentPid != app.pid) firstPids.add(parentPid); 3958 3959 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3960 3961 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3962 ProcessRecord r = mLruProcesses.get(i); 3963 if (r != null && r.thread != null) { 3964 int pid = r.pid; 3965 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3966 if (r.persistent) { 3967 firstPids.add(pid); 3968 } else { 3969 lastPids.put(pid, Boolean.TRUE); 3970 } 3971 } 3972 } 3973 } 3974 } 3975 3976 // Log the ANR to the main log. 3977 StringBuilder info = new StringBuilder(); 3978 info.setLength(0); 3979 info.append("ANR in ").append(app.processName); 3980 if (activity != null && activity.shortComponentName != null) { 3981 info.append(" (").append(activity.shortComponentName).append(")"); 3982 } 3983 info.append("\n"); 3984 info.append("PID: ").append(app.pid).append("\n"); 3985 if (annotation != null) { 3986 info.append("Reason: ").append(annotation).append("\n"); 3987 } 3988 if (parent != null && parent != activity) { 3989 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3990 } 3991 3992 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 3993 3994 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 3995 NATIVE_STACKS_OF_INTEREST); 3996 3997 String cpuInfo = null; 3998 if (MONITOR_CPU_USAGE) { 3999 updateCpuStatsNow(); 4000 synchronized (mProcessCpuThread) { 4001 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4002 } 4003 info.append(processCpuTracker.printCurrentLoad()); 4004 info.append(cpuInfo); 4005 } 4006 4007 info.append(processCpuTracker.printCurrentState(anrTime)); 4008 4009 Slog.e(TAG, info.toString()); 4010 if (tracesFile == null) { 4011 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4012 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4013 } 4014 4015 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4016 cpuInfo, tracesFile, null); 4017 4018 if (mController != null) { 4019 try { 4020 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4021 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4022 if (res != 0) { 4023 if (res < 0 && app.pid != MY_PID) { 4024 Process.killProcess(app.pid); 4025 } else { 4026 synchronized (this) { 4027 mServices.scheduleServiceTimeoutLocked(app); 4028 } 4029 } 4030 return; 4031 } 4032 } catch (RemoteException e) { 4033 mController = null; 4034 Watchdog.getInstance().setActivityController(null); 4035 } 4036 } 4037 4038 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4039 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4040 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4041 4042 synchronized (this) { 4043 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4044 killUnneededProcessLocked(app, "background ANR"); 4045 return; 4046 } 4047 4048 // Set the app's notResponding state, and look up the errorReportReceiver 4049 makeAppNotRespondingLocked(app, 4050 activity != null ? activity.shortComponentName : null, 4051 annotation != null ? "ANR " + annotation : "ANR", 4052 info.toString()); 4053 4054 // Bring up the infamous App Not Responding dialog 4055 Message msg = Message.obtain(); 4056 HashMap<String, Object> map = new HashMap<String, Object>(); 4057 msg.what = SHOW_NOT_RESPONDING_MSG; 4058 msg.obj = map; 4059 msg.arg1 = aboveSystem ? 1 : 0; 4060 map.put("app", app); 4061 if (activity != null) { 4062 map.put("activity", activity); 4063 } 4064 4065 mHandler.sendMessage(msg); 4066 } 4067 } 4068 4069 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4070 if (!mLaunchWarningShown) { 4071 mLaunchWarningShown = true; 4072 mHandler.post(new Runnable() { 4073 @Override 4074 public void run() { 4075 synchronized (ActivityManagerService.this) { 4076 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4077 d.show(); 4078 mHandler.postDelayed(new Runnable() { 4079 @Override 4080 public void run() { 4081 synchronized (ActivityManagerService.this) { 4082 d.dismiss(); 4083 mLaunchWarningShown = false; 4084 } 4085 } 4086 }, 4000); 4087 } 4088 } 4089 }); 4090 } 4091 } 4092 4093 @Override 4094 public boolean clearApplicationUserData(final String packageName, 4095 final IPackageDataObserver observer, int userId) { 4096 enforceNotIsolatedCaller("clearApplicationUserData"); 4097 int uid = Binder.getCallingUid(); 4098 int pid = Binder.getCallingPid(); 4099 userId = handleIncomingUser(pid, uid, 4100 userId, false, true, "clearApplicationUserData", null); 4101 long callingId = Binder.clearCallingIdentity(); 4102 try { 4103 IPackageManager pm = AppGlobals.getPackageManager(); 4104 int pkgUid = -1; 4105 synchronized(this) { 4106 try { 4107 pkgUid = pm.getPackageUid(packageName, userId); 4108 } catch (RemoteException e) { 4109 } 4110 if (pkgUid == -1) { 4111 Slog.w(TAG, "Invalid packageName: " + packageName); 4112 if (observer != null) { 4113 try { 4114 observer.onRemoveCompleted(packageName, false); 4115 } catch (RemoteException e) { 4116 Slog.i(TAG, "Observer no longer exists."); 4117 } 4118 } 4119 return false; 4120 } 4121 if (uid == pkgUid || checkComponentPermission( 4122 android.Manifest.permission.CLEAR_APP_USER_DATA, 4123 pid, uid, -1, true) 4124 == PackageManager.PERMISSION_GRANTED) { 4125 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4126 } else { 4127 throw new SecurityException("PID " + pid + " does not have permission " 4128 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4129 + " of package " + packageName); 4130 } 4131 } 4132 4133 try { 4134 // Clear application user data 4135 pm.clearApplicationUserData(packageName, observer, userId); 4136 4137 // Remove all permissions granted from/to this package 4138 removeUriPermissionsForPackageLocked(packageName, userId, true); 4139 4140 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4141 Uri.fromParts("package", packageName, null)); 4142 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4143 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4144 null, null, 0, null, null, null, false, false, userId); 4145 } catch (RemoteException e) { 4146 } 4147 } finally { 4148 Binder.restoreCallingIdentity(callingId); 4149 } 4150 return true; 4151 } 4152 4153 @Override 4154 public void killBackgroundProcesses(final String packageName, int userId) { 4155 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4156 != PackageManager.PERMISSION_GRANTED && 4157 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4158 != PackageManager.PERMISSION_GRANTED) { 4159 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4160 + Binder.getCallingPid() 4161 + ", uid=" + Binder.getCallingUid() 4162 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4163 Slog.w(TAG, msg); 4164 throw new SecurityException(msg); 4165 } 4166 4167 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4168 userId, true, true, "killBackgroundProcesses", null); 4169 long callingId = Binder.clearCallingIdentity(); 4170 try { 4171 IPackageManager pm = AppGlobals.getPackageManager(); 4172 synchronized(this) { 4173 int appId = -1; 4174 try { 4175 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4176 } catch (RemoteException e) { 4177 } 4178 if (appId == -1) { 4179 Slog.w(TAG, "Invalid packageName: " + packageName); 4180 return; 4181 } 4182 killPackageProcessesLocked(packageName, appId, userId, 4183 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4184 } 4185 } finally { 4186 Binder.restoreCallingIdentity(callingId); 4187 } 4188 } 4189 4190 @Override 4191 public void killAllBackgroundProcesses() { 4192 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4193 != PackageManager.PERMISSION_GRANTED) { 4194 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4195 + Binder.getCallingPid() 4196 + ", uid=" + Binder.getCallingUid() 4197 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4198 Slog.w(TAG, msg); 4199 throw new SecurityException(msg); 4200 } 4201 4202 long callingId = Binder.clearCallingIdentity(); 4203 try { 4204 synchronized(this) { 4205 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4206 final int NP = mProcessNames.getMap().size(); 4207 for (int ip=0; ip<NP; ip++) { 4208 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4209 final int NA = apps.size(); 4210 for (int ia=0; ia<NA; ia++) { 4211 ProcessRecord app = apps.valueAt(ia); 4212 if (app.persistent) { 4213 // we don't kill persistent processes 4214 continue; 4215 } 4216 if (app.removed) { 4217 procs.add(app); 4218 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4219 app.removed = true; 4220 procs.add(app); 4221 } 4222 } 4223 } 4224 4225 int N = procs.size(); 4226 for (int i=0; i<N; i++) { 4227 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4228 } 4229 mAllowLowerMemLevel = true; 4230 updateOomAdjLocked(); 4231 doLowMemReportIfNeededLocked(null); 4232 } 4233 } finally { 4234 Binder.restoreCallingIdentity(callingId); 4235 } 4236 } 4237 4238 @Override 4239 public void forceStopPackage(final String packageName, int userId) { 4240 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4241 != PackageManager.PERMISSION_GRANTED) { 4242 String msg = "Permission Denial: forceStopPackage() from pid=" 4243 + Binder.getCallingPid() 4244 + ", uid=" + Binder.getCallingUid() 4245 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4246 Slog.w(TAG, msg); 4247 throw new SecurityException(msg); 4248 } 4249 final int callingPid = Binder.getCallingPid(); 4250 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4251 userId, true, true, "forceStopPackage", null); 4252 long callingId = Binder.clearCallingIdentity(); 4253 try { 4254 IPackageManager pm = AppGlobals.getPackageManager(); 4255 synchronized(this) { 4256 int[] users = userId == UserHandle.USER_ALL 4257 ? getUsersLocked() : new int[] { userId }; 4258 for (int user : users) { 4259 int pkgUid = -1; 4260 try { 4261 pkgUid = pm.getPackageUid(packageName, user); 4262 } catch (RemoteException e) { 4263 } 4264 if (pkgUid == -1) { 4265 Slog.w(TAG, "Invalid packageName: " + packageName); 4266 continue; 4267 } 4268 try { 4269 pm.setPackageStoppedState(packageName, true, user); 4270 } catch (RemoteException e) { 4271 } catch (IllegalArgumentException e) { 4272 Slog.w(TAG, "Failed trying to unstop package " 4273 + packageName + ": " + e); 4274 } 4275 if (isUserRunningLocked(user, false)) { 4276 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4277 } 4278 } 4279 } 4280 } finally { 4281 Binder.restoreCallingIdentity(callingId); 4282 } 4283 } 4284 4285 /* 4286 * The pkg name and app id have to be specified. 4287 */ 4288 @Override 4289 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4290 if (pkg == null) { 4291 return; 4292 } 4293 // Make sure the uid is valid. 4294 if (appid < 0) { 4295 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4296 return; 4297 } 4298 int callerUid = Binder.getCallingUid(); 4299 // Only the system server can kill an application 4300 if (callerUid == Process.SYSTEM_UID) { 4301 // Post an aysnc message to kill the application 4302 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4303 msg.arg1 = appid; 4304 msg.arg2 = 0; 4305 Bundle bundle = new Bundle(); 4306 bundle.putString("pkg", pkg); 4307 bundle.putString("reason", reason); 4308 msg.obj = bundle; 4309 mHandler.sendMessage(msg); 4310 } else { 4311 throw new SecurityException(callerUid + " cannot kill pkg: " + 4312 pkg); 4313 } 4314 } 4315 4316 @Override 4317 public void closeSystemDialogs(String reason) { 4318 enforceNotIsolatedCaller("closeSystemDialogs"); 4319 4320 final int pid = Binder.getCallingPid(); 4321 final int uid = Binder.getCallingUid(); 4322 final long origId = Binder.clearCallingIdentity(); 4323 try { 4324 synchronized (this) { 4325 // Only allow this from foreground processes, so that background 4326 // applications can't abuse it to prevent system UI from being shown. 4327 if (uid >= Process.FIRST_APPLICATION_UID) { 4328 ProcessRecord proc; 4329 synchronized (mPidsSelfLocked) { 4330 proc = mPidsSelfLocked.get(pid); 4331 } 4332 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4333 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4334 + " from background process " + proc); 4335 return; 4336 } 4337 } 4338 closeSystemDialogsLocked(reason); 4339 } 4340 } finally { 4341 Binder.restoreCallingIdentity(origId); 4342 } 4343 } 4344 4345 void closeSystemDialogsLocked(String reason) { 4346 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4347 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4348 | Intent.FLAG_RECEIVER_FOREGROUND); 4349 if (reason != null) { 4350 intent.putExtra("reason", reason); 4351 } 4352 mWindowManager.closeSystemDialogs(reason); 4353 4354 mStackSupervisor.closeSystemDialogsLocked(); 4355 4356 broadcastIntentLocked(null, null, intent, null, 4357 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4358 Process.SYSTEM_UID, UserHandle.USER_ALL); 4359 } 4360 4361 @Override 4362 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4363 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4364 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4365 for (int i=pids.length-1; i>=0; i--) { 4366 ProcessRecord proc; 4367 int oomAdj; 4368 synchronized (this) { 4369 synchronized (mPidsSelfLocked) { 4370 proc = mPidsSelfLocked.get(pids[i]); 4371 oomAdj = proc != null ? proc.setAdj : 0; 4372 } 4373 } 4374 infos[i] = new Debug.MemoryInfo(); 4375 Debug.getMemoryInfo(pids[i], infos[i]); 4376 if (proc != null) { 4377 synchronized (this) { 4378 if (proc.thread != null && proc.setAdj == oomAdj) { 4379 // Record this for posterity if the process has been stable. 4380 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4381 infos[i].getTotalUss(), false, proc.pkgList); 4382 } 4383 } 4384 } 4385 } 4386 return infos; 4387 } 4388 4389 @Override 4390 public long[] getProcessPss(int[] pids) { 4391 enforceNotIsolatedCaller("getProcessPss"); 4392 long[] pss = new long[pids.length]; 4393 for (int i=pids.length-1; i>=0; i--) { 4394 ProcessRecord proc; 4395 int oomAdj; 4396 synchronized (this) { 4397 synchronized (mPidsSelfLocked) { 4398 proc = mPidsSelfLocked.get(pids[i]); 4399 oomAdj = proc != null ? proc.setAdj : 0; 4400 } 4401 } 4402 long[] tmpUss = new long[1]; 4403 pss[i] = Debug.getPss(pids[i], tmpUss); 4404 if (proc != null) { 4405 synchronized (this) { 4406 if (proc.thread != null && proc.setAdj == oomAdj) { 4407 // Record this for posterity if the process has been stable. 4408 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4409 } 4410 } 4411 } 4412 } 4413 return pss; 4414 } 4415 4416 @Override 4417 public void killApplicationProcess(String processName, int uid) { 4418 if (processName == null) { 4419 return; 4420 } 4421 4422 int callerUid = Binder.getCallingUid(); 4423 // Only the system server can kill an application 4424 if (callerUid == Process.SYSTEM_UID) { 4425 synchronized (this) { 4426 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4427 if (app != null && app.thread != null) { 4428 try { 4429 app.thread.scheduleSuicide(); 4430 } catch (RemoteException e) { 4431 // If the other end already died, then our work here is done. 4432 } 4433 } else { 4434 Slog.w(TAG, "Process/uid not found attempting kill of " 4435 + processName + " / " + uid); 4436 } 4437 } 4438 } else { 4439 throw new SecurityException(callerUid + " cannot kill app process: " + 4440 processName); 4441 } 4442 } 4443 4444 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4445 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4446 false, true, false, UserHandle.getUserId(uid), reason); 4447 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4448 Uri.fromParts("package", packageName, null)); 4449 if (!mProcessesReady) { 4450 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4451 | Intent.FLAG_RECEIVER_FOREGROUND); 4452 } 4453 intent.putExtra(Intent.EXTRA_UID, uid); 4454 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4455 broadcastIntentLocked(null, null, intent, 4456 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4457 false, false, 4458 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4459 } 4460 4461 private void forceStopUserLocked(int userId, String reason) { 4462 forceStopPackageLocked(null, -1, false, false, true, false, userId, reason); 4463 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4464 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4465 | Intent.FLAG_RECEIVER_FOREGROUND); 4466 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4467 broadcastIntentLocked(null, null, intent, 4468 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4469 false, false, 4470 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4471 } 4472 4473 private final boolean killPackageProcessesLocked(String packageName, int appId, 4474 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4475 boolean doit, boolean evenPersistent, String reason) { 4476 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4477 4478 // Remove all processes this package may have touched: all with the 4479 // same UID (except for the system or root user), and all whose name 4480 // matches the package name. 4481 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4482 final int NP = mProcessNames.getMap().size(); 4483 for (int ip=0; ip<NP; ip++) { 4484 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4485 final int NA = apps.size(); 4486 for (int ia=0; ia<NA; ia++) { 4487 ProcessRecord app = apps.valueAt(ia); 4488 if (app.persistent && !evenPersistent) { 4489 // we don't kill persistent processes 4490 continue; 4491 } 4492 if (app.removed) { 4493 if (doit) { 4494 procs.add(app); 4495 } 4496 continue; 4497 } 4498 4499 // Skip process if it doesn't meet our oom adj requirement. 4500 if (app.setAdj < minOomAdj) { 4501 continue; 4502 } 4503 4504 // If no package is specified, we call all processes under the 4505 // give user id. 4506 if (packageName == null) { 4507 if (app.userId != userId) { 4508 continue; 4509 } 4510 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4511 continue; 4512 } 4513 // Package has been specified, we want to hit all processes 4514 // that match it. We need to qualify this by the processes 4515 // that are running under the specified app and user ID. 4516 } else { 4517 if (UserHandle.getAppId(app.uid) != appId) { 4518 continue; 4519 } 4520 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4521 continue; 4522 } 4523 if (!app.pkgList.containsKey(packageName)) { 4524 continue; 4525 } 4526 } 4527 4528 // Process has passed all conditions, kill it! 4529 if (!doit) { 4530 return true; 4531 } 4532 app.removed = true; 4533 procs.add(app); 4534 } 4535 } 4536 4537 int N = procs.size(); 4538 for (int i=0; i<N; i++) { 4539 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4540 } 4541 updateOomAdjLocked(); 4542 return N > 0; 4543 } 4544 4545 private final boolean forceStopPackageLocked(String name, int appId, 4546 boolean callerWillRestart, boolean purgeCache, boolean doit, 4547 boolean evenPersistent, int userId, String reason) { 4548 int i; 4549 int N; 4550 4551 if (userId == UserHandle.USER_ALL && name == null) { 4552 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4553 } 4554 4555 if (appId < 0 && name != null) { 4556 try { 4557 appId = UserHandle.getAppId( 4558 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4559 } catch (RemoteException e) { 4560 } 4561 } 4562 4563 if (doit) { 4564 if (name != null) { 4565 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4566 + " user=" + userId + ": " + reason); 4567 } else { 4568 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4569 } 4570 4571 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4572 for (int ip=pmap.size()-1; ip>=0; ip--) { 4573 SparseArray<Long> ba = pmap.valueAt(ip); 4574 for (i=ba.size()-1; i>=0; i--) { 4575 boolean remove = false; 4576 final int entUid = ba.keyAt(i); 4577 if (name != null) { 4578 if (userId == UserHandle.USER_ALL) { 4579 if (UserHandle.getAppId(entUid) == appId) { 4580 remove = true; 4581 } 4582 } else { 4583 if (entUid == UserHandle.getUid(userId, appId)) { 4584 remove = true; 4585 } 4586 } 4587 } else if (UserHandle.getUserId(entUid) == userId) { 4588 remove = true; 4589 } 4590 if (remove) { 4591 ba.removeAt(i); 4592 } 4593 } 4594 if (ba.size() == 0) { 4595 pmap.removeAt(ip); 4596 } 4597 } 4598 } 4599 4600 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4601 -100, callerWillRestart, true, doit, evenPersistent, 4602 name == null ? ("stop user " + userId) : ("stop " + name)); 4603 4604 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4605 if (!doit) { 4606 return true; 4607 } 4608 didSomething = true; 4609 } 4610 4611 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4612 if (!doit) { 4613 return true; 4614 } 4615 didSomething = true; 4616 } 4617 4618 if (name == null) { 4619 // Remove all sticky broadcasts from this user. 4620 mStickyBroadcasts.remove(userId); 4621 } 4622 4623 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4624 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4625 userId, providers)) { 4626 if (!doit) { 4627 return true; 4628 } 4629 didSomething = true; 4630 } 4631 N = providers.size(); 4632 for (i=0; i<N; i++) { 4633 removeDyingProviderLocked(null, providers.get(i), true); 4634 } 4635 4636 // Remove transient permissions granted from/to this package/user 4637 removeUriPermissionsForPackageLocked(name, userId, false); 4638 4639 if (name == null) { 4640 // Remove pending intents. For now we only do this when force 4641 // stopping users, because we have some problems when doing this 4642 // for packages -- app widgets are not currently cleaned up for 4643 // such packages, so they can be left with bad pending intents. 4644 if (mIntentSenderRecords.size() > 0) { 4645 Iterator<WeakReference<PendingIntentRecord>> it 4646 = mIntentSenderRecords.values().iterator(); 4647 while (it.hasNext()) { 4648 WeakReference<PendingIntentRecord> wpir = it.next(); 4649 if (wpir == null) { 4650 it.remove(); 4651 continue; 4652 } 4653 PendingIntentRecord pir = wpir.get(); 4654 if (pir == null) { 4655 it.remove(); 4656 continue; 4657 } 4658 if (name == null) { 4659 // Stopping user, remove all objects for the user. 4660 if (pir.key.userId != userId) { 4661 // Not the same user, skip it. 4662 continue; 4663 } 4664 } else { 4665 if (UserHandle.getAppId(pir.uid) != appId) { 4666 // Different app id, skip it. 4667 continue; 4668 } 4669 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4670 // Different user, skip it. 4671 continue; 4672 } 4673 if (!pir.key.packageName.equals(name)) { 4674 // Different package, skip it. 4675 continue; 4676 } 4677 } 4678 if (!doit) { 4679 return true; 4680 } 4681 didSomething = true; 4682 it.remove(); 4683 pir.canceled = true; 4684 if (pir.key.activity != null) { 4685 pir.key.activity.pendingResults.remove(pir.ref); 4686 } 4687 } 4688 } 4689 } 4690 4691 if (doit) { 4692 if (purgeCache && name != null) { 4693 AttributeCache ac = AttributeCache.instance(); 4694 if (ac != null) { 4695 ac.removePackage(name); 4696 } 4697 } 4698 if (mBooted) { 4699 mStackSupervisor.resumeTopActivitiesLocked(); 4700 mStackSupervisor.scheduleIdleLocked(); 4701 } 4702 } 4703 4704 return didSomething; 4705 } 4706 4707 private final boolean removeProcessLocked(ProcessRecord app, 4708 boolean callerWillRestart, boolean allowRestart, String reason) { 4709 final String name = app.processName; 4710 final int uid = app.uid; 4711 if (DEBUG_PROCESSES) Slog.d( 4712 TAG, "Force removing proc " + app.toShortString() + " (" + name 4713 + "/" + uid + ")"); 4714 4715 mProcessNames.remove(name, uid); 4716 mIsolatedProcesses.remove(app.uid); 4717 if (mHeavyWeightProcess == app) { 4718 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4719 mHeavyWeightProcess.userId, 0)); 4720 mHeavyWeightProcess = null; 4721 } 4722 boolean needRestart = false; 4723 if (app.pid > 0 && app.pid != MY_PID) { 4724 int pid = app.pid; 4725 synchronized (mPidsSelfLocked) { 4726 mPidsSelfLocked.remove(pid); 4727 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4728 } 4729 killUnneededProcessLocked(app, reason); 4730 handleAppDiedLocked(app, true, allowRestart); 4731 removeLruProcessLocked(app); 4732 4733 if (app.persistent && !app.isolated) { 4734 if (!callerWillRestart) { 4735 addAppLocked(app.info, false); 4736 } else { 4737 needRestart = true; 4738 } 4739 } 4740 } else { 4741 mRemovedProcesses.add(app); 4742 } 4743 4744 return needRestart; 4745 } 4746 4747 private final void processStartTimedOutLocked(ProcessRecord app) { 4748 final int pid = app.pid; 4749 boolean gone = false; 4750 synchronized (mPidsSelfLocked) { 4751 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4752 if (knownApp != null && knownApp.thread == null) { 4753 mPidsSelfLocked.remove(pid); 4754 gone = true; 4755 } 4756 } 4757 4758 if (gone) { 4759 Slog.w(TAG, "Process " + app + " failed to attach"); 4760 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4761 pid, app.uid, app.processName); 4762 mProcessNames.remove(app.processName, app.uid); 4763 mIsolatedProcesses.remove(app.uid); 4764 if (mHeavyWeightProcess == app) { 4765 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4766 mHeavyWeightProcess.userId, 0)); 4767 mHeavyWeightProcess = null; 4768 } 4769 // Take care of any launching providers waiting for this process. 4770 checkAppInLaunchingProvidersLocked(app, true); 4771 // Take care of any services that are waiting for the process. 4772 mServices.processStartTimedOutLocked(app); 4773 killUnneededProcessLocked(app, "start timeout"); 4774 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4775 Slog.w(TAG, "Unattached app died before backup, skipping"); 4776 try { 4777 IBackupManager bm = IBackupManager.Stub.asInterface( 4778 ServiceManager.getService(Context.BACKUP_SERVICE)); 4779 bm.agentDisconnected(app.info.packageName); 4780 } catch (RemoteException e) { 4781 // Can't happen; the backup manager is local 4782 } 4783 } 4784 if (isPendingBroadcastProcessLocked(pid)) { 4785 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4786 skipPendingBroadcastLocked(pid); 4787 } 4788 } else { 4789 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4790 } 4791 } 4792 4793 private final boolean attachApplicationLocked(IApplicationThread thread, 4794 int pid) { 4795 4796 // Find the application record that is being attached... either via 4797 // the pid if we are running in multiple processes, or just pull the 4798 // next app record if we are emulating process with anonymous threads. 4799 ProcessRecord app; 4800 if (pid != MY_PID && pid >= 0) { 4801 synchronized (mPidsSelfLocked) { 4802 app = mPidsSelfLocked.get(pid); 4803 } 4804 } else { 4805 app = null; 4806 } 4807 4808 if (app == null) { 4809 Slog.w(TAG, "No pending application record for pid " + pid 4810 + " (IApplicationThread " + thread + "); dropping process"); 4811 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4812 if (pid > 0 && pid != MY_PID) { 4813 Process.killProcessQuiet(pid); 4814 } else { 4815 try { 4816 thread.scheduleExit(); 4817 } catch (Exception e) { 4818 // Ignore exceptions. 4819 } 4820 } 4821 return false; 4822 } 4823 4824 // If this application record is still attached to a previous 4825 // process, clean it up now. 4826 if (app.thread != null) { 4827 handleAppDiedLocked(app, true, true); 4828 } 4829 4830 // Tell the process all about itself. 4831 4832 if (localLOGV) Slog.v( 4833 TAG, "Binding process pid " + pid + " to record " + app); 4834 4835 final String processName = app.processName; 4836 try { 4837 AppDeathRecipient adr = new AppDeathRecipient( 4838 app, pid, thread); 4839 thread.asBinder().linkToDeath(adr, 0); 4840 app.deathRecipient = adr; 4841 } catch (RemoteException e) { 4842 app.resetPackageList(mProcessStats); 4843 startProcessLocked(app, "link fail", processName); 4844 return false; 4845 } 4846 4847 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4848 4849 app.makeActive(thread, mProcessStats); 4850 app.curAdj = app.setAdj = -100; 4851 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4852 app.forcingToForeground = null; 4853 app.foregroundServices = false; 4854 app.hasShownUi = false; 4855 app.debugging = false; 4856 app.cached = false; 4857 4858 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4859 4860 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4861 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4862 4863 if (!normalMode) { 4864 Slog.i(TAG, "Launching preboot mode app: " + app); 4865 } 4866 4867 if (localLOGV) Slog.v( 4868 TAG, "New app record " + app 4869 + " thread=" + thread.asBinder() + " pid=" + pid); 4870 try { 4871 int testMode = IApplicationThread.DEBUG_OFF; 4872 if (mDebugApp != null && mDebugApp.equals(processName)) { 4873 testMode = mWaitForDebugger 4874 ? IApplicationThread.DEBUG_WAIT 4875 : IApplicationThread.DEBUG_ON; 4876 app.debugging = true; 4877 if (mDebugTransient) { 4878 mDebugApp = mOrigDebugApp; 4879 mWaitForDebugger = mOrigWaitForDebugger; 4880 } 4881 } 4882 String profileFile = app.instrumentationProfileFile; 4883 ParcelFileDescriptor profileFd = null; 4884 boolean profileAutoStop = false; 4885 if (mProfileApp != null && mProfileApp.equals(processName)) { 4886 mProfileProc = app; 4887 profileFile = mProfileFile; 4888 profileFd = mProfileFd; 4889 profileAutoStop = mAutoStopProfiler; 4890 } 4891 boolean enableOpenGlTrace = false; 4892 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4893 enableOpenGlTrace = true; 4894 mOpenGlTraceApp = null; 4895 } 4896 4897 // If the app is being launched for restore or full backup, set it up specially 4898 boolean isRestrictedBackupMode = false; 4899 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4900 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4901 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4902 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4903 } 4904 4905 ensurePackageDexOpt(app.instrumentationInfo != null 4906 ? app.instrumentationInfo.packageName 4907 : app.info.packageName); 4908 if (app.instrumentationClass != null) { 4909 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4910 } 4911 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4912 + processName + " with config " + mConfiguration); 4913 ApplicationInfo appInfo = app.instrumentationInfo != null 4914 ? app.instrumentationInfo : app.info; 4915 app.compat = compatibilityInfoForPackageLocked(appInfo); 4916 if (profileFd != null) { 4917 profileFd = profileFd.dup(); 4918 } 4919 thread.bindApplication(processName, appInfo, providers, 4920 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4921 app.instrumentationArguments, app.instrumentationWatcher, 4922 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4923 isRestrictedBackupMode || !normalMode, app.persistent, 4924 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4925 mCoreSettingsObserver.getCoreSettingsLocked()); 4926 updateLruProcessLocked(app, false, null); 4927 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4928 } catch (Exception e) { 4929 // todo: Yikes! What should we do? For now we will try to 4930 // start another process, but that could easily get us in 4931 // an infinite loop of restarting processes... 4932 Slog.w(TAG, "Exception thrown during bind!", e); 4933 4934 app.resetPackageList(mProcessStats); 4935 app.unlinkDeathRecipient(); 4936 startProcessLocked(app, "bind fail", processName); 4937 return false; 4938 } 4939 4940 // Remove this record from the list of starting applications. 4941 mPersistentStartingProcesses.remove(app); 4942 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4943 "Attach application locked removing on hold: " + app); 4944 mProcessesOnHold.remove(app); 4945 4946 boolean badApp = false; 4947 boolean didSomething = false; 4948 4949 // See if the top visible activity is waiting to run in this process... 4950 if (normalMode) { 4951 try { 4952 if (mStackSupervisor.attachApplicationLocked(app)) { 4953 didSomething = true; 4954 } 4955 } catch (Exception e) { 4956 badApp = true; 4957 } 4958 } 4959 4960 // Find any services that should be running in this process... 4961 if (!badApp) { 4962 try { 4963 didSomething |= mServices.attachApplicationLocked(app, processName); 4964 } catch (Exception e) { 4965 badApp = true; 4966 } 4967 } 4968 4969 // Check if a next-broadcast receiver is in this process... 4970 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4971 try { 4972 didSomething |= sendPendingBroadcastsLocked(app); 4973 } catch (Exception e) { 4974 // If the app died trying to launch the receiver we declare it 'bad' 4975 badApp = true; 4976 } 4977 } 4978 4979 // Check whether the next backup agent is in this process... 4980 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4981 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4982 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4983 try { 4984 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4985 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4986 mBackupTarget.backupMode); 4987 } catch (Exception e) { 4988 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4989 e.printStackTrace(); 4990 } 4991 } 4992 4993 if (badApp) { 4994 // todo: Also need to kill application to deal with all 4995 // kinds of exceptions. 4996 handleAppDiedLocked(app, false, true); 4997 return false; 4998 } 4999 5000 if (!didSomething) { 5001 updateOomAdjLocked(); 5002 } 5003 5004 return true; 5005 } 5006 5007 @Override 5008 public final void attachApplication(IApplicationThread thread) { 5009 synchronized (this) { 5010 int callingPid = Binder.getCallingPid(); 5011 final long origId = Binder.clearCallingIdentity(); 5012 attachApplicationLocked(thread, callingPid); 5013 Binder.restoreCallingIdentity(origId); 5014 } 5015 } 5016 5017 @Override 5018 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5019 final long origId = Binder.clearCallingIdentity(); 5020 synchronized (this) { 5021 ActivityStack stack = ActivityRecord.getStackLocked(token); 5022 if (stack != null) { 5023 ActivityRecord r = 5024 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5025 if (stopProfiling) { 5026 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5027 try { 5028 mProfileFd.close(); 5029 } catch (IOException e) { 5030 } 5031 clearProfilerLocked(); 5032 } 5033 } 5034 } 5035 } 5036 Binder.restoreCallingIdentity(origId); 5037 } 5038 5039 void enableScreenAfterBoot() { 5040 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5041 SystemClock.uptimeMillis()); 5042 mWindowManager.enableScreenAfterBoot(); 5043 5044 synchronized (this) { 5045 updateEventDispatchingLocked(); 5046 } 5047 } 5048 5049 @Override 5050 public void showBootMessage(final CharSequence msg, final boolean always) { 5051 enforceNotIsolatedCaller("showBootMessage"); 5052 mWindowManager.showBootMessage(msg, always); 5053 } 5054 5055 @Override 5056 public void dismissKeyguardOnNextActivity() { 5057 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5058 final long token = Binder.clearCallingIdentity(); 5059 try { 5060 synchronized (this) { 5061 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5062 if (mLockScreenShown) { 5063 mLockScreenShown = false; 5064 comeOutOfSleepIfNeededLocked(); 5065 } 5066 mStackSupervisor.setDismissKeyguard(true); 5067 } 5068 } finally { 5069 Binder.restoreCallingIdentity(token); 5070 } 5071 } 5072 5073 final void finishBooting() { 5074 IntentFilter pkgFilter = new IntentFilter(); 5075 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5076 pkgFilter.addDataScheme("package"); 5077 mContext.registerReceiver(new BroadcastReceiver() { 5078 @Override 5079 public void onReceive(Context context, Intent intent) { 5080 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5081 if (pkgs != null) { 5082 for (String pkg : pkgs) { 5083 synchronized (ActivityManagerService.this) { 5084 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0, 5085 "finished booting")) { 5086 setResultCode(Activity.RESULT_OK); 5087 return; 5088 } 5089 } 5090 } 5091 } 5092 } 5093 }, pkgFilter); 5094 5095 synchronized (this) { 5096 // Ensure that any processes we had put on hold are now started 5097 // up. 5098 final int NP = mProcessesOnHold.size(); 5099 if (NP > 0) { 5100 ArrayList<ProcessRecord> procs = 5101 new ArrayList<ProcessRecord>(mProcessesOnHold); 5102 for (int ip=0; ip<NP; ip++) { 5103 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5104 + procs.get(ip)); 5105 startProcessLocked(procs.get(ip), "on-hold", null); 5106 } 5107 } 5108 5109 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5110 // Start looking for apps that are abusing wake locks. 5111 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5112 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5113 // Tell anyone interested that we are done booting! 5114 SystemProperties.set("sys.boot_completed", "1"); 5115 SystemProperties.set("dev.bootcomplete", "1"); 5116 for (int i=0; i<mStartedUsers.size(); i++) { 5117 UserStartedState uss = mStartedUsers.valueAt(i); 5118 if (uss.mState == UserStartedState.STATE_BOOTING) { 5119 uss.mState = UserStartedState.STATE_RUNNING; 5120 final int userId = mStartedUsers.keyAt(i); 5121 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5122 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5123 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5124 broadcastIntentLocked(null, null, intent, null, 5125 new IIntentReceiver.Stub() { 5126 @Override 5127 public void performReceive(Intent intent, int resultCode, 5128 String data, Bundle extras, boolean ordered, 5129 boolean sticky, int sendingUser) { 5130 synchronized (ActivityManagerService.this) { 5131 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5132 true, false); 5133 } 5134 } 5135 }, 5136 0, null, null, 5137 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5138 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5139 userId); 5140 } 5141 } 5142 } 5143 } 5144 } 5145 5146 final void ensureBootCompleted() { 5147 boolean booting; 5148 boolean enableScreen; 5149 synchronized (this) { 5150 booting = mBooting; 5151 mBooting = false; 5152 enableScreen = !mBooted; 5153 mBooted = true; 5154 } 5155 5156 if (booting) { 5157 finishBooting(); 5158 } 5159 5160 if (enableScreen) { 5161 enableScreenAfterBoot(); 5162 } 5163 } 5164 5165 @Override 5166 public final void activityResumed(IBinder token) { 5167 final long origId = Binder.clearCallingIdentity(); 5168 synchronized(this) { 5169 ActivityStack stack = ActivityRecord.getStackLocked(token); 5170 if (stack != null) { 5171 ActivityRecord.activityResumedLocked(token); 5172 } 5173 } 5174 Binder.restoreCallingIdentity(origId); 5175 } 5176 5177 @Override 5178 public final void activityPaused(IBinder token) { 5179 final long origId = Binder.clearCallingIdentity(); 5180 synchronized(this) { 5181 ActivityStack stack = ActivityRecord.getStackLocked(token); 5182 if (stack != null) { 5183 stack.activityPausedLocked(token, false); 5184 } 5185 } 5186 Binder.restoreCallingIdentity(origId); 5187 } 5188 5189 @Override 5190 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5191 CharSequence description) { 5192 if (localLOGV) Slog.v( 5193 TAG, "Activity stopped: token=" + token); 5194 5195 // Refuse possible leaked file descriptors 5196 if (icicle != null && icicle.hasFileDescriptors()) { 5197 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5198 } 5199 5200 ActivityRecord r = null; 5201 5202 final long origId = Binder.clearCallingIdentity(); 5203 5204 synchronized (this) { 5205 r = ActivityRecord.isInStackLocked(token); 5206 if (r != null) { 5207 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5208 } 5209 } 5210 5211 if (r != null) { 5212 sendPendingThumbnail(r, null, null, null, false); 5213 } 5214 5215 trimApplications(); 5216 5217 Binder.restoreCallingIdentity(origId); 5218 } 5219 5220 @Override 5221 public final void activityDestroyed(IBinder token) { 5222 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5223 synchronized (this) { 5224 ActivityStack stack = ActivityRecord.getStackLocked(token); 5225 if (stack != null) { 5226 stack.activityDestroyedLocked(token); 5227 } 5228 } 5229 } 5230 5231 @Override 5232 public String getCallingPackage(IBinder token) { 5233 synchronized (this) { 5234 ActivityRecord r = getCallingRecordLocked(token); 5235 return r != null ? r.info.packageName : null; 5236 } 5237 } 5238 5239 @Override 5240 public ComponentName getCallingActivity(IBinder token) { 5241 synchronized (this) { 5242 ActivityRecord r = getCallingRecordLocked(token); 5243 return r != null ? r.intent.getComponent() : null; 5244 } 5245 } 5246 5247 private ActivityRecord getCallingRecordLocked(IBinder token) { 5248 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5249 if (r == null) { 5250 return null; 5251 } 5252 return r.resultTo; 5253 } 5254 5255 @Override 5256 public ComponentName getActivityClassForToken(IBinder token) { 5257 synchronized(this) { 5258 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5259 if (r == null) { 5260 return null; 5261 } 5262 return r.intent.getComponent(); 5263 } 5264 } 5265 5266 @Override 5267 public String getPackageForToken(IBinder token) { 5268 synchronized(this) { 5269 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5270 if (r == null) { 5271 return null; 5272 } 5273 return r.packageName; 5274 } 5275 } 5276 5277 @Override 5278 public IIntentSender getIntentSender(int type, 5279 String packageName, IBinder token, String resultWho, 5280 int requestCode, Intent[] intents, String[] resolvedTypes, 5281 int flags, Bundle options, int userId) { 5282 enforceNotIsolatedCaller("getIntentSender"); 5283 // Refuse possible leaked file descriptors 5284 if (intents != null) { 5285 if (intents.length < 1) { 5286 throw new IllegalArgumentException("Intents array length must be >= 1"); 5287 } 5288 for (int i=0; i<intents.length; i++) { 5289 Intent intent = intents[i]; 5290 if (intent != null) { 5291 if (intent.hasFileDescriptors()) { 5292 throw new IllegalArgumentException("File descriptors passed in Intent"); 5293 } 5294 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5295 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5296 throw new IllegalArgumentException( 5297 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5298 } 5299 intents[i] = new Intent(intent); 5300 } 5301 } 5302 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5303 throw new IllegalArgumentException( 5304 "Intent array length does not match resolvedTypes length"); 5305 } 5306 } 5307 if (options != null) { 5308 if (options.hasFileDescriptors()) { 5309 throw new IllegalArgumentException("File descriptors passed in options"); 5310 } 5311 } 5312 5313 synchronized(this) { 5314 int callingUid = Binder.getCallingUid(); 5315 int origUserId = userId; 5316 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5317 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5318 "getIntentSender", null); 5319 if (origUserId == UserHandle.USER_CURRENT) { 5320 // We don't want to evaluate this until the pending intent is 5321 // actually executed. However, we do want to always do the 5322 // security checking for it above. 5323 userId = UserHandle.USER_CURRENT; 5324 } 5325 try { 5326 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5327 int uid = AppGlobals.getPackageManager() 5328 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5329 if (!UserHandle.isSameApp(callingUid, uid)) { 5330 String msg = "Permission Denial: getIntentSender() from pid=" 5331 + Binder.getCallingPid() 5332 + ", uid=" + Binder.getCallingUid() 5333 + ", (need uid=" + uid + ")" 5334 + " is not allowed to send as package " + packageName; 5335 Slog.w(TAG, msg); 5336 throw new SecurityException(msg); 5337 } 5338 } 5339 5340 return getIntentSenderLocked(type, packageName, callingUid, userId, 5341 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5342 5343 } catch (RemoteException e) { 5344 throw new SecurityException(e); 5345 } 5346 } 5347 } 5348 5349 IIntentSender getIntentSenderLocked(int type, String packageName, 5350 int callingUid, int userId, IBinder token, String resultWho, 5351 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5352 Bundle options) { 5353 if (DEBUG_MU) 5354 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5355 ActivityRecord activity = null; 5356 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5357 activity = ActivityRecord.isInStackLocked(token); 5358 if (activity == null) { 5359 return null; 5360 } 5361 if (activity.finishing) { 5362 return null; 5363 } 5364 } 5365 5366 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5367 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5368 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5369 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5370 |PendingIntent.FLAG_UPDATE_CURRENT); 5371 5372 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5373 type, packageName, activity, resultWho, 5374 requestCode, intents, resolvedTypes, flags, options, userId); 5375 WeakReference<PendingIntentRecord> ref; 5376 ref = mIntentSenderRecords.get(key); 5377 PendingIntentRecord rec = ref != null ? ref.get() : null; 5378 if (rec != null) { 5379 if (!cancelCurrent) { 5380 if (updateCurrent) { 5381 if (rec.key.requestIntent != null) { 5382 rec.key.requestIntent.replaceExtras(intents != null ? 5383 intents[intents.length - 1] : null); 5384 } 5385 if (intents != null) { 5386 intents[intents.length-1] = rec.key.requestIntent; 5387 rec.key.allIntents = intents; 5388 rec.key.allResolvedTypes = resolvedTypes; 5389 } else { 5390 rec.key.allIntents = null; 5391 rec.key.allResolvedTypes = null; 5392 } 5393 } 5394 return rec; 5395 } 5396 rec.canceled = true; 5397 mIntentSenderRecords.remove(key); 5398 } 5399 if (noCreate) { 5400 return rec; 5401 } 5402 rec = new PendingIntentRecord(this, key, callingUid); 5403 mIntentSenderRecords.put(key, rec.ref); 5404 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5405 if (activity.pendingResults == null) { 5406 activity.pendingResults 5407 = new HashSet<WeakReference<PendingIntentRecord>>(); 5408 } 5409 activity.pendingResults.add(rec.ref); 5410 } 5411 return rec; 5412 } 5413 5414 @Override 5415 public void cancelIntentSender(IIntentSender sender) { 5416 if (!(sender instanceof PendingIntentRecord)) { 5417 return; 5418 } 5419 synchronized(this) { 5420 PendingIntentRecord rec = (PendingIntentRecord)sender; 5421 try { 5422 int uid = AppGlobals.getPackageManager() 5423 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5424 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5425 String msg = "Permission Denial: cancelIntentSender() from pid=" 5426 + Binder.getCallingPid() 5427 + ", uid=" + Binder.getCallingUid() 5428 + " is not allowed to cancel packges " 5429 + rec.key.packageName; 5430 Slog.w(TAG, msg); 5431 throw new SecurityException(msg); 5432 } 5433 } catch (RemoteException e) { 5434 throw new SecurityException(e); 5435 } 5436 cancelIntentSenderLocked(rec, true); 5437 } 5438 } 5439 5440 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5441 rec.canceled = true; 5442 mIntentSenderRecords.remove(rec.key); 5443 if (cleanActivity && rec.key.activity != null) { 5444 rec.key.activity.pendingResults.remove(rec.ref); 5445 } 5446 } 5447 5448 @Override 5449 public String getPackageForIntentSender(IIntentSender pendingResult) { 5450 if (!(pendingResult instanceof PendingIntentRecord)) { 5451 return null; 5452 } 5453 try { 5454 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5455 return res.key.packageName; 5456 } catch (ClassCastException e) { 5457 } 5458 return null; 5459 } 5460 5461 @Override 5462 public int getUidForIntentSender(IIntentSender sender) { 5463 if (sender instanceof PendingIntentRecord) { 5464 try { 5465 PendingIntentRecord res = (PendingIntentRecord)sender; 5466 return res.uid; 5467 } catch (ClassCastException e) { 5468 } 5469 } 5470 return -1; 5471 } 5472 5473 @Override 5474 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5475 if (!(pendingResult instanceof PendingIntentRecord)) { 5476 return false; 5477 } 5478 try { 5479 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5480 if (res.key.allIntents == null) { 5481 return false; 5482 } 5483 for (int i=0; i<res.key.allIntents.length; i++) { 5484 Intent intent = res.key.allIntents[i]; 5485 if (intent.getPackage() != null && intent.getComponent() != null) { 5486 return false; 5487 } 5488 } 5489 return true; 5490 } catch (ClassCastException e) { 5491 } 5492 return false; 5493 } 5494 5495 @Override 5496 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5497 if (!(pendingResult instanceof PendingIntentRecord)) { 5498 return false; 5499 } 5500 try { 5501 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5502 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5503 return true; 5504 } 5505 return false; 5506 } catch (ClassCastException e) { 5507 } 5508 return false; 5509 } 5510 5511 @Override 5512 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5513 if (!(pendingResult instanceof PendingIntentRecord)) { 5514 return null; 5515 } 5516 try { 5517 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5518 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5519 } catch (ClassCastException e) { 5520 } 5521 return null; 5522 } 5523 5524 @Override 5525 public void setProcessLimit(int max) { 5526 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5527 "setProcessLimit()"); 5528 synchronized (this) { 5529 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5530 mProcessLimitOverride = max; 5531 } 5532 trimApplications(); 5533 } 5534 5535 @Override 5536 public int getProcessLimit() { 5537 synchronized (this) { 5538 return mProcessLimitOverride; 5539 } 5540 } 5541 5542 void foregroundTokenDied(ForegroundToken token) { 5543 synchronized (ActivityManagerService.this) { 5544 synchronized (mPidsSelfLocked) { 5545 ForegroundToken cur 5546 = mForegroundProcesses.get(token.pid); 5547 if (cur != token) { 5548 return; 5549 } 5550 mForegroundProcesses.remove(token.pid); 5551 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5552 if (pr == null) { 5553 return; 5554 } 5555 pr.forcingToForeground = null; 5556 pr.foregroundServices = false; 5557 } 5558 updateOomAdjLocked(); 5559 } 5560 } 5561 5562 @Override 5563 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5564 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5565 "setProcessForeground()"); 5566 synchronized(this) { 5567 boolean changed = false; 5568 5569 synchronized (mPidsSelfLocked) { 5570 ProcessRecord pr = mPidsSelfLocked.get(pid); 5571 if (pr == null && isForeground) { 5572 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5573 return; 5574 } 5575 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5576 if (oldToken != null) { 5577 oldToken.token.unlinkToDeath(oldToken, 0); 5578 mForegroundProcesses.remove(pid); 5579 if (pr != null) { 5580 pr.forcingToForeground = null; 5581 } 5582 changed = true; 5583 } 5584 if (isForeground && token != null) { 5585 ForegroundToken newToken = new ForegroundToken() { 5586 @Override 5587 public void binderDied() { 5588 foregroundTokenDied(this); 5589 } 5590 }; 5591 newToken.pid = pid; 5592 newToken.token = token; 5593 try { 5594 token.linkToDeath(newToken, 0); 5595 mForegroundProcesses.put(pid, newToken); 5596 pr.forcingToForeground = token; 5597 changed = true; 5598 } catch (RemoteException e) { 5599 // If the process died while doing this, we will later 5600 // do the cleanup with the process death link. 5601 } 5602 } 5603 } 5604 5605 if (changed) { 5606 updateOomAdjLocked(); 5607 } 5608 } 5609 } 5610 5611 // ========================================================= 5612 // PERMISSIONS 5613 // ========================================================= 5614 5615 static class PermissionController extends IPermissionController.Stub { 5616 ActivityManagerService mActivityManagerService; 5617 PermissionController(ActivityManagerService activityManagerService) { 5618 mActivityManagerService = activityManagerService; 5619 } 5620 5621 @Override 5622 public boolean checkPermission(String permission, int pid, int uid) { 5623 return mActivityManagerService.checkPermission(permission, pid, 5624 uid) == PackageManager.PERMISSION_GRANTED; 5625 } 5626 } 5627 5628 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5629 @Override 5630 public int checkComponentPermission(String permission, int pid, int uid, 5631 int owningUid, boolean exported) { 5632 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5633 owningUid, exported); 5634 } 5635 5636 @Override 5637 public Object getAMSLock() { 5638 return ActivityManagerService.this; 5639 } 5640 } 5641 5642 /** 5643 * This can be called with or without the global lock held. 5644 */ 5645 int checkComponentPermission(String permission, int pid, int uid, 5646 int owningUid, boolean exported) { 5647 // We might be performing an operation on behalf of an indirect binder 5648 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5649 // client identity accordingly before proceeding. 5650 Identity tlsIdentity = sCallerIdentity.get(); 5651 if (tlsIdentity != null) { 5652 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5653 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5654 uid = tlsIdentity.uid; 5655 pid = tlsIdentity.pid; 5656 } 5657 5658 if (pid == MY_PID) { 5659 return PackageManager.PERMISSION_GRANTED; 5660 } 5661 5662 return ActivityManager.checkComponentPermission(permission, uid, 5663 owningUid, exported); 5664 } 5665 5666 /** 5667 * As the only public entry point for permissions checking, this method 5668 * can enforce the semantic that requesting a check on a null global 5669 * permission is automatically denied. (Internally a null permission 5670 * string is used when calling {@link #checkComponentPermission} in cases 5671 * when only uid-based security is needed.) 5672 * 5673 * This can be called with or without the global lock held. 5674 */ 5675 @Override 5676 public int checkPermission(String permission, int pid, int uid) { 5677 if (permission == null) { 5678 return PackageManager.PERMISSION_DENIED; 5679 } 5680 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5681 } 5682 5683 /** 5684 * Binder IPC calls go through the public entry point. 5685 * This can be called with or without the global lock held. 5686 */ 5687 int checkCallingPermission(String permission) { 5688 return checkPermission(permission, 5689 Binder.getCallingPid(), 5690 UserHandle.getAppId(Binder.getCallingUid())); 5691 } 5692 5693 /** 5694 * This can be called with or without the global lock held. 5695 */ 5696 void enforceCallingPermission(String permission, String func) { 5697 if (checkCallingPermission(permission) 5698 == PackageManager.PERMISSION_GRANTED) { 5699 return; 5700 } 5701 5702 String msg = "Permission Denial: " + func + " from pid=" 5703 + Binder.getCallingPid() 5704 + ", uid=" + Binder.getCallingUid() 5705 + " requires " + permission; 5706 Slog.w(TAG, msg); 5707 throw new SecurityException(msg); 5708 } 5709 5710 /** 5711 * Determine if UID is holding permissions required to access {@link Uri} in 5712 * the given {@link ProviderInfo}. Final permission checking is always done 5713 * in {@link ContentProvider}. 5714 */ 5715 private final boolean checkHoldingPermissionsLocked( 5716 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5717 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5718 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5719 5720 if (pi.applicationInfo.uid == uid) { 5721 return true; 5722 } else if (!pi.exported) { 5723 return false; 5724 } 5725 5726 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5727 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5728 try { 5729 // check if target holds top-level <provider> permissions 5730 if (!readMet && pi.readPermission != null 5731 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5732 readMet = true; 5733 } 5734 if (!writeMet && pi.writePermission != null 5735 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5736 writeMet = true; 5737 } 5738 5739 // track if unprotected read/write is allowed; any denied 5740 // <path-permission> below removes this ability 5741 boolean allowDefaultRead = pi.readPermission == null; 5742 boolean allowDefaultWrite = pi.writePermission == null; 5743 5744 // check if target holds any <path-permission> that match uri 5745 final PathPermission[] pps = pi.pathPermissions; 5746 if (pps != null) { 5747 final String path = uri.getPath(); 5748 int i = pps.length; 5749 while (i > 0 && (!readMet || !writeMet)) { 5750 i--; 5751 PathPermission pp = pps[i]; 5752 if (pp.match(path)) { 5753 if (!readMet) { 5754 final String pprperm = pp.getReadPermission(); 5755 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5756 + pprperm + " for " + pp.getPath() 5757 + ": match=" + pp.match(path) 5758 + " check=" + pm.checkUidPermission(pprperm, uid)); 5759 if (pprperm != null) { 5760 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5761 readMet = true; 5762 } else { 5763 allowDefaultRead = false; 5764 } 5765 } 5766 } 5767 if (!writeMet) { 5768 final String ppwperm = pp.getWritePermission(); 5769 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5770 + ppwperm + " for " + pp.getPath() 5771 + ": match=" + pp.match(path) 5772 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5773 if (ppwperm != null) { 5774 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5775 writeMet = true; 5776 } else { 5777 allowDefaultWrite = false; 5778 } 5779 } 5780 } 5781 } 5782 } 5783 } 5784 5785 // grant unprotected <provider> read/write, if not blocked by 5786 // <path-permission> above 5787 if (allowDefaultRead) readMet = true; 5788 if (allowDefaultWrite) writeMet = true; 5789 5790 } catch (RemoteException e) { 5791 return false; 5792 } 5793 5794 return readMet && writeMet; 5795 } 5796 5797 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5798 ProviderInfo pi = null; 5799 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5800 if (cpr != null) { 5801 pi = cpr.info; 5802 } else { 5803 try { 5804 pi = AppGlobals.getPackageManager().resolveContentProvider( 5805 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5806 } catch (RemoteException ex) { 5807 } 5808 } 5809 return pi; 5810 } 5811 5812 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5813 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5814 if (targetUris != null) { 5815 return targetUris.get(uri); 5816 } else { 5817 return null; 5818 } 5819 } 5820 5821 private UriPermission findOrCreateUriPermissionLocked( 5822 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5823 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5824 if (targetUris == null) { 5825 targetUris = Maps.newArrayMap(); 5826 mGrantedUriPermissions.put(targetUid, targetUris); 5827 } 5828 5829 UriPermission perm = targetUris.get(uri); 5830 if (perm == null) { 5831 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5832 targetUris.put(uri, perm); 5833 } 5834 5835 return perm; 5836 } 5837 5838 private final boolean checkUriPermissionLocked( 5839 Uri uri, int uid, int modeFlags, int minStrength) { 5840 // Root gets to do everything. 5841 if (uid == 0) { 5842 return true; 5843 } 5844 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5845 if (perms == null) return false; 5846 UriPermission perm = perms.get(uri); 5847 if (perm == null) return false; 5848 return perm.getStrength(modeFlags) >= minStrength; 5849 } 5850 5851 @Override 5852 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5853 enforceNotIsolatedCaller("checkUriPermission"); 5854 5855 // Another redirected-binder-call permissions check as in 5856 // {@link checkComponentPermission}. 5857 Identity tlsIdentity = sCallerIdentity.get(); 5858 if (tlsIdentity != null) { 5859 uid = tlsIdentity.uid; 5860 pid = tlsIdentity.pid; 5861 } 5862 5863 // Our own process gets to do everything. 5864 if (pid == MY_PID) { 5865 return PackageManager.PERMISSION_GRANTED; 5866 } 5867 synchronized(this) { 5868 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5869 ? PackageManager.PERMISSION_GRANTED 5870 : PackageManager.PERMISSION_DENIED; 5871 } 5872 } 5873 5874 /** 5875 * Check if the targetPkg can be granted permission to access uri by 5876 * the callingUid using the given modeFlags. Throws a security exception 5877 * if callingUid is not allowed to do this. Returns the uid of the target 5878 * if the URI permission grant should be performed; returns -1 if it is not 5879 * needed (for example targetPkg already has permission to access the URI). 5880 * If you already know the uid of the target, you can supply it in 5881 * lastTargetUid else set that to -1. 5882 */ 5883 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5884 Uri uri, int modeFlags, int lastTargetUid) { 5885 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5886 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5887 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5888 if (modeFlags == 0) { 5889 return -1; 5890 } 5891 5892 if (targetPkg != null) { 5893 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5894 "Checking grant " + targetPkg + " permission to " + uri); 5895 } 5896 5897 final IPackageManager pm = AppGlobals.getPackageManager(); 5898 5899 // If this is not a content: uri, we can't do anything with it. 5900 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5901 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5902 "Can't grant URI permission for non-content URI: " + uri); 5903 return -1; 5904 } 5905 5906 final String authority = uri.getAuthority(); 5907 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 5908 if (pi == null) { 5909 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5910 return -1; 5911 } 5912 5913 int targetUid = lastTargetUid; 5914 if (targetUid < 0 && targetPkg != null) { 5915 try { 5916 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5917 if (targetUid < 0) { 5918 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5919 "Can't grant URI permission no uid for: " + targetPkg); 5920 return -1; 5921 } 5922 } catch (RemoteException ex) { 5923 return -1; 5924 } 5925 } 5926 5927 if (targetUid >= 0) { 5928 // First... does the target actually need this permission? 5929 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5930 // No need to grant the target this permission. 5931 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5932 "Target " + targetPkg + " already has full permission to " + uri); 5933 return -1; 5934 } 5935 } else { 5936 // First... there is no target package, so can anyone access it? 5937 boolean allowed = pi.exported; 5938 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5939 if (pi.readPermission != null) { 5940 allowed = false; 5941 } 5942 } 5943 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5944 if (pi.writePermission != null) { 5945 allowed = false; 5946 } 5947 } 5948 if (allowed) { 5949 return -1; 5950 } 5951 } 5952 5953 // Second... is the provider allowing granting of URI permissions? 5954 if (!pi.grantUriPermissions) { 5955 throw new SecurityException("Provider " + pi.packageName 5956 + "/" + pi.name 5957 + " does not allow granting of Uri permissions (uri " 5958 + uri + ")"); 5959 } 5960 if (pi.uriPermissionPatterns != null) { 5961 final int N = pi.uriPermissionPatterns.length; 5962 boolean allowed = false; 5963 for (int i=0; i<N; i++) { 5964 if (pi.uriPermissionPatterns[i] != null 5965 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5966 allowed = true; 5967 break; 5968 } 5969 } 5970 if (!allowed) { 5971 throw new SecurityException("Provider " + pi.packageName 5972 + "/" + pi.name 5973 + " does not allow granting of permission to path of Uri " 5974 + uri); 5975 } 5976 } 5977 5978 // Third... does the caller itself have permission to access 5979 // this uri? 5980 if (callingUid != Process.myUid()) { 5981 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5982 // Require they hold a strong enough Uri permission 5983 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 5984 : UriPermission.STRENGTH_OWNED; 5985 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 5986 throw new SecurityException("Uid " + callingUid 5987 + " does not have permission to uri " + uri); 5988 } 5989 } 5990 } 5991 5992 return targetUid; 5993 } 5994 5995 @Override 5996 public int checkGrantUriPermission(int callingUid, String targetPkg, 5997 Uri uri, int modeFlags) { 5998 enforceNotIsolatedCaller("checkGrantUriPermission"); 5999 synchronized(this) { 6000 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6001 } 6002 } 6003 6004 void grantUriPermissionUncheckedLocked( 6005 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6006 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6007 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6008 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6009 if (modeFlags == 0) { 6010 return; 6011 } 6012 6013 // So here we are: the caller has the assumed permission 6014 // to the uri, and the target doesn't. Let's now give this to 6015 // the target. 6016 6017 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6018 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6019 6020 final String authority = uri.getAuthority(); 6021 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6022 if (pi == null) { 6023 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6024 return; 6025 } 6026 6027 final UriPermission perm = findOrCreateUriPermissionLocked( 6028 pi.packageName, targetPkg, targetUid, uri); 6029 perm.grantModes(modeFlags, persistable, owner); 6030 } 6031 6032 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6033 int modeFlags, UriPermissionOwner owner) { 6034 if (targetPkg == null) { 6035 throw new NullPointerException("targetPkg"); 6036 } 6037 6038 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6039 if (targetUid < 0) { 6040 return; 6041 } 6042 6043 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6044 } 6045 6046 static class NeededUriGrants extends ArrayList<Uri> { 6047 final String targetPkg; 6048 final int targetUid; 6049 final int flags; 6050 6051 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6052 this.targetPkg = targetPkg; 6053 this.targetUid = targetUid; 6054 this.flags = flags; 6055 } 6056 } 6057 6058 /** 6059 * Like checkGrantUriPermissionLocked, but takes an Intent. 6060 */ 6061 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6062 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6063 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6064 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6065 + " clip=" + (intent != null ? intent.getClipData() : null) 6066 + " from " + intent + "; flags=0x" 6067 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6068 6069 if (targetPkg == null) { 6070 throw new NullPointerException("targetPkg"); 6071 } 6072 6073 if (intent == null) { 6074 return null; 6075 } 6076 Uri data = intent.getData(); 6077 ClipData clip = intent.getClipData(); 6078 if (data == null && clip == null) { 6079 return null; 6080 } 6081 6082 if (data != null) { 6083 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6084 mode, needed != null ? needed.targetUid : -1); 6085 if (targetUid > 0) { 6086 if (needed == null) { 6087 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6088 } 6089 needed.add(data); 6090 } 6091 } 6092 if (clip != null) { 6093 for (int i=0; i<clip.getItemCount(); i++) { 6094 Uri uri = clip.getItemAt(i).getUri(); 6095 if (uri != null) { 6096 int targetUid = -1; 6097 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6098 mode, needed != null ? needed.targetUid : -1); 6099 if (targetUid > 0) { 6100 if (needed == null) { 6101 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6102 } 6103 needed.add(uri); 6104 } 6105 } else { 6106 Intent clipIntent = clip.getItemAt(i).getIntent(); 6107 if (clipIntent != null) { 6108 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6109 callingUid, targetPkg, clipIntent, mode, needed); 6110 if (newNeeded != null) { 6111 needed = newNeeded; 6112 } 6113 } 6114 } 6115 } 6116 } 6117 6118 return needed; 6119 } 6120 6121 /** 6122 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6123 */ 6124 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6125 UriPermissionOwner owner) { 6126 if (needed != null) { 6127 for (int i=0; i<needed.size(); i++) { 6128 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6129 needed.get(i), needed.flags, owner); 6130 } 6131 } 6132 } 6133 6134 void grantUriPermissionFromIntentLocked(int callingUid, 6135 String targetPkg, Intent intent, UriPermissionOwner owner) { 6136 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6137 intent, intent != null ? intent.getFlags() : 0, null); 6138 if (needed == null) { 6139 return; 6140 } 6141 6142 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6143 } 6144 6145 @Override 6146 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6147 Uri uri, int modeFlags) { 6148 enforceNotIsolatedCaller("grantUriPermission"); 6149 synchronized(this) { 6150 final ProcessRecord r = getRecordForAppLocked(caller); 6151 if (r == null) { 6152 throw new SecurityException("Unable to find app for caller " 6153 + caller 6154 + " when granting permission to uri " + uri); 6155 } 6156 if (targetPkg == null) { 6157 throw new IllegalArgumentException("null target"); 6158 } 6159 if (uri == null) { 6160 throw new IllegalArgumentException("null uri"); 6161 } 6162 6163 // Persistable only supported through Intents 6164 Preconditions.checkFlagsArgument(modeFlags, 6165 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6166 6167 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6168 null); 6169 } 6170 } 6171 6172 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6173 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6174 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6175 ArrayMap<Uri, UriPermission> perms 6176 = mGrantedUriPermissions.get(perm.targetUid); 6177 if (perms != null) { 6178 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6179 "Removing " + perm.targetUid + " permission to " + perm.uri); 6180 perms.remove(perm.uri); 6181 if (perms.size() == 0) { 6182 mGrantedUriPermissions.remove(perm.targetUid); 6183 } 6184 } 6185 } 6186 } 6187 6188 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6189 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6190 6191 final IPackageManager pm = AppGlobals.getPackageManager(); 6192 final String authority = uri.getAuthority(); 6193 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6194 if (pi == null) { 6195 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6196 return; 6197 } 6198 6199 // Does the caller have this permission on the URI? 6200 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6201 // Right now, if you are not the original owner of the permission, 6202 // you are not allowed to revoke it. 6203 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6204 throw new SecurityException("Uid " + callingUid 6205 + " does not have permission to uri " + uri); 6206 //} 6207 } 6208 6209 boolean persistChanged = false; 6210 6211 // Go through all of the permissions and remove any that match. 6212 final List<String> SEGMENTS = uri.getPathSegments(); 6213 if (SEGMENTS != null) { 6214 final int NS = SEGMENTS.size(); 6215 int N = mGrantedUriPermissions.size(); 6216 for (int i=0; i<N; i++) { 6217 ArrayMap<Uri, UriPermission> perms 6218 = mGrantedUriPermissions.valueAt(i); 6219 Iterator<UriPermission> it = perms.values().iterator(); 6220 toploop: 6221 while (it.hasNext()) { 6222 UriPermission perm = it.next(); 6223 Uri targetUri = perm.uri; 6224 if (!authority.equals(targetUri.getAuthority())) { 6225 continue; 6226 } 6227 List<String> targetSegments = targetUri.getPathSegments(); 6228 if (targetSegments == null) { 6229 continue; 6230 } 6231 if (targetSegments.size() < NS) { 6232 continue; 6233 } 6234 for (int j=0; j<NS; j++) { 6235 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6236 continue toploop; 6237 } 6238 } 6239 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6240 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6241 persistChanged |= perm.clearModes(modeFlags, true); 6242 if (perm.modeFlags == 0) { 6243 it.remove(); 6244 } 6245 } 6246 if (perms.size() == 0) { 6247 mGrantedUriPermissions.remove( 6248 mGrantedUriPermissions.keyAt(i)); 6249 N--; 6250 i--; 6251 } 6252 } 6253 } 6254 6255 if (persistChanged) { 6256 schedulePersistUriGrants(); 6257 } 6258 } 6259 6260 @Override 6261 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6262 int modeFlags) { 6263 enforceNotIsolatedCaller("revokeUriPermission"); 6264 synchronized(this) { 6265 final ProcessRecord r = getRecordForAppLocked(caller); 6266 if (r == null) { 6267 throw new SecurityException("Unable to find app for caller " 6268 + caller 6269 + " when revoking permission to uri " + uri); 6270 } 6271 if (uri == null) { 6272 Slog.w(TAG, "revokeUriPermission: null uri"); 6273 return; 6274 } 6275 6276 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6277 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6278 if (modeFlags == 0) { 6279 return; 6280 } 6281 6282 final IPackageManager pm = AppGlobals.getPackageManager(); 6283 final String authority = uri.getAuthority(); 6284 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6285 if (pi == null) { 6286 Slog.w(TAG, "No content provider found for permission revoke: " 6287 + uri.toSafeString()); 6288 return; 6289 } 6290 6291 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6292 } 6293 } 6294 6295 /** 6296 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6297 * given package. 6298 * 6299 * @param packageName Package name to match, or {@code null} to apply to all 6300 * packages. 6301 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6302 * to all users. 6303 * @param persistable If persistable grants should be removed. 6304 */ 6305 private void removeUriPermissionsForPackageLocked( 6306 String packageName, int userHandle, boolean persistable) { 6307 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6308 throw new IllegalArgumentException("Must narrow by either package or user"); 6309 } 6310 6311 boolean persistChanged = false; 6312 6313 final int size = mGrantedUriPermissions.size(); 6314 for (int i = 0; i < size; i++) { 6315 // Only inspect grants matching user 6316 if (userHandle == UserHandle.USER_ALL 6317 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6318 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6319 .values().iterator(); 6320 while (it.hasNext()) { 6321 final UriPermission perm = it.next(); 6322 6323 // Only inspect grants matching package 6324 if (packageName == null || perm.sourcePkg.equals(packageName) 6325 || perm.targetPkg.equals(packageName)) { 6326 persistChanged |= perm.clearModes(~0, persistable); 6327 6328 // Only remove when no modes remain; any persisted grants 6329 // will keep this alive. 6330 if (perm.modeFlags == 0) { 6331 it.remove(); 6332 } 6333 } 6334 } 6335 } 6336 } 6337 6338 if (persistChanged) { 6339 schedulePersistUriGrants(); 6340 } 6341 } 6342 6343 @Override 6344 public IBinder newUriPermissionOwner(String name) { 6345 enforceNotIsolatedCaller("newUriPermissionOwner"); 6346 synchronized(this) { 6347 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6348 return owner.getExternalTokenLocked(); 6349 } 6350 } 6351 6352 @Override 6353 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6354 Uri uri, int modeFlags) { 6355 synchronized(this) { 6356 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6357 if (owner == null) { 6358 throw new IllegalArgumentException("Unknown owner: " + token); 6359 } 6360 if (fromUid != Binder.getCallingUid()) { 6361 if (Binder.getCallingUid() != Process.myUid()) { 6362 // Only system code can grant URI permissions on behalf 6363 // of other users. 6364 throw new SecurityException("nice try"); 6365 } 6366 } 6367 if (targetPkg == null) { 6368 throw new IllegalArgumentException("null target"); 6369 } 6370 if (uri == null) { 6371 throw new IllegalArgumentException("null uri"); 6372 } 6373 6374 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6375 } 6376 } 6377 6378 @Override 6379 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6380 synchronized(this) { 6381 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6382 if (owner == null) { 6383 throw new IllegalArgumentException("Unknown owner: " + token); 6384 } 6385 6386 if (uri == null) { 6387 owner.removeUriPermissionsLocked(mode); 6388 } else { 6389 owner.removeUriPermissionLocked(uri, mode); 6390 } 6391 } 6392 } 6393 6394 private void schedulePersistUriGrants() { 6395 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6396 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6397 10 * DateUtils.SECOND_IN_MILLIS); 6398 } 6399 } 6400 6401 private void writeGrantedUriPermissions() { 6402 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6403 6404 // Snapshot permissions so we can persist without lock 6405 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6406 synchronized (this) { 6407 final int size = mGrantedUriPermissions.size(); 6408 for (int i = 0 ; i < size; i++) { 6409 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6410 if (perm.persistedModeFlags != 0) { 6411 persist.add(perm.snapshot()); 6412 } 6413 } 6414 } 6415 } 6416 6417 FileOutputStream fos = null; 6418 try { 6419 fos = mGrantFile.startWrite(); 6420 6421 XmlSerializer out = new FastXmlSerializer(); 6422 out.setOutput(fos, "utf-8"); 6423 out.startDocument(null, true); 6424 out.startTag(null, TAG_URI_GRANTS); 6425 for (UriPermission.Snapshot perm : persist) { 6426 out.startTag(null, TAG_URI_GRANT); 6427 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6428 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6429 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6430 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6431 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6432 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6433 out.endTag(null, TAG_URI_GRANT); 6434 } 6435 out.endTag(null, TAG_URI_GRANTS); 6436 out.endDocument(); 6437 6438 mGrantFile.finishWrite(fos); 6439 } catch (IOException e) { 6440 if (fos != null) { 6441 mGrantFile.failWrite(fos); 6442 } 6443 } 6444 } 6445 6446 private void readGrantedUriPermissionsLocked() { 6447 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6448 6449 final long now = System.currentTimeMillis(); 6450 6451 FileInputStream fis = null; 6452 try { 6453 fis = mGrantFile.openRead(); 6454 final XmlPullParser in = Xml.newPullParser(); 6455 in.setInput(fis, null); 6456 6457 int type; 6458 while ((type = in.next()) != END_DOCUMENT) { 6459 final String tag = in.getName(); 6460 if (type == START_TAG) { 6461 if (TAG_URI_GRANT.equals(tag)) { 6462 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6463 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6464 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6465 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6466 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6467 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6468 6469 // Sanity check that provider still belongs to source package 6470 final ProviderInfo pi = getProviderInfoLocked( 6471 uri.getAuthority(), userHandle); 6472 if (pi != null && sourcePkg.equals(pi.packageName)) { 6473 int targetUid = -1; 6474 try { 6475 targetUid = AppGlobals.getPackageManager() 6476 .getPackageUid(targetPkg, userHandle); 6477 } catch (RemoteException e) { 6478 } 6479 if (targetUid != -1) { 6480 final UriPermission perm = findOrCreateUriPermissionLocked( 6481 sourcePkg, targetPkg, targetUid, uri); 6482 perm.initPersistedModes(modeFlags, createdTime); 6483 } 6484 } else { 6485 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6486 + " but instead found " + pi); 6487 } 6488 } 6489 } 6490 } 6491 } catch (FileNotFoundException e) { 6492 // Missing grants is okay 6493 } catch (IOException e) { 6494 Log.wtf(TAG, "Failed reading Uri grants", e); 6495 } catch (XmlPullParserException e) { 6496 Log.wtf(TAG, "Failed reading Uri grants", e); 6497 } finally { 6498 IoUtils.closeQuietly(fis); 6499 } 6500 } 6501 6502 @Override 6503 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6504 enforceNotIsolatedCaller("takePersistableUriPermission"); 6505 6506 Preconditions.checkFlagsArgument(modeFlags, 6507 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6508 6509 synchronized (this) { 6510 final int callingUid = Binder.getCallingUid(); 6511 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6512 if (perm == null) { 6513 throw new SecurityException("No permission grant found for UID " + callingUid 6514 + " and Uri " + uri.toSafeString()); 6515 } 6516 6517 boolean persistChanged = perm.takePersistableModes(modeFlags); 6518 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6519 6520 if (persistChanged) { 6521 schedulePersistUriGrants(); 6522 } 6523 } 6524 } 6525 6526 @Override 6527 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6528 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6529 6530 Preconditions.checkFlagsArgument(modeFlags, 6531 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6532 6533 synchronized (this) { 6534 final int callingUid = Binder.getCallingUid(); 6535 6536 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6537 if (perm == null) { 6538 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6539 + uri.toSafeString()); 6540 return; 6541 } 6542 6543 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6544 removeUriPermissionIfNeededLocked(perm); 6545 if (persistChanged) { 6546 schedulePersistUriGrants(); 6547 } 6548 } 6549 } 6550 6551 /** 6552 * Prune any older {@link UriPermission} for the given UID until outstanding 6553 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6554 * 6555 * @return if any mutations occured that require persisting. 6556 */ 6557 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6558 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6559 if (perms == null) return false; 6560 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6561 6562 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6563 for (UriPermission perm : perms.values()) { 6564 if (perm.persistedModeFlags != 0) { 6565 persisted.add(perm); 6566 } 6567 } 6568 6569 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6570 if (trimCount <= 0) return false; 6571 6572 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6573 for (int i = 0; i < trimCount; i++) { 6574 final UriPermission perm = persisted.get(i); 6575 6576 if (DEBUG_URI_PERMISSION) { 6577 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6578 } 6579 6580 perm.releasePersistableModes(~0); 6581 removeUriPermissionIfNeededLocked(perm); 6582 } 6583 6584 return true; 6585 } 6586 6587 @Override 6588 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6589 String packageName, boolean incoming) { 6590 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6591 Preconditions.checkNotNull(packageName, "packageName"); 6592 6593 final int callingUid = Binder.getCallingUid(); 6594 final IPackageManager pm = AppGlobals.getPackageManager(); 6595 try { 6596 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6597 if (packageUid != callingUid) { 6598 throw new SecurityException( 6599 "Package " + packageName + " does not belong to calling UID " + callingUid); 6600 } 6601 } catch (RemoteException e) { 6602 throw new SecurityException("Failed to verify package name ownership"); 6603 } 6604 6605 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6606 synchronized (this) { 6607 if (incoming) { 6608 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6609 if (perms == null) { 6610 Slog.w(TAG, "No permission grants found for " + packageName); 6611 } else { 6612 final int size = perms.size(); 6613 for (int i = 0; i < size; i++) { 6614 final UriPermission perm = perms.valueAt(i); 6615 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6616 result.add(perm.buildPersistedPublicApiObject()); 6617 } 6618 } 6619 } 6620 } else { 6621 final int size = mGrantedUriPermissions.size(); 6622 for (int i = 0; i < size; i++) { 6623 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6624 final int permsSize = perms.size(); 6625 for (int j = 0; j < permsSize; j++) { 6626 final UriPermission perm = perms.valueAt(j); 6627 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6628 result.add(perm.buildPersistedPublicApiObject()); 6629 } 6630 } 6631 } 6632 } 6633 } 6634 return new ParceledListSlice<android.content.UriPermission>(result); 6635 } 6636 6637 @Override 6638 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6639 synchronized (this) { 6640 ProcessRecord app = 6641 who != null ? getRecordForAppLocked(who) : null; 6642 if (app == null) return; 6643 6644 Message msg = Message.obtain(); 6645 msg.what = WAIT_FOR_DEBUGGER_MSG; 6646 msg.obj = app; 6647 msg.arg1 = waiting ? 1 : 0; 6648 mHandler.sendMessage(msg); 6649 } 6650 } 6651 6652 @Override 6653 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6654 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6655 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6656 outInfo.availMem = Process.getFreeMemory(); 6657 outInfo.totalMem = Process.getTotalMemory(); 6658 outInfo.threshold = homeAppMem; 6659 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6660 outInfo.hiddenAppThreshold = cachedAppMem; 6661 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6662 ProcessList.SERVICE_ADJ); 6663 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6664 ProcessList.VISIBLE_APP_ADJ); 6665 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6666 ProcessList.FOREGROUND_APP_ADJ); 6667 } 6668 6669 // ========================================================= 6670 // TASK MANAGEMENT 6671 // ========================================================= 6672 6673 @Override 6674 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6675 IThumbnailReceiver receiver) { 6676 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6677 6678 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6679 ActivityRecord topRecord = null; 6680 6681 synchronized(this) { 6682 if (localLOGV) Slog.v( 6683 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6684 + ", receiver=" + receiver); 6685 6686 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6687 != PackageManager.PERMISSION_GRANTED) { 6688 if (receiver != null) { 6689 // If the caller wants to wait for pending thumbnails, 6690 // it ain't gonna get them. 6691 try { 6692 receiver.finished(); 6693 } catch (RemoteException ex) { 6694 } 6695 } 6696 String msg = "Permission Denial: getTasks() from pid=" 6697 + Binder.getCallingPid() 6698 + ", uid=" + Binder.getCallingUid() 6699 + " requires " + android.Manifest.permission.GET_TASKS; 6700 Slog.w(TAG, msg); 6701 throw new SecurityException(msg); 6702 } 6703 6704 // TODO: Improve with MRU list from all ActivityStacks. 6705 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6706 6707 if (!pending.pendingRecords.isEmpty()) { 6708 mPendingThumbnails.add(pending); 6709 } 6710 } 6711 6712 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6713 6714 if (topRecord != null) { 6715 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6716 try { 6717 IApplicationThread topThumbnail = topRecord.app.thread; 6718 topThumbnail.requestThumbnail(topRecord.appToken); 6719 } catch (Exception e) { 6720 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6721 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6722 } 6723 } 6724 6725 if (pending == null && receiver != null) { 6726 // In this case all thumbnails were available and the client 6727 // is being asked to be told when the remaining ones come in... 6728 // which is unusually, since the top-most currently running 6729 // activity should never have a canned thumbnail! Oh well. 6730 try { 6731 receiver.finished(); 6732 } catch (RemoteException ex) { 6733 } 6734 } 6735 6736 return list; 6737 } 6738 6739 TaskRecord getMostRecentTask() { 6740 return mRecentTasks.get(0); 6741 } 6742 6743 @Override 6744 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6745 int flags, int userId) { 6746 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6747 false, true, "getRecentTasks", null); 6748 6749 synchronized (this) { 6750 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6751 "getRecentTasks()"); 6752 final boolean detailed = checkCallingPermission( 6753 android.Manifest.permission.GET_DETAILED_TASKS) 6754 == PackageManager.PERMISSION_GRANTED; 6755 6756 IPackageManager pm = AppGlobals.getPackageManager(); 6757 6758 final int N = mRecentTasks.size(); 6759 ArrayList<ActivityManager.RecentTaskInfo> res 6760 = new ArrayList<ActivityManager.RecentTaskInfo>( 6761 maxNum < N ? maxNum : N); 6762 for (int i=0; i<N && maxNum > 0; i++) { 6763 TaskRecord tr = mRecentTasks.get(i); 6764 // Only add calling user's recent tasks 6765 if (tr.userId != userId) continue; 6766 // Return the entry if desired by the caller. We always return 6767 // the first entry, because callers always expect this to be the 6768 // foreground app. We may filter others if the caller has 6769 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6770 // we should exclude the entry. 6771 6772 if (i == 0 6773 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6774 || (tr.intent == null) 6775 || ((tr.intent.getFlags() 6776 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6777 ActivityManager.RecentTaskInfo rti 6778 = new ActivityManager.RecentTaskInfo(); 6779 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6780 rti.persistentId = tr.taskId; 6781 rti.baseIntent = new Intent( 6782 tr.intent != null ? tr.intent : tr.affinityIntent); 6783 if (!detailed) { 6784 rti.baseIntent.replaceExtras((Bundle)null); 6785 } 6786 rti.origActivity = tr.origActivity; 6787 rti.description = tr.lastDescription; 6788 rti.stackId = tr.stack.mStackId; 6789 6790 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6791 // Check whether this activity is currently available. 6792 try { 6793 if (rti.origActivity != null) { 6794 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6795 == null) { 6796 continue; 6797 } 6798 } else if (rti.baseIntent != null) { 6799 if (pm.queryIntentActivities(rti.baseIntent, 6800 null, 0, userId) == null) { 6801 continue; 6802 } 6803 } 6804 } catch (RemoteException e) { 6805 // Will never happen. 6806 } 6807 } 6808 6809 res.add(rti); 6810 maxNum--; 6811 } 6812 } 6813 return res; 6814 } 6815 } 6816 6817 private TaskRecord recentTaskForIdLocked(int id) { 6818 final int N = mRecentTasks.size(); 6819 for (int i=0; i<N; i++) { 6820 TaskRecord tr = mRecentTasks.get(i); 6821 if (tr.taskId == id) { 6822 return tr; 6823 } 6824 } 6825 return null; 6826 } 6827 6828 @Override 6829 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6830 synchronized (this) { 6831 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6832 "getTaskThumbnails()"); 6833 TaskRecord tr = recentTaskForIdLocked(id); 6834 if (tr != null) { 6835 return tr.getTaskThumbnailsLocked(); 6836 } 6837 } 6838 return null; 6839 } 6840 6841 @Override 6842 public Bitmap getTaskTopThumbnail(int id) { 6843 synchronized (this) { 6844 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6845 "getTaskTopThumbnail()"); 6846 TaskRecord tr = recentTaskForIdLocked(id); 6847 if (tr != null) { 6848 return tr.getTaskTopThumbnailLocked(); 6849 } 6850 } 6851 return null; 6852 } 6853 6854 @Override 6855 public boolean removeSubTask(int taskId, int subTaskIndex) { 6856 synchronized (this) { 6857 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6858 "removeSubTask()"); 6859 long ident = Binder.clearCallingIdentity(); 6860 try { 6861 TaskRecord tr = recentTaskForIdLocked(taskId); 6862 if (tr != null) { 6863 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6864 } 6865 return false; 6866 } finally { 6867 Binder.restoreCallingIdentity(ident); 6868 } 6869 } 6870 } 6871 6872 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6873 if (!pr.killedByAm) { 6874 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6875 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6876 pr.processName, pr.setAdj, reason); 6877 pr.killedByAm = true; 6878 Process.killProcessQuiet(pr.pid); 6879 } 6880 } 6881 6882 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6883 tr.disposeThumbnail(); 6884 mRecentTasks.remove(tr); 6885 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6886 Intent baseIntent = new Intent( 6887 tr.intent != null ? tr.intent : tr.affinityIntent); 6888 ComponentName component = baseIntent.getComponent(); 6889 if (component == null) { 6890 Slog.w(TAG, "Now component for base intent of task: " + tr); 6891 return; 6892 } 6893 6894 // Find any running services associated with this app. 6895 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6896 6897 if (killProcesses) { 6898 // Find any running processes associated with this app. 6899 final String pkg = component.getPackageName(); 6900 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6901 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 6902 for (int i=0; i<pmap.size(); i++) { 6903 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 6904 for (int j=0; j<uids.size(); j++) { 6905 ProcessRecord proc = uids.valueAt(j); 6906 if (proc.userId != tr.userId) { 6907 continue; 6908 } 6909 if (!proc.pkgList.containsKey(pkg)) { 6910 continue; 6911 } 6912 procs.add(proc); 6913 } 6914 } 6915 6916 // Kill the running processes. 6917 for (int i=0; i<procs.size(); i++) { 6918 ProcessRecord pr = procs.get(i); 6919 if (pr == mHomeProcess) { 6920 // Don't kill the home process along with tasks from the same package. 6921 continue; 6922 } 6923 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 6924 killUnneededProcessLocked(pr, "remove task"); 6925 } else { 6926 pr.waitingToKill = "remove task"; 6927 } 6928 } 6929 } 6930 } 6931 6932 @Override 6933 public boolean removeTask(int taskId, int flags) { 6934 synchronized (this) { 6935 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6936 "removeTask()"); 6937 long ident = Binder.clearCallingIdentity(); 6938 try { 6939 TaskRecord tr = recentTaskForIdLocked(taskId); 6940 if (tr != null) { 6941 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 6942 if (r != null) { 6943 cleanUpRemovedTaskLocked(tr, flags); 6944 return true; 6945 } 6946 if (tr.mActivities.size() == 0) { 6947 // Caller is just removing a recent task that is 6948 // not actively running. That is easy! 6949 cleanUpRemovedTaskLocked(tr, flags); 6950 return true; 6951 } 6952 Slog.w(TAG, "removeTask: task " + taskId 6953 + " does not have activities to remove, " 6954 + " but numActivities=" + tr.numActivities 6955 + ": " + tr); 6956 } 6957 } finally { 6958 Binder.restoreCallingIdentity(ident); 6959 } 6960 } 6961 return false; 6962 } 6963 6964 /** 6965 * TODO: Add mController hook 6966 */ 6967 @Override 6968 public void moveTaskToFront(int task, int flags, Bundle options) { 6969 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6970 "moveTaskToFront()"); 6971 6972 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task); 6973 synchronized(this) { 6974 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6975 Binder.getCallingUid(), "Task to front")) { 6976 ActivityOptions.abort(options); 6977 return; 6978 } 6979 final long origId = Binder.clearCallingIdentity(); 6980 try { 6981 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 6982 } finally { 6983 Binder.restoreCallingIdentity(origId); 6984 } 6985 ActivityOptions.abort(options); 6986 } 6987 } 6988 6989 @Override 6990 public void moveTaskToBack(int taskId) { 6991 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6992 "moveTaskToBack()"); 6993 6994 synchronized(this) { 6995 TaskRecord tr = recentTaskForIdLocked(taskId); 6996 if (tr != null) { 6997 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 6998 ActivityStack stack = tr.stack; 6999 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7000 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7001 Binder.getCallingUid(), "Task to back")) { 7002 return; 7003 } 7004 } 7005 final long origId = Binder.clearCallingIdentity(); 7006 try { 7007 stack.moveTaskToBackLocked(taskId, null); 7008 } finally { 7009 Binder.restoreCallingIdentity(origId); 7010 } 7011 } 7012 } 7013 } 7014 7015 /** 7016 * Moves an activity, and all of the other activities within the same task, to the bottom 7017 * of the history stack. The activity's order within the task is unchanged. 7018 * 7019 * @param token A reference to the activity we wish to move 7020 * @param nonRoot If false then this only works if the activity is the root 7021 * of a task; if true it will work for any activity in a task. 7022 * @return Returns true if the move completed, false if not. 7023 */ 7024 @Override 7025 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7026 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7027 synchronized(this) { 7028 final long origId = Binder.clearCallingIdentity(); 7029 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7030 if (taskId >= 0) { 7031 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7032 } 7033 Binder.restoreCallingIdentity(origId); 7034 } 7035 return false; 7036 } 7037 7038 @Override 7039 public void moveTaskBackwards(int task) { 7040 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7041 "moveTaskBackwards()"); 7042 7043 synchronized(this) { 7044 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7045 Binder.getCallingUid(), "Task backwards")) { 7046 return; 7047 } 7048 final long origId = Binder.clearCallingIdentity(); 7049 moveTaskBackwardsLocked(task); 7050 Binder.restoreCallingIdentity(origId); 7051 } 7052 } 7053 7054 private final void moveTaskBackwardsLocked(int task) { 7055 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7056 } 7057 7058 @Override 7059 public IBinder getHomeActivityToken() throws RemoteException { 7060 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7061 "getHomeActivityToken()"); 7062 synchronized (this) { 7063 return mStackSupervisor.getHomeActivityToken(); 7064 } 7065 } 7066 7067 @Override 7068 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7069 IActivityContainerCallback callback) throws RemoteException { 7070 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7071 "createActivityContainer()"); 7072 synchronized (this) { 7073 if (parentActivityToken == null) { 7074 throw new IllegalArgumentException("parent token must not be null"); 7075 } 7076 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7077 if (r == null) { 7078 return null; 7079 } 7080 return mStackSupervisor.createActivityContainer(r, callback); 7081 } 7082 } 7083 7084 @Override 7085 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7086 throws RemoteException { 7087 synchronized (this) { 7088 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7089 if (stack != null) { 7090 return stack.mActivityContainer; 7091 } 7092 return null; 7093 } 7094 } 7095 7096 @Override 7097 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7098 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7099 "moveTaskToStack()"); 7100 if (stackId == HOME_STACK_ID) { 7101 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7102 new RuntimeException("here").fillInStackTrace()); 7103 } 7104 synchronized (this) { 7105 long ident = Binder.clearCallingIdentity(); 7106 try { 7107 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7108 + stackId + " toTop=" + toTop); 7109 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7110 } finally { 7111 Binder.restoreCallingIdentity(ident); 7112 } 7113 } 7114 } 7115 7116 @Override 7117 public void resizeStack(int stackBoxId, Rect bounds) { 7118 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7119 "resizeStackBox()"); 7120 long ident = Binder.clearCallingIdentity(); 7121 try { 7122 mWindowManager.resizeStack(stackBoxId, bounds); 7123 } finally { 7124 Binder.restoreCallingIdentity(ident); 7125 } 7126 } 7127 7128 @Override 7129 public List<StackInfo> getAllStackInfos() { 7130 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7131 "getAllStackInfos()"); 7132 long ident = Binder.clearCallingIdentity(); 7133 try { 7134 synchronized (this) { 7135 return mStackSupervisor.getAllStackInfosLocked(); 7136 } 7137 } finally { 7138 Binder.restoreCallingIdentity(ident); 7139 } 7140 } 7141 7142 @Override 7143 public StackInfo getStackInfo(int stackId) { 7144 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7145 "getStackInfo()"); 7146 long ident = Binder.clearCallingIdentity(); 7147 try { 7148 synchronized (this) { 7149 return mStackSupervisor.getStackInfoLocked(stackId); 7150 } 7151 } finally { 7152 Binder.restoreCallingIdentity(ident); 7153 } 7154 } 7155 7156 @Override 7157 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7158 synchronized(this) { 7159 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7160 } 7161 } 7162 7163 // ========================================================= 7164 // THUMBNAILS 7165 // ========================================================= 7166 7167 public void reportThumbnail(IBinder token, 7168 Bitmap thumbnail, CharSequence description) { 7169 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7170 final long origId = Binder.clearCallingIdentity(); 7171 sendPendingThumbnail(null, token, thumbnail, description, true); 7172 Binder.restoreCallingIdentity(origId); 7173 } 7174 7175 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7176 Bitmap thumbnail, CharSequence description, boolean always) { 7177 TaskRecord task; 7178 ArrayList<PendingThumbnailsRecord> receivers = null; 7179 7180 //System.out.println("Send pending thumbnail: " + r); 7181 7182 synchronized(this) { 7183 if (r == null) { 7184 r = ActivityRecord.isInStackLocked(token); 7185 if (r == null) { 7186 return; 7187 } 7188 } 7189 if (thumbnail == null && r.thumbHolder != null) { 7190 thumbnail = r.thumbHolder.lastThumbnail; 7191 description = r.thumbHolder.lastDescription; 7192 } 7193 if (thumbnail == null && !always) { 7194 // If there is no thumbnail, and this entry is not actually 7195 // going away, then abort for now and pick up the next 7196 // thumbnail we get. 7197 return; 7198 } 7199 task = r.task; 7200 7201 int N = mPendingThumbnails.size(); 7202 int i=0; 7203 while (i<N) { 7204 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7205 //System.out.println("Looking in " + pr.pendingRecords); 7206 if (pr.pendingRecords.remove(r)) { 7207 if (receivers == null) { 7208 receivers = new ArrayList<PendingThumbnailsRecord>(); 7209 } 7210 receivers.add(pr); 7211 if (pr.pendingRecords.size() == 0) { 7212 pr.finished = true; 7213 mPendingThumbnails.remove(i); 7214 N--; 7215 continue; 7216 } 7217 } 7218 i++; 7219 } 7220 } 7221 7222 if (receivers != null) { 7223 final int N = receivers.size(); 7224 for (int i=0; i<N; i++) { 7225 try { 7226 PendingThumbnailsRecord pr = receivers.get(i); 7227 pr.receiver.newThumbnail( 7228 task != null ? task.taskId : -1, thumbnail, description); 7229 if (pr.finished) { 7230 pr.receiver.finished(); 7231 } 7232 } catch (Exception e) { 7233 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7234 } 7235 } 7236 } 7237 } 7238 7239 // ========================================================= 7240 // CONTENT PROVIDERS 7241 // ========================================================= 7242 7243 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7244 List<ProviderInfo> providers = null; 7245 try { 7246 providers = AppGlobals.getPackageManager(). 7247 queryContentProviders(app.processName, app.uid, 7248 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7249 } catch (RemoteException ex) { 7250 } 7251 if (DEBUG_MU) 7252 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7253 int userId = app.userId; 7254 if (providers != null) { 7255 int N = providers.size(); 7256 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7257 for (int i=0; i<N; i++) { 7258 ProviderInfo cpi = 7259 (ProviderInfo)providers.get(i); 7260 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7261 cpi.name, cpi.flags); 7262 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7263 // This is a singleton provider, but a user besides the 7264 // default user is asking to initialize a process it runs 7265 // in... well, no, it doesn't actually run in this process, 7266 // it runs in the process of the default user. Get rid of it. 7267 providers.remove(i); 7268 N--; 7269 i--; 7270 continue; 7271 } 7272 7273 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7274 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7275 if (cpr == null) { 7276 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7277 mProviderMap.putProviderByClass(comp, cpr); 7278 } 7279 if (DEBUG_MU) 7280 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7281 app.pubProviders.put(cpi.name, cpr); 7282 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7283 // Don't add this if it is a platform component that is marked 7284 // to run in multiple processes, because this is actually 7285 // part of the framework so doesn't make sense to track as a 7286 // separate apk in the process. 7287 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7288 } 7289 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7290 } 7291 } 7292 return providers; 7293 } 7294 7295 /** 7296 * Check if {@link ProcessRecord} has a possible chance at accessing the 7297 * given {@link ProviderInfo}. Final permission checking is always done 7298 * in {@link ContentProvider}. 7299 */ 7300 private final String checkContentProviderPermissionLocked( 7301 ProviderInfo cpi, ProcessRecord r) { 7302 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7303 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7304 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7305 cpi.applicationInfo.uid, cpi.exported) 7306 == PackageManager.PERMISSION_GRANTED) { 7307 return null; 7308 } 7309 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7310 cpi.applicationInfo.uid, cpi.exported) 7311 == PackageManager.PERMISSION_GRANTED) { 7312 return null; 7313 } 7314 7315 PathPermission[] pps = cpi.pathPermissions; 7316 if (pps != null) { 7317 int i = pps.length; 7318 while (i > 0) { 7319 i--; 7320 PathPermission pp = pps[i]; 7321 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7322 cpi.applicationInfo.uid, cpi.exported) 7323 == PackageManager.PERMISSION_GRANTED) { 7324 return null; 7325 } 7326 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7327 cpi.applicationInfo.uid, cpi.exported) 7328 == PackageManager.PERMISSION_GRANTED) { 7329 return null; 7330 } 7331 } 7332 } 7333 7334 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7335 if (perms != null) { 7336 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7337 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7338 return null; 7339 } 7340 } 7341 } 7342 7343 String msg; 7344 if (!cpi.exported) { 7345 msg = "Permission Denial: opening provider " + cpi.name 7346 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7347 + ", uid=" + callingUid + ") that is not exported from uid " 7348 + cpi.applicationInfo.uid; 7349 } else { 7350 msg = "Permission Denial: opening provider " + cpi.name 7351 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7352 + ", uid=" + callingUid + ") requires " 7353 + cpi.readPermission + " or " + cpi.writePermission; 7354 } 7355 Slog.w(TAG, msg); 7356 return msg; 7357 } 7358 7359 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7360 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7361 if (r != null) { 7362 for (int i=0; i<r.conProviders.size(); i++) { 7363 ContentProviderConnection conn = r.conProviders.get(i); 7364 if (conn.provider == cpr) { 7365 if (DEBUG_PROVIDER) Slog.v(TAG, 7366 "Adding provider requested by " 7367 + r.processName + " from process " 7368 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7369 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7370 if (stable) { 7371 conn.stableCount++; 7372 conn.numStableIncs++; 7373 } else { 7374 conn.unstableCount++; 7375 conn.numUnstableIncs++; 7376 } 7377 return conn; 7378 } 7379 } 7380 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7381 if (stable) { 7382 conn.stableCount = 1; 7383 conn.numStableIncs = 1; 7384 } else { 7385 conn.unstableCount = 1; 7386 conn.numUnstableIncs = 1; 7387 } 7388 cpr.connections.add(conn); 7389 r.conProviders.add(conn); 7390 return conn; 7391 } 7392 cpr.addExternalProcessHandleLocked(externalProcessToken); 7393 return null; 7394 } 7395 7396 boolean decProviderCountLocked(ContentProviderConnection conn, 7397 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7398 if (conn != null) { 7399 cpr = conn.provider; 7400 if (DEBUG_PROVIDER) Slog.v(TAG, 7401 "Removing provider requested by " 7402 + conn.client.processName + " from process " 7403 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7404 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7405 if (stable) { 7406 conn.stableCount--; 7407 } else { 7408 conn.unstableCount--; 7409 } 7410 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7411 cpr.connections.remove(conn); 7412 conn.client.conProviders.remove(conn); 7413 return true; 7414 } 7415 return false; 7416 } 7417 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7418 return false; 7419 } 7420 7421 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7422 String name, IBinder token, boolean stable, int userId) { 7423 ContentProviderRecord cpr; 7424 ContentProviderConnection conn = null; 7425 ProviderInfo cpi = null; 7426 7427 synchronized(this) { 7428 ProcessRecord r = null; 7429 if (caller != null) { 7430 r = getRecordForAppLocked(caller); 7431 if (r == null) { 7432 throw new SecurityException( 7433 "Unable to find app for caller " + caller 7434 + " (pid=" + Binder.getCallingPid() 7435 + ") when getting content provider " + name); 7436 } 7437 } 7438 7439 // First check if this content provider has been published... 7440 cpr = mProviderMap.getProviderByName(name, userId); 7441 boolean providerRunning = cpr != null; 7442 if (providerRunning) { 7443 cpi = cpr.info; 7444 String msg; 7445 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7446 throw new SecurityException(msg); 7447 } 7448 7449 if (r != null && cpr.canRunHere(r)) { 7450 // This provider has been published or is in the process 7451 // of being published... but it is also allowed to run 7452 // in the caller's process, so don't make a connection 7453 // and just let the caller instantiate its own instance. 7454 ContentProviderHolder holder = cpr.newHolder(null); 7455 // don't give caller the provider object, it needs 7456 // to make its own. 7457 holder.provider = null; 7458 return holder; 7459 } 7460 7461 final long origId = Binder.clearCallingIdentity(); 7462 7463 // In this case the provider instance already exists, so we can 7464 // return it right away. 7465 conn = incProviderCountLocked(r, cpr, token, stable); 7466 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7467 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7468 // If this is a perceptible app accessing the provider, 7469 // make sure to count it as being accessed and thus 7470 // back up on the LRU list. This is good because 7471 // content providers are often expensive to start. 7472 updateLruProcessLocked(cpr.proc, false, null); 7473 } 7474 } 7475 7476 if (cpr.proc != null) { 7477 if (false) { 7478 if (cpr.name.flattenToShortString().equals( 7479 "com.android.providers.calendar/.CalendarProvider2")) { 7480 Slog.v(TAG, "****************** KILLING " 7481 + cpr.name.flattenToShortString()); 7482 Process.killProcess(cpr.proc.pid); 7483 } 7484 } 7485 boolean success = updateOomAdjLocked(cpr.proc); 7486 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7487 // NOTE: there is still a race here where a signal could be 7488 // pending on the process even though we managed to update its 7489 // adj level. Not sure what to do about this, but at least 7490 // the race is now smaller. 7491 if (!success) { 7492 // Uh oh... it looks like the provider's process 7493 // has been killed on us. We need to wait for a new 7494 // process to be started, and make sure its death 7495 // doesn't kill our process. 7496 Slog.i(TAG, 7497 "Existing provider " + cpr.name.flattenToShortString() 7498 + " is crashing; detaching " + r); 7499 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7500 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7501 if (!lastRef) { 7502 // This wasn't the last ref our process had on 7503 // the provider... we have now been killed, bail. 7504 return null; 7505 } 7506 providerRunning = false; 7507 conn = null; 7508 } 7509 } 7510 7511 Binder.restoreCallingIdentity(origId); 7512 } 7513 7514 boolean singleton; 7515 if (!providerRunning) { 7516 try { 7517 cpi = AppGlobals.getPackageManager(). 7518 resolveContentProvider(name, 7519 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7520 } catch (RemoteException ex) { 7521 } 7522 if (cpi == null) { 7523 return null; 7524 } 7525 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7526 cpi.name, cpi.flags); 7527 if (singleton) { 7528 userId = 0; 7529 } 7530 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7531 7532 String msg; 7533 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7534 throw new SecurityException(msg); 7535 } 7536 7537 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7538 && !cpi.processName.equals("system")) { 7539 // If this content provider does not run in the system 7540 // process, and the system is not yet ready to run other 7541 // processes, then fail fast instead of hanging. 7542 throw new IllegalArgumentException( 7543 "Attempt to launch content provider before system ready"); 7544 } 7545 7546 // Make sure that the user who owns this provider is started. If not, 7547 // we don't want to allow it to run. 7548 if (mStartedUsers.get(userId) == null) { 7549 Slog.w(TAG, "Unable to launch app " 7550 + cpi.applicationInfo.packageName + "/" 7551 + cpi.applicationInfo.uid + " for provider " 7552 + name + ": user " + userId + " is stopped"); 7553 return null; 7554 } 7555 7556 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7557 cpr = mProviderMap.getProviderByClass(comp, userId); 7558 final boolean firstClass = cpr == null; 7559 if (firstClass) { 7560 try { 7561 ApplicationInfo ai = 7562 AppGlobals.getPackageManager(). 7563 getApplicationInfo( 7564 cpi.applicationInfo.packageName, 7565 STOCK_PM_FLAGS, userId); 7566 if (ai == null) { 7567 Slog.w(TAG, "No package info for content provider " 7568 + cpi.name); 7569 return null; 7570 } 7571 ai = getAppInfoForUser(ai, userId); 7572 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7573 } catch (RemoteException ex) { 7574 // pm is in same process, this will never happen. 7575 } 7576 } 7577 7578 if (r != null && cpr.canRunHere(r)) { 7579 // If this is a multiprocess provider, then just return its 7580 // info and allow the caller to instantiate it. Only do 7581 // this if the provider is the same user as the caller's 7582 // process, or can run as root (so can be in any process). 7583 return cpr.newHolder(null); 7584 } 7585 7586 if (DEBUG_PROVIDER) { 7587 RuntimeException e = new RuntimeException("here"); 7588 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7589 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7590 } 7591 7592 // This is single process, and our app is now connecting to it. 7593 // See if we are already in the process of launching this 7594 // provider. 7595 final int N = mLaunchingProviders.size(); 7596 int i; 7597 for (i=0; i<N; i++) { 7598 if (mLaunchingProviders.get(i) == cpr) { 7599 break; 7600 } 7601 } 7602 7603 // If the provider is not already being launched, then get it 7604 // started. 7605 if (i >= N) { 7606 final long origId = Binder.clearCallingIdentity(); 7607 7608 try { 7609 // Content provider is now in use, its package can't be stopped. 7610 try { 7611 AppGlobals.getPackageManager().setPackageStoppedState( 7612 cpr.appInfo.packageName, false, userId); 7613 } catch (RemoteException e) { 7614 } catch (IllegalArgumentException e) { 7615 Slog.w(TAG, "Failed trying to unstop package " 7616 + cpr.appInfo.packageName + ": " + e); 7617 } 7618 7619 // Use existing process if already started 7620 ProcessRecord proc = getProcessRecordLocked( 7621 cpi.processName, cpr.appInfo.uid, false); 7622 if (proc != null && proc.thread != null) { 7623 if (DEBUG_PROVIDER) { 7624 Slog.d(TAG, "Installing in existing process " + proc); 7625 } 7626 proc.pubProviders.put(cpi.name, cpr); 7627 try { 7628 proc.thread.scheduleInstallProvider(cpi); 7629 } catch (RemoteException e) { 7630 } 7631 } else { 7632 proc = startProcessLocked(cpi.processName, 7633 cpr.appInfo, false, 0, "content provider", 7634 new ComponentName(cpi.applicationInfo.packageName, 7635 cpi.name), false, false, false); 7636 if (proc == null) { 7637 Slog.w(TAG, "Unable to launch app " 7638 + cpi.applicationInfo.packageName + "/" 7639 + cpi.applicationInfo.uid + " for provider " 7640 + name + ": process is bad"); 7641 return null; 7642 } 7643 } 7644 cpr.launchingApp = proc; 7645 mLaunchingProviders.add(cpr); 7646 } finally { 7647 Binder.restoreCallingIdentity(origId); 7648 } 7649 } 7650 7651 // Make sure the provider is published (the same provider class 7652 // may be published under multiple names). 7653 if (firstClass) { 7654 mProviderMap.putProviderByClass(comp, cpr); 7655 } 7656 7657 mProviderMap.putProviderByName(name, cpr); 7658 conn = incProviderCountLocked(r, cpr, token, stable); 7659 if (conn != null) { 7660 conn.waiting = true; 7661 } 7662 } 7663 } 7664 7665 // Wait for the provider to be published... 7666 synchronized (cpr) { 7667 while (cpr.provider == null) { 7668 if (cpr.launchingApp == null) { 7669 Slog.w(TAG, "Unable to launch app " 7670 + cpi.applicationInfo.packageName + "/" 7671 + cpi.applicationInfo.uid + " for provider " 7672 + name + ": launching app became null"); 7673 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7674 UserHandle.getUserId(cpi.applicationInfo.uid), 7675 cpi.applicationInfo.packageName, 7676 cpi.applicationInfo.uid, name); 7677 return null; 7678 } 7679 try { 7680 if (DEBUG_MU) { 7681 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7682 + cpr.launchingApp); 7683 } 7684 if (conn != null) { 7685 conn.waiting = true; 7686 } 7687 cpr.wait(); 7688 } catch (InterruptedException ex) { 7689 } finally { 7690 if (conn != null) { 7691 conn.waiting = false; 7692 } 7693 } 7694 } 7695 } 7696 return cpr != null ? cpr.newHolder(conn) : null; 7697 } 7698 7699 public final ContentProviderHolder getContentProvider( 7700 IApplicationThread caller, String name, int userId, boolean stable) { 7701 enforceNotIsolatedCaller("getContentProvider"); 7702 if (caller == null) { 7703 String msg = "null IApplicationThread when getting content provider " 7704 + name; 7705 Slog.w(TAG, msg); 7706 throw new SecurityException(msg); 7707 } 7708 7709 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7710 false, true, "getContentProvider", null); 7711 return getContentProviderImpl(caller, name, null, stable, userId); 7712 } 7713 7714 public ContentProviderHolder getContentProviderExternal( 7715 String name, int userId, IBinder token) { 7716 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7717 "Do not have permission in call getContentProviderExternal()"); 7718 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7719 false, true, "getContentProvider", null); 7720 return getContentProviderExternalUnchecked(name, token, userId); 7721 } 7722 7723 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7724 IBinder token, int userId) { 7725 return getContentProviderImpl(null, name, token, true, userId); 7726 } 7727 7728 /** 7729 * Drop a content provider from a ProcessRecord's bookkeeping 7730 */ 7731 public void removeContentProvider(IBinder connection, boolean stable) { 7732 enforceNotIsolatedCaller("removeContentProvider"); 7733 synchronized (this) { 7734 ContentProviderConnection conn; 7735 try { 7736 conn = (ContentProviderConnection)connection; 7737 } catch (ClassCastException e) { 7738 String msg ="removeContentProvider: " + connection 7739 + " not a ContentProviderConnection"; 7740 Slog.w(TAG, msg); 7741 throw new IllegalArgumentException(msg); 7742 } 7743 if (conn == null) { 7744 throw new NullPointerException("connection is null"); 7745 } 7746 if (decProviderCountLocked(conn, null, null, stable)) { 7747 updateOomAdjLocked(); 7748 } 7749 } 7750 } 7751 7752 public void removeContentProviderExternal(String name, IBinder token) { 7753 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7754 "Do not have permission in call removeContentProviderExternal()"); 7755 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7756 } 7757 7758 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7759 synchronized (this) { 7760 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7761 if(cpr == null) { 7762 //remove from mProvidersByClass 7763 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7764 return; 7765 } 7766 7767 //update content provider record entry info 7768 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7769 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7770 if (localCpr.hasExternalProcessHandles()) { 7771 if (localCpr.removeExternalProcessHandleLocked(token)) { 7772 updateOomAdjLocked(); 7773 } else { 7774 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7775 + " with no external reference for token: " 7776 + token + "."); 7777 } 7778 } else { 7779 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7780 + " with no external references."); 7781 } 7782 } 7783 } 7784 7785 public final void publishContentProviders(IApplicationThread caller, 7786 List<ContentProviderHolder> providers) { 7787 if (providers == null) { 7788 return; 7789 } 7790 7791 enforceNotIsolatedCaller("publishContentProviders"); 7792 synchronized (this) { 7793 final ProcessRecord r = getRecordForAppLocked(caller); 7794 if (DEBUG_MU) 7795 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 7796 if (r == null) { 7797 throw new SecurityException( 7798 "Unable to find app for caller " + caller 7799 + " (pid=" + Binder.getCallingPid() 7800 + ") when publishing content providers"); 7801 } 7802 7803 final long origId = Binder.clearCallingIdentity(); 7804 7805 final int N = providers.size(); 7806 for (int i=0; i<N; i++) { 7807 ContentProviderHolder src = providers.get(i); 7808 if (src == null || src.info == null || src.provider == null) { 7809 continue; 7810 } 7811 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 7812 if (DEBUG_MU) 7813 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 7814 if (dst != null) { 7815 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 7816 mProviderMap.putProviderByClass(comp, dst); 7817 String names[] = dst.info.authority.split(";"); 7818 for (int j = 0; j < names.length; j++) { 7819 mProviderMap.putProviderByName(names[j], dst); 7820 } 7821 7822 int NL = mLaunchingProviders.size(); 7823 int j; 7824 for (j=0; j<NL; j++) { 7825 if (mLaunchingProviders.get(j) == dst) { 7826 mLaunchingProviders.remove(j); 7827 j--; 7828 NL--; 7829 } 7830 } 7831 synchronized (dst) { 7832 dst.provider = src.provider; 7833 dst.proc = r; 7834 dst.notifyAll(); 7835 } 7836 updateOomAdjLocked(r); 7837 } 7838 } 7839 7840 Binder.restoreCallingIdentity(origId); 7841 } 7842 } 7843 7844 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 7845 ContentProviderConnection conn; 7846 try { 7847 conn = (ContentProviderConnection)connection; 7848 } catch (ClassCastException e) { 7849 String msg ="refContentProvider: " + connection 7850 + " not a ContentProviderConnection"; 7851 Slog.w(TAG, msg); 7852 throw new IllegalArgumentException(msg); 7853 } 7854 if (conn == null) { 7855 throw new NullPointerException("connection is null"); 7856 } 7857 7858 synchronized (this) { 7859 if (stable > 0) { 7860 conn.numStableIncs += stable; 7861 } 7862 stable = conn.stableCount + stable; 7863 if (stable < 0) { 7864 throw new IllegalStateException("stableCount < 0: " + stable); 7865 } 7866 7867 if (unstable > 0) { 7868 conn.numUnstableIncs += unstable; 7869 } 7870 unstable = conn.unstableCount + unstable; 7871 if (unstable < 0) { 7872 throw new IllegalStateException("unstableCount < 0: " + unstable); 7873 } 7874 7875 if ((stable+unstable) <= 0) { 7876 throw new IllegalStateException("ref counts can't go to zero here: stable=" 7877 + stable + " unstable=" + unstable); 7878 } 7879 conn.stableCount = stable; 7880 conn.unstableCount = unstable; 7881 return !conn.dead; 7882 } 7883 } 7884 7885 public void unstableProviderDied(IBinder connection) { 7886 ContentProviderConnection conn; 7887 try { 7888 conn = (ContentProviderConnection)connection; 7889 } catch (ClassCastException e) { 7890 String msg ="refContentProvider: " + connection 7891 + " not a ContentProviderConnection"; 7892 Slog.w(TAG, msg); 7893 throw new IllegalArgumentException(msg); 7894 } 7895 if (conn == null) { 7896 throw new NullPointerException("connection is null"); 7897 } 7898 7899 // Safely retrieve the content provider associated with the connection. 7900 IContentProvider provider; 7901 synchronized (this) { 7902 provider = conn.provider.provider; 7903 } 7904 7905 if (provider == null) { 7906 // Um, yeah, we're way ahead of you. 7907 return; 7908 } 7909 7910 // Make sure the caller is being honest with us. 7911 if (provider.asBinder().pingBinder()) { 7912 // Er, no, still looks good to us. 7913 synchronized (this) { 7914 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 7915 + " says " + conn + " died, but we don't agree"); 7916 return; 7917 } 7918 } 7919 7920 // Well look at that! It's dead! 7921 synchronized (this) { 7922 if (conn.provider.provider != provider) { 7923 // But something changed... good enough. 7924 return; 7925 } 7926 7927 ProcessRecord proc = conn.provider.proc; 7928 if (proc == null || proc.thread == null) { 7929 // Seems like the process is already cleaned up. 7930 return; 7931 } 7932 7933 // As far as we're concerned, this is just like receiving a 7934 // death notification... just a bit prematurely. 7935 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 7936 + ") early provider death"); 7937 final long ident = Binder.clearCallingIdentity(); 7938 try { 7939 appDiedLocked(proc, proc.pid, proc.thread); 7940 } finally { 7941 Binder.restoreCallingIdentity(ident); 7942 } 7943 } 7944 } 7945 7946 @Override 7947 public void appNotRespondingViaProvider(IBinder connection) { 7948 enforceCallingPermission( 7949 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 7950 7951 final ContentProviderConnection conn = (ContentProviderConnection) connection; 7952 if (conn == null) { 7953 Slog.w(TAG, "ContentProviderConnection is null"); 7954 return; 7955 } 7956 7957 final ProcessRecord host = conn.provider.proc; 7958 if (host == null) { 7959 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 7960 return; 7961 } 7962 7963 final long token = Binder.clearCallingIdentity(); 7964 try { 7965 appNotResponding(host, null, null, false, "ContentProvider not responding"); 7966 } finally { 7967 Binder.restoreCallingIdentity(token); 7968 } 7969 } 7970 7971 public final void installSystemProviders() { 7972 List<ProviderInfo> providers; 7973 synchronized (this) { 7974 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 7975 providers = generateApplicationProvidersLocked(app); 7976 if (providers != null) { 7977 for (int i=providers.size()-1; i>=0; i--) { 7978 ProviderInfo pi = (ProviderInfo)providers.get(i); 7979 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 7980 Slog.w(TAG, "Not installing system proc provider " + pi.name 7981 + ": not system .apk"); 7982 providers.remove(i); 7983 } 7984 } 7985 } 7986 } 7987 if (providers != null) { 7988 mSystemThread.installSystemProviders(providers); 7989 } 7990 7991 mCoreSettingsObserver = new CoreSettingsObserver(this); 7992 7993 mUsageStatsService.monitorPackages(); 7994 } 7995 7996 /** 7997 * Allows app to retrieve the MIME type of a URI without having permission 7998 * to access its content provider. 7999 * 8000 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8001 * 8002 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8003 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8004 */ 8005 public String getProviderMimeType(Uri uri, int userId) { 8006 enforceNotIsolatedCaller("getProviderMimeType"); 8007 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8008 userId, false, true, "getProviderMimeType", null); 8009 final String name = uri.getAuthority(); 8010 final long ident = Binder.clearCallingIdentity(); 8011 ContentProviderHolder holder = null; 8012 8013 try { 8014 holder = getContentProviderExternalUnchecked(name, null, userId); 8015 if (holder != null) { 8016 return holder.provider.getType(uri); 8017 } 8018 } catch (RemoteException e) { 8019 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8020 return null; 8021 } finally { 8022 if (holder != null) { 8023 removeContentProviderExternalUnchecked(name, null, userId); 8024 } 8025 Binder.restoreCallingIdentity(ident); 8026 } 8027 8028 return null; 8029 } 8030 8031 // ========================================================= 8032 // GLOBAL MANAGEMENT 8033 // ========================================================= 8034 8035 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8036 boolean isolated) { 8037 String proc = customProcess != null ? customProcess : info.processName; 8038 BatteryStatsImpl.Uid.Proc ps = null; 8039 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8040 int uid = info.uid; 8041 if (isolated) { 8042 int userId = UserHandle.getUserId(uid); 8043 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8044 while (true) { 8045 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8046 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8047 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8048 } 8049 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8050 mNextIsolatedProcessUid++; 8051 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8052 // No process for this uid, use it. 8053 break; 8054 } 8055 stepsLeft--; 8056 if (stepsLeft <= 0) { 8057 return null; 8058 } 8059 } 8060 } 8061 return new ProcessRecord(stats, info, proc, uid); 8062 } 8063 8064 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8065 ProcessRecord app; 8066 if (!isolated) { 8067 app = getProcessRecordLocked(info.processName, info.uid, true); 8068 } else { 8069 app = null; 8070 } 8071 8072 if (app == null) { 8073 app = newProcessRecordLocked(info, null, isolated); 8074 mProcessNames.put(info.processName, app.uid, app); 8075 if (isolated) { 8076 mIsolatedProcesses.put(app.uid, app); 8077 } 8078 updateLruProcessLocked(app, false, null); 8079 updateOomAdjLocked(); 8080 } 8081 8082 // This package really, really can not be stopped. 8083 try { 8084 AppGlobals.getPackageManager().setPackageStoppedState( 8085 info.packageName, false, UserHandle.getUserId(app.uid)); 8086 } catch (RemoteException e) { 8087 } catch (IllegalArgumentException e) { 8088 Slog.w(TAG, "Failed trying to unstop package " 8089 + info.packageName + ": " + e); 8090 } 8091 8092 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8093 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8094 app.persistent = true; 8095 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8096 } 8097 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8098 mPersistentStartingProcesses.add(app); 8099 startProcessLocked(app, "added application", app.processName); 8100 } 8101 8102 return app; 8103 } 8104 8105 public void unhandledBack() { 8106 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8107 "unhandledBack()"); 8108 8109 synchronized(this) { 8110 final long origId = Binder.clearCallingIdentity(); 8111 try { 8112 getFocusedStack().unhandledBackLocked(); 8113 } finally { 8114 Binder.restoreCallingIdentity(origId); 8115 } 8116 } 8117 } 8118 8119 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8120 enforceNotIsolatedCaller("openContentUri"); 8121 final int userId = UserHandle.getCallingUserId(); 8122 String name = uri.getAuthority(); 8123 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8124 ParcelFileDescriptor pfd = null; 8125 if (cph != null) { 8126 // We record the binder invoker's uid in thread-local storage before 8127 // going to the content provider to open the file. Later, in the code 8128 // that handles all permissions checks, we look for this uid and use 8129 // that rather than the Activity Manager's own uid. The effect is that 8130 // we do the check against the caller's permissions even though it looks 8131 // to the content provider like the Activity Manager itself is making 8132 // the request. 8133 sCallerIdentity.set(new Identity( 8134 Binder.getCallingPid(), Binder.getCallingUid())); 8135 try { 8136 pfd = cph.provider.openFile(null, uri, "r", null); 8137 } catch (FileNotFoundException e) { 8138 // do nothing; pfd will be returned null 8139 } finally { 8140 // Ensure that whatever happens, we clean up the identity state 8141 sCallerIdentity.remove(); 8142 } 8143 8144 // We've got the fd now, so we're done with the provider. 8145 removeContentProviderExternalUnchecked(name, null, userId); 8146 } else { 8147 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8148 } 8149 return pfd; 8150 } 8151 8152 // Actually is sleeping or shutting down or whatever else in the future 8153 // is an inactive state. 8154 public boolean isSleepingOrShuttingDown() { 8155 return mSleeping || mShuttingDown; 8156 } 8157 8158 public void goingToSleep() { 8159 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8160 != PackageManager.PERMISSION_GRANTED) { 8161 throw new SecurityException("Requires permission " 8162 + android.Manifest.permission.DEVICE_POWER); 8163 } 8164 8165 synchronized(this) { 8166 mWentToSleep = true; 8167 updateEventDispatchingLocked(); 8168 8169 if (!mSleeping) { 8170 mSleeping = true; 8171 mStackSupervisor.goingToSleepLocked(); 8172 8173 // Initialize the wake times of all processes. 8174 checkExcessivePowerUsageLocked(false); 8175 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8176 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8177 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8178 } 8179 } 8180 } 8181 8182 @Override 8183 public boolean shutdown(int timeout) { 8184 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8185 != PackageManager.PERMISSION_GRANTED) { 8186 throw new SecurityException("Requires permission " 8187 + android.Manifest.permission.SHUTDOWN); 8188 } 8189 8190 boolean timedout = false; 8191 8192 synchronized(this) { 8193 mShuttingDown = true; 8194 updateEventDispatchingLocked(); 8195 timedout = mStackSupervisor.shutdownLocked(timeout); 8196 } 8197 8198 mAppOpsService.shutdown(); 8199 mUsageStatsService.shutdown(); 8200 mBatteryStatsService.shutdown(); 8201 synchronized (this) { 8202 mProcessStats.shutdownLocked(); 8203 } 8204 8205 return timedout; 8206 } 8207 8208 public final void activitySlept(IBinder token) { 8209 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8210 8211 final long origId = Binder.clearCallingIdentity(); 8212 8213 synchronized (this) { 8214 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8215 if (r != null) { 8216 mStackSupervisor.activitySleptLocked(r); 8217 } 8218 } 8219 8220 Binder.restoreCallingIdentity(origId); 8221 } 8222 8223 void logLockScreen(String msg) { 8224 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8225 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8226 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8227 mStackSupervisor.mDismissKeyguardOnNextActivity); 8228 } 8229 8230 private void comeOutOfSleepIfNeededLocked() { 8231 if (!mWentToSleep && !mLockScreenShown) { 8232 if (mSleeping) { 8233 mSleeping = false; 8234 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8235 } 8236 } 8237 } 8238 8239 public void wakingUp() { 8240 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8241 != PackageManager.PERMISSION_GRANTED) { 8242 throw new SecurityException("Requires permission " 8243 + android.Manifest.permission.DEVICE_POWER); 8244 } 8245 8246 synchronized(this) { 8247 mWentToSleep = false; 8248 updateEventDispatchingLocked(); 8249 comeOutOfSleepIfNeededLocked(); 8250 } 8251 } 8252 8253 private void updateEventDispatchingLocked() { 8254 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8255 } 8256 8257 public void setLockScreenShown(boolean shown) { 8258 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8259 != PackageManager.PERMISSION_GRANTED) { 8260 throw new SecurityException("Requires permission " 8261 + android.Manifest.permission.DEVICE_POWER); 8262 } 8263 8264 synchronized(this) { 8265 long ident = Binder.clearCallingIdentity(); 8266 try { 8267 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8268 mLockScreenShown = shown; 8269 comeOutOfSleepIfNeededLocked(); 8270 } finally { 8271 Binder.restoreCallingIdentity(ident); 8272 } 8273 } 8274 } 8275 8276 public void stopAppSwitches() { 8277 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8278 != PackageManager.PERMISSION_GRANTED) { 8279 throw new SecurityException("Requires permission " 8280 + android.Manifest.permission.STOP_APP_SWITCHES); 8281 } 8282 8283 synchronized(this) { 8284 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8285 + APP_SWITCH_DELAY_TIME; 8286 mDidAppSwitch = false; 8287 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8288 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8289 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8290 } 8291 } 8292 8293 public void resumeAppSwitches() { 8294 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8295 != PackageManager.PERMISSION_GRANTED) { 8296 throw new SecurityException("Requires permission " 8297 + android.Manifest.permission.STOP_APP_SWITCHES); 8298 } 8299 8300 synchronized(this) { 8301 // Note that we don't execute any pending app switches... we will 8302 // let those wait until either the timeout, or the next start 8303 // activity request. 8304 mAppSwitchesAllowedTime = 0; 8305 } 8306 } 8307 8308 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8309 String name) { 8310 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8311 return true; 8312 } 8313 8314 final int perm = checkComponentPermission( 8315 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8316 callingUid, -1, true); 8317 if (perm == PackageManager.PERMISSION_GRANTED) { 8318 return true; 8319 } 8320 8321 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8322 return false; 8323 } 8324 8325 public void setDebugApp(String packageName, boolean waitForDebugger, 8326 boolean persistent) { 8327 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8328 "setDebugApp()"); 8329 8330 long ident = Binder.clearCallingIdentity(); 8331 try { 8332 // Note that this is not really thread safe if there are multiple 8333 // callers into it at the same time, but that's not a situation we 8334 // care about. 8335 if (persistent) { 8336 final ContentResolver resolver = mContext.getContentResolver(); 8337 Settings.Global.putString( 8338 resolver, Settings.Global.DEBUG_APP, 8339 packageName); 8340 Settings.Global.putInt( 8341 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8342 waitForDebugger ? 1 : 0); 8343 } 8344 8345 synchronized (this) { 8346 if (!persistent) { 8347 mOrigDebugApp = mDebugApp; 8348 mOrigWaitForDebugger = mWaitForDebugger; 8349 } 8350 mDebugApp = packageName; 8351 mWaitForDebugger = waitForDebugger; 8352 mDebugTransient = !persistent; 8353 if (packageName != null) { 8354 forceStopPackageLocked(packageName, -1, false, false, true, true, 8355 UserHandle.USER_ALL, "set debug app"); 8356 } 8357 } 8358 } finally { 8359 Binder.restoreCallingIdentity(ident); 8360 } 8361 } 8362 8363 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8364 synchronized (this) { 8365 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8366 if (!isDebuggable) { 8367 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8368 throw new SecurityException("Process not debuggable: " + app.packageName); 8369 } 8370 } 8371 8372 mOpenGlTraceApp = processName; 8373 } 8374 } 8375 8376 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8377 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8378 synchronized (this) { 8379 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8380 if (!isDebuggable) { 8381 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8382 throw new SecurityException("Process not debuggable: " + app.packageName); 8383 } 8384 } 8385 mProfileApp = processName; 8386 mProfileFile = profileFile; 8387 if (mProfileFd != null) { 8388 try { 8389 mProfileFd.close(); 8390 } catch (IOException e) { 8391 } 8392 mProfileFd = null; 8393 } 8394 mProfileFd = profileFd; 8395 mProfileType = 0; 8396 mAutoStopProfiler = autoStopProfiler; 8397 } 8398 } 8399 8400 @Override 8401 public void setAlwaysFinish(boolean enabled) { 8402 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8403 "setAlwaysFinish()"); 8404 8405 Settings.Global.putInt( 8406 mContext.getContentResolver(), 8407 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8408 8409 synchronized (this) { 8410 mAlwaysFinishActivities = enabled; 8411 } 8412 } 8413 8414 @Override 8415 public void setActivityController(IActivityController controller) { 8416 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8417 "setActivityController()"); 8418 synchronized (this) { 8419 mController = controller; 8420 Watchdog.getInstance().setActivityController(controller); 8421 } 8422 } 8423 8424 @Override 8425 public void setUserIsMonkey(boolean userIsMonkey) { 8426 synchronized (this) { 8427 synchronized (mPidsSelfLocked) { 8428 final int callingPid = Binder.getCallingPid(); 8429 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8430 if (precessRecord == null) { 8431 throw new SecurityException("Unknown process: " + callingPid); 8432 } 8433 if (precessRecord.instrumentationUiAutomationConnection == null) { 8434 throw new SecurityException("Only an instrumentation process " 8435 + "with a UiAutomation can call setUserIsMonkey"); 8436 } 8437 } 8438 mUserIsMonkey = userIsMonkey; 8439 } 8440 } 8441 8442 @Override 8443 public boolean isUserAMonkey() { 8444 synchronized (this) { 8445 // If there is a controller also implies the user is a monkey. 8446 return (mUserIsMonkey || mController != null); 8447 } 8448 } 8449 8450 public void requestBugReport() { 8451 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8452 SystemProperties.set("ctl.start", "bugreport"); 8453 } 8454 8455 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8456 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8457 } 8458 8459 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8460 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8461 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8462 } 8463 return KEY_DISPATCHING_TIMEOUT; 8464 } 8465 8466 @Override 8467 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8468 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8469 != PackageManager.PERMISSION_GRANTED) { 8470 throw new SecurityException("Requires permission " 8471 + android.Manifest.permission.FILTER_EVENTS); 8472 } 8473 ProcessRecord proc; 8474 long timeout; 8475 synchronized (this) { 8476 synchronized (mPidsSelfLocked) { 8477 proc = mPidsSelfLocked.get(pid); 8478 } 8479 timeout = getInputDispatchingTimeoutLocked(proc); 8480 } 8481 8482 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8483 return -1; 8484 } 8485 8486 return timeout; 8487 } 8488 8489 /** 8490 * Handle input dispatching timeouts. 8491 * Returns whether input dispatching should be aborted or not. 8492 */ 8493 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8494 final ActivityRecord activity, final ActivityRecord parent, 8495 final boolean aboveSystem, String reason) { 8496 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8497 != PackageManager.PERMISSION_GRANTED) { 8498 throw new SecurityException("Requires permission " 8499 + android.Manifest.permission.FILTER_EVENTS); 8500 } 8501 8502 final String annotation; 8503 if (reason == null) { 8504 annotation = "Input dispatching timed out"; 8505 } else { 8506 annotation = "Input dispatching timed out (" + reason + ")"; 8507 } 8508 8509 if (proc != null) { 8510 synchronized (this) { 8511 if (proc.debugging) { 8512 return false; 8513 } 8514 8515 if (mDidDexOpt) { 8516 // Give more time since we were dexopting. 8517 mDidDexOpt = false; 8518 return false; 8519 } 8520 8521 if (proc.instrumentationClass != null) { 8522 Bundle info = new Bundle(); 8523 info.putString("shortMsg", "keyDispatchingTimedOut"); 8524 info.putString("longMsg", annotation); 8525 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8526 return true; 8527 } 8528 } 8529 mHandler.post(new Runnable() { 8530 @Override 8531 public void run() { 8532 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8533 } 8534 }); 8535 } 8536 8537 return true; 8538 } 8539 8540 public Bundle getAssistContextExtras(int requestType) { 8541 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8542 "getAssistContextExtras()"); 8543 PendingAssistExtras pae; 8544 Bundle extras = new Bundle(); 8545 synchronized (this) { 8546 ActivityRecord activity = getFocusedStack().mResumedActivity; 8547 if (activity == null) { 8548 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8549 return null; 8550 } 8551 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8552 if (activity.app == null || activity.app.thread == null) { 8553 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8554 return extras; 8555 } 8556 if (activity.app.pid == Binder.getCallingPid()) { 8557 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8558 return extras; 8559 } 8560 pae = new PendingAssistExtras(activity); 8561 try { 8562 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8563 requestType); 8564 mPendingAssistExtras.add(pae); 8565 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8566 } catch (RemoteException e) { 8567 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8568 return extras; 8569 } 8570 } 8571 synchronized (pae) { 8572 while (!pae.haveResult) { 8573 try { 8574 pae.wait(); 8575 } catch (InterruptedException e) { 8576 } 8577 } 8578 if (pae.result != null) { 8579 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8580 } 8581 } 8582 synchronized (this) { 8583 mPendingAssistExtras.remove(pae); 8584 mHandler.removeCallbacks(pae); 8585 } 8586 return extras; 8587 } 8588 8589 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8590 PendingAssistExtras pae = (PendingAssistExtras)token; 8591 synchronized (pae) { 8592 pae.result = extras; 8593 pae.haveResult = true; 8594 pae.notifyAll(); 8595 } 8596 } 8597 8598 public void registerProcessObserver(IProcessObserver observer) { 8599 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8600 "registerProcessObserver()"); 8601 synchronized (this) { 8602 mProcessObservers.register(observer); 8603 } 8604 } 8605 8606 @Override 8607 public void unregisterProcessObserver(IProcessObserver observer) { 8608 synchronized (this) { 8609 mProcessObservers.unregister(observer); 8610 } 8611 } 8612 8613 @Override 8614 public boolean convertFromTranslucent(IBinder token) { 8615 final long origId = Binder.clearCallingIdentity(); 8616 try { 8617 synchronized (this) { 8618 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8619 if (r == null) { 8620 return false; 8621 } 8622 if (r.changeWindowTranslucency(true)) { 8623 mWindowManager.setAppFullscreen(token, true); 8624 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8625 return true; 8626 } 8627 return false; 8628 } 8629 } finally { 8630 Binder.restoreCallingIdentity(origId); 8631 } 8632 } 8633 8634 @Override 8635 public boolean convertToTranslucent(IBinder token) { 8636 final long origId = Binder.clearCallingIdentity(); 8637 try { 8638 synchronized (this) { 8639 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8640 if (r == null) { 8641 return false; 8642 } 8643 if (r.changeWindowTranslucency(false)) { 8644 r.task.stack.convertToTranslucent(r); 8645 mWindowManager.setAppFullscreen(token, false); 8646 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8647 return true; 8648 } 8649 return false; 8650 } 8651 } finally { 8652 Binder.restoreCallingIdentity(origId); 8653 } 8654 } 8655 8656 @Override 8657 public void setImmersive(IBinder token, boolean immersive) { 8658 synchronized(this) { 8659 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8660 if (r == null) { 8661 throw new IllegalArgumentException(); 8662 } 8663 r.immersive = immersive; 8664 8665 // update associated state if we're frontmost 8666 if (r == mFocusedActivity) { 8667 if (DEBUG_IMMERSIVE) { 8668 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8669 } 8670 applyUpdateLockStateLocked(r); 8671 } 8672 } 8673 } 8674 8675 @Override 8676 public boolean isImmersive(IBinder token) { 8677 synchronized (this) { 8678 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8679 if (r == null) { 8680 throw new IllegalArgumentException(); 8681 } 8682 return r.immersive; 8683 } 8684 } 8685 8686 public boolean isTopActivityImmersive() { 8687 enforceNotIsolatedCaller("startActivity"); 8688 synchronized (this) { 8689 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8690 return (r != null) ? r.immersive : false; 8691 } 8692 } 8693 8694 public final void enterSafeMode() { 8695 synchronized(this) { 8696 // It only makes sense to do this before the system is ready 8697 // and started launching other packages. 8698 if (!mSystemReady) { 8699 try { 8700 AppGlobals.getPackageManager().enterSafeMode(); 8701 } catch (RemoteException e) { 8702 } 8703 } 8704 } 8705 } 8706 8707 public final void showSafeModeOverlay() { 8708 View v = LayoutInflater.from(mContext).inflate( 8709 com.android.internal.R.layout.safe_mode, null); 8710 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8711 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8712 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8713 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8714 lp.gravity = Gravity.BOTTOM | Gravity.START; 8715 lp.format = v.getBackground().getOpacity(); 8716 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8717 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8718 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8719 ((WindowManager)mContext.getSystemService( 8720 Context.WINDOW_SERVICE)).addView(v, lp); 8721 } 8722 8723 public void noteWakeupAlarm(IIntentSender sender) { 8724 if (!(sender instanceof PendingIntentRecord)) { 8725 return; 8726 } 8727 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8728 synchronized (stats) { 8729 if (mBatteryStatsService.isOnBattery()) { 8730 mBatteryStatsService.enforceCallingPermission(); 8731 PendingIntentRecord rec = (PendingIntentRecord)sender; 8732 int MY_UID = Binder.getCallingUid(); 8733 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8734 BatteryStatsImpl.Uid.Pkg pkg = 8735 stats.getPackageStatsLocked(uid, rec.key.packageName); 8736 pkg.incWakeupsLocked(); 8737 } 8738 } 8739 } 8740 8741 public boolean killPids(int[] pids, String pReason, boolean secure) { 8742 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8743 throw new SecurityException("killPids only available to the system"); 8744 } 8745 String reason = (pReason == null) ? "Unknown" : pReason; 8746 // XXX Note: don't acquire main activity lock here, because the window 8747 // manager calls in with its locks held. 8748 8749 boolean killed = false; 8750 synchronized (mPidsSelfLocked) { 8751 int[] types = new int[pids.length]; 8752 int worstType = 0; 8753 for (int i=0; i<pids.length; i++) { 8754 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8755 if (proc != null) { 8756 int type = proc.setAdj; 8757 types[i] = type; 8758 if (type > worstType) { 8759 worstType = type; 8760 } 8761 } 8762 } 8763 8764 // If the worst oom_adj is somewhere in the cached proc LRU range, 8765 // then constrain it so we will kill all cached procs. 8766 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8767 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8768 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8769 } 8770 8771 // If this is not a secure call, don't let it kill processes that 8772 // are important. 8773 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8774 worstType = ProcessList.SERVICE_ADJ; 8775 } 8776 8777 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8778 for (int i=0; i<pids.length; i++) { 8779 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8780 if (proc == null) { 8781 continue; 8782 } 8783 int adj = proc.setAdj; 8784 if (adj >= worstType && !proc.killedByAm) { 8785 killUnneededProcessLocked(proc, reason); 8786 killed = true; 8787 } 8788 } 8789 } 8790 return killed; 8791 } 8792 8793 @Override 8794 public void killUid(int uid, String reason) { 8795 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8796 throw new SecurityException("killUid only available to the system"); 8797 } 8798 synchronized (this) { 8799 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 8800 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 8801 reason != null ? reason : "kill uid"); 8802 } 8803 } 8804 8805 @Override 8806 public boolean killProcessesBelowForeground(String reason) { 8807 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8808 throw new SecurityException("killProcessesBelowForeground() only available to system"); 8809 } 8810 8811 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 8812 } 8813 8814 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 8815 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8816 throw new SecurityException("killProcessesBelowAdj() only available to system"); 8817 } 8818 8819 boolean killed = false; 8820 synchronized (mPidsSelfLocked) { 8821 final int size = mPidsSelfLocked.size(); 8822 for (int i = 0; i < size; i++) { 8823 final int pid = mPidsSelfLocked.keyAt(i); 8824 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8825 if (proc == null) continue; 8826 8827 final int adj = proc.setAdj; 8828 if (adj > belowAdj && !proc.killedByAm) { 8829 killUnneededProcessLocked(proc, reason); 8830 killed = true; 8831 } 8832 } 8833 } 8834 return killed; 8835 } 8836 8837 @Override 8838 public void hang(final IBinder who, boolean allowRestart) { 8839 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8840 != PackageManager.PERMISSION_GRANTED) { 8841 throw new SecurityException("Requires permission " 8842 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8843 } 8844 8845 final IBinder.DeathRecipient death = new DeathRecipient() { 8846 @Override 8847 public void binderDied() { 8848 synchronized (this) { 8849 notifyAll(); 8850 } 8851 } 8852 }; 8853 8854 try { 8855 who.linkToDeath(death, 0); 8856 } catch (RemoteException e) { 8857 Slog.w(TAG, "hang: given caller IBinder is already dead."); 8858 return; 8859 } 8860 8861 synchronized (this) { 8862 Watchdog.getInstance().setAllowRestart(allowRestart); 8863 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 8864 synchronized (death) { 8865 while (who.isBinderAlive()) { 8866 try { 8867 death.wait(); 8868 } catch (InterruptedException e) { 8869 } 8870 } 8871 } 8872 Watchdog.getInstance().setAllowRestart(true); 8873 } 8874 } 8875 8876 @Override 8877 public void restart() { 8878 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8879 != PackageManager.PERMISSION_GRANTED) { 8880 throw new SecurityException("Requires permission " 8881 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8882 } 8883 8884 Log.i(TAG, "Sending shutdown broadcast..."); 8885 8886 BroadcastReceiver br = new BroadcastReceiver() { 8887 @Override public void onReceive(Context context, Intent intent) { 8888 // Now the broadcast is done, finish up the low-level shutdown. 8889 Log.i(TAG, "Shutting down activity manager..."); 8890 shutdown(10000); 8891 Log.i(TAG, "Shutdown complete, restarting!"); 8892 Process.killProcess(Process.myPid()); 8893 System.exit(10); 8894 } 8895 }; 8896 8897 // First send the high-level shut down broadcast. 8898 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 8899 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 8900 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 8901 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 8902 mContext.sendOrderedBroadcastAsUser(intent, 8903 UserHandle.ALL, null, br, mHandler, 0, null, null); 8904 */ 8905 br.onReceive(mContext, intent); 8906 } 8907 8908 private long getLowRamTimeSinceIdle(long now) { 8909 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 8910 } 8911 8912 @Override 8913 public void performIdleMaintenance() { 8914 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8915 != PackageManager.PERMISSION_GRANTED) { 8916 throw new SecurityException("Requires permission " 8917 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8918 } 8919 8920 synchronized (this) { 8921 final long now = SystemClock.uptimeMillis(); 8922 final long timeSinceLastIdle = now - mLastIdleTime; 8923 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 8924 mLastIdleTime = now; 8925 mLowRamTimeSinceLastIdle = 0; 8926 if (mLowRamStartTime != 0) { 8927 mLowRamStartTime = now; 8928 } 8929 8930 StringBuilder sb = new StringBuilder(128); 8931 sb.append("Idle maintenance over "); 8932 TimeUtils.formatDuration(timeSinceLastIdle, sb); 8933 sb.append(" low RAM for "); 8934 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 8935 Slog.i(TAG, sb.toString()); 8936 8937 // If at least 1/3 of our time since the last idle period has been spent 8938 // with RAM low, then we want to kill processes. 8939 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 8940 8941 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 8942 ProcessRecord proc = mLruProcesses.get(i); 8943 if (proc.notCachedSinceIdle) { 8944 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 8945 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 8946 if (doKilling && proc.initialIdlePss != 0 8947 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 8948 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 8949 + " from " + proc.initialIdlePss + ")"); 8950 } 8951 } 8952 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 8953 proc.notCachedSinceIdle = true; 8954 proc.initialIdlePss = 0; 8955 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 8956 mSleeping, now); 8957 } 8958 } 8959 8960 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 8961 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 8962 } 8963 } 8964 8965 public final void startRunning(String pkg, String cls, String action, 8966 String data) { 8967 synchronized(this) { 8968 if (mStartRunning) { 8969 return; 8970 } 8971 mStartRunning = true; 8972 mTopComponent = pkg != null && cls != null 8973 ? new ComponentName(pkg, cls) : null; 8974 mTopAction = action != null ? action : Intent.ACTION_MAIN; 8975 mTopData = data; 8976 if (!mSystemReady) { 8977 return; 8978 } 8979 } 8980 8981 systemReady(null); 8982 } 8983 8984 private void retrieveSettings() { 8985 final ContentResolver resolver = mContext.getContentResolver(); 8986 String debugApp = Settings.Global.getString( 8987 resolver, Settings.Global.DEBUG_APP); 8988 boolean waitForDebugger = Settings.Global.getInt( 8989 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 8990 boolean alwaysFinishActivities = Settings.Global.getInt( 8991 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 8992 boolean forceRtl = Settings.Global.getInt( 8993 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 8994 // Transfer any global setting for forcing RTL layout, into a System Property 8995 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 8996 8997 Configuration configuration = new Configuration(); 8998 Settings.System.getConfiguration(resolver, configuration); 8999 if (forceRtl) { 9000 // This will take care of setting the correct layout direction flags 9001 configuration.setLayoutDirection(configuration.locale); 9002 } 9003 9004 synchronized (this) { 9005 mDebugApp = mOrigDebugApp = debugApp; 9006 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9007 mAlwaysFinishActivities = alwaysFinishActivities; 9008 // This happens before any activities are started, so we can 9009 // change mConfiguration in-place. 9010 updateConfigurationLocked(configuration, null, false, true); 9011 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9012 } 9013 } 9014 9015 public boolean testIsSystemReady() { 9016 // no need to synchronize(this) just to read & return the value 9017 return mSystemReady; 9018 } 9019 9020 private static File getCalledPreBootReceiversFile() { 9021 File dataDir = Environment.getDataDirectory(); 9022 File systemDir = new File(dataDir, "system"); 9023 File fname = new File(systemDir, "called_pre_boots.dat"); 9024 return fname; 9025 } 9026 9027 static final int LAST_DONE_VERSION = 10000; 9028 9029 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9030 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9031 File file = getCalledPreBootReceiversFile(); 9032 FileInputStream fis = null; 9033 try { 9034 fis = new FileInputStream(file); 9035 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9036 int fvers = dis.readInt(); 9037 if (fvers == LAST_DONE_VERSION) { 9038 String vers = dis.readUTF(); 9039 String codename = dis.readUTF(); 9040 String build = dis.readUTF(); 9041 if (android.os.Build.VERSION.RELEASE.equals(vers) 9042 && android.os.Build.VERSION.CODENAME.equals(codename) 9043 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9044 int num = dis.readInt(); 9045 while (num > 0) { 9046 num--; 9047 String pkg = dis.readUTF(); 9048 String cls = dis.readUTF(); 9049 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9050 } 9051 } 9052 } 9053 } catch (FileNotFoundException e) { 9054 } catch (IOException e) { 9055 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9056 } finally { 9057 if (fis != null) { 9058 try { 9059 fis.close(); 9060 } catch (IOException e) { 9061 } 9062 } 9063 } 9064 return lastDoneReceivers; 9065 } 9066 9067 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9068 File file = getCalledPreBootReceiversFile(); 9069 FileOutputStream fos = null; 9070 DataOutputStream dos = null; 9071 try { 9072 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9073 fos = new FileOutputStream(file); 9074 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9075 dos.writeInt(LAST_DONE_VERSION); 9076 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9077 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9078 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9079 dos.writeInt(list.size()); 9080 for (int i=0; i<list.size(); i++) { 9081 dos.writeUTF(list.get(i).getPackageName()); 9082 dos.writeUTF(list.get(i).getClassName()); 9083 } 9084 } catch (IOException e) { 9085 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9086 file.delete(); 9087 } finally { 9088 FileUtils.sync(fos); 9089 if (dos != null) { 9090 try { 9091 dos.close(); 9092 } catch (IOException e) { 9093 // TODO Auto-generated catch block 9094 e.printStackTrace(); 9095 } 9096 } 9097 } 9098 } 9099 9100 public void systemReady(final Runnable goingCallback) { 9101 synchronized(this) { 9102 if (mSystemReady) { 9103 if (goingCallback != null) goingCallback.run(); 9104 return; 9105 } 9106 9107 // Check to see if there are any update receivers to run. 9108 if (!mDidUpdate) { 9109 if (mWaitingUpdate) { 9110 return; 9111 } 9112 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9113 List<ResolveInfo> ris = null; 9114 try { 9115 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9116 intent, null, 0, 0); 9117 } catch (RemoteException e) { 9118 } 9119 if (ris != null) { 9120 for (int i=ris.size()-1; i>=0; i--) { 9121 if ((ris.get(i).activityInfo.applicationInfo.flags 9122 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9123 ris.remove(i); 9124 } 9125 } 9126 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9127 9128 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9129 9130 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9131 for (int i=0; i<ris.size(); i++) { 9132 ActivityInfo ai = ris.get(i).activityInfo; 9133 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9134 if (lastDoneReceivers.contains(comp)) { 9135 ris.remove(i); 9136 i--; 9137 } 9138 } 9139 9140 final int[] users = getUsersLocked(); 9141 for (int i=0; i<ris.size(); i++) { 9142 ActivityInfo ai = ris.get(i).activityInfo; 9143 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9144 doneReceivers.add(comp); 9145 intent.setComponent(comp); 9146 for (int j=0; j<users.length; j++) { 9147 IIntentReceiver finisher = null; 9148 if (i == ris.size()-1 && j == users.length-1) { 9149 finisher = new IIntentReceiver.Stub() { 9150 public void performReceive(Intent intent, int resultCode, 9151 String data, Bundle extras, boolean ordered, 9152 boolean sticky, int sendingUser) { 9153 // The raw IIntentReceiver interface is called 9154 // with the AM lock held, so redispatch to 9155 // execute our code without the lock. 9156 mHandler.post(new Runnable() { 9157 public void run() { 9158 synchronized (ActivityManagerService.this) { 9159 mDidUpdate = true; 9160 } 9161 writeLastDonePreBootReceivers(doneReceivers); 9162 showBootMessage(mContext.getText( 9163 R.string.android_upgrading_complete), 9164 false); 9165 systemReady(goingCallback); 9166 } 9167 }); 9168 } 9169 }; 9170 } 9171 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9172 + " for user " + users[j]); 9173 broadcastIntentLocked(null, null, intent, null, finisher, 9174 0, null, null, null, AppOpsManager.OP_NONE, 9175 true, false, MY_PID, Process.SYSTEM_UID, 9176 users[j]); 9177 if (finisher != null) { 9178 mWaitingUpdate = true; 9179 } 9180 } 9181 } 9182 } 9183 if (mWaitingUpdate) { 9184 return; 9185 } 9186 mDidUpdate = true; 9187 } 9188 9189 mAppOpsService.systemReady(); 9190 mSystemReady = true; 9191 if (!mStartRunning) { 9192 return; 9193 } 9194 } 9195 9196 ArrayList<ProcessRecord> procsToKill = null; 9197 synchronized(mPidsSelfLocked) { 9198 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9199 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9200 if (!isAllowedWhileBooting(proc.info)){ 9201 if (procsToKill == null) { 9202 procsToKill = new ArrayList<ProcessRecord>(); 9203 } 9204 procsToKill.add(proc); 9205 } 9206 } 9207 } 9208 9209 synchronized(this) { 9210 if (procsToKill != null) { 9211 for (int i=procsToKill.size()-1; i>=0; i--) { 9212 ProcessRecord proc = procsToKill.get(i); 9213 Slog.i(TAG, "Removing system update proc: " + proc); 9214 removeProcessLocked(proc, true, false, "system update done"); 9215 } 9216 } 9217 9218 // Now that we have cleaned up any update processes, we 9219 // are ready to start launching real processes and know that 9220 // we won't trample on them any more. 9221 mProcessesReady = true; 9222 } 9223 9224 Slog.i(TAG, "System now ready"); 9225 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9226 SystemClock.uptimeMillis()); 9227 9228 synchronized(this) { 9229 // Make sure we have no pre-ready processes sitting around. 9230 9231 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9232 ResolveInfo ri = mContext.getPackageManager() 9233 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9234 STOCK_PM_FLAGS); 9235 CharSequence errorMsg = null; 9236 if (ri != null) { 9237 ActivityInfo ai = ri.activityInfo; 9238 ApplicationInfo app = ai.applicationInfo; 9239 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9240 mTopAction = Intent.ACTION_FACTORY_TEST; 9241 mTopData = null; 9242 mTopComponent = new ComponentName(app.packageName, 9243 ai.name); 9244 } else { 9245 errorMsg = mContext.getResources().getText( 9246 com.android.internal.R.string.factorytest_not_system); 9247 } 9248 } else { 9249 errorMsg = mContext.getResources().getText( 9250 com.android.internal.R.string.factorytest_no_action); 9251 } 9252 if (errorMsg != null) { 9253 mTopAction = null; 9254 mTopData = null; 9255 mTopComponent = null; 9256 Message msg = Message.obtain(); 9257 msg.what = SHOW_FACTORY_ERROR_MSG; 9258 msg.getData().putCharSequence("msg", errorMsg); 9259 mHandler.sendMessage(msg); 9260 } 9261 } 9262 } 9263 9264 retrieveSettings(); 9265 9266 synchronized (this) { 9267 readGrantedUriPermissionsLocked(); 9268 } 9269 9270 if (goingCallback != null) goingCallback.run(); 9271 9272 synchronized (this) { 9273 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9274 try { 9275 List apps = AppGlobals.getPackageManager(). 9276 getPersistentApplications(STOCK_PM_FLAGS); 9277 if (apps != null) { 9278 int N = apps.size(); 9279 int i; 9280 for (i=0; i<N; i++) { 9281 ApplicationInfo info 9282 = (ApplicationInfo)apps.get(i); 9283 if (info != null && 9284 !info.packageName.equals("android")) { 9285 addAppLocked(info, false); 9286 } 9287 } 9288 } 9289 } catch (RemoteException ex) { 9290 // pm is in same process, this will never happen. 9291 } 9292 } 9293 9294 // Start up initial activity. 9295 mBooting = true; 9296 9297 try { 9298 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9299 Message msg = Message.obtain(); 9300 msg.what = SHOW_UID_ERROR_MSG; 9301 mHandler.sendMessage(msg); 9302 } 9303 } catch (RemoteException e) { 9304 } 9305 9306 long ident = Binder.clearCallingIdentity(); 9307 try { 9308 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9309 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9310 | Intent.FLAG_RECEIVER_FOREGROUND); 9311 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9312 broadcastIntentLocked(null, null, intent, 9313 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9314 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9315 intent = new Intent(Intent.ACTION_USER_STARTING); 9316 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9317 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9318 broadcastIntentLocked(null, null, intent, 9319 null, new IIntentReceiver.Stub() { 9320 @Override 9321 public void performReceive(Intent intent, int resultCode, String data, 9322 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9323 throws RemoteException { 9324 } 9325 }, 0, null, null, 9326 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9327 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9328 } finally { 9329 Binder.restoreCallingIdentity(ident); 9330 } 9331 mStackSupervisor.resumeTopActivitiesLocked(); 9332 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9333 } 9334 } 9335 9336 private boolean makeAppCrashingLocked(ProcessRecord app, 9337 String shortMsg, String longMsg, String stackTrace) { 9338 app.crashing = true; 9339 app.crashingReport = generateProcessError(app, 9340 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9341 startAppProblemLocked(app); 9342 app.stopFreezingAllLocked(); 9343 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9344 } 9345 9346 private void makeAppNotRespondingLocked(ProcessRecord app, 9347 String activity, String shortMsg, String longMsg) { 9348 app.notResponding = true; 9349 app.notRespondingReport = generateProcessError(app, 9350 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9351 activity, shortMsg, longMsg, null); 9352 startAppProblemLocked(app); 9353 app.stopFreezingAllLocked(); 9354 } 9355 9356 /** 9357 * Generate a process error record, suitable for attachment to a ProcessRecord. 9358 * 9359 * @param app The ProcessRecord in which the error occurred. 9360 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9361 * ActivityManager.AppErrorStateInfo 9362 * @param activity The activity associated with the crash, if known. 9363 * @param shortMsg Short message describing the crash. 9364 * @param longMsg Long message describing the crash. 9365 * @param stackTrace Full crash stack trace, may be null. 9366 * 9367 * @return Returns a fully-formed AppErrorStateInfo record. 9368 */ 9369 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9370 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9371 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9372 9373 report.condition = condition; 9374 report.processName = app.processName; 9375 report.pid = app.pid; 9376 report.uid = app.info.uid; 9377 report.tag = activity; 9378 report.shortMsg = shortMsg; 9379 report.longMsg = longMsg; 9380 report.stackTrace = stackTrace; 9381 9382 return report; 9383 } 9384 9385 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9386 synchronized (this) { 9387 app.crashing = false; 9388 app.crashingReport = null; 9389 app.notResponding = false; 9390 app.notRespondingReport = null; 9391 if (app.anrDialog == fromDialog) { 9392 app.anrDialog = null; 9393 } 9394 if (app.waitDialog == fromDialog) { 9395 app.waitDialog = null; 9396 } 9397 if (app.pid > 0 && app.pid != MY_PID) { 9398 handleAppCrashLocked(app, null, null, null); 9399 killUnneededProcessLocked(app, "user request after error"); 9400 } 9401 } 9402 } 9403 9404 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9405 String stackTrace) { 9406 long now = SystemClock.uptimeMillis(); 9407 9408 Long crashTime; 9409 if (!app.isolated) { 9410 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9411 } else { 9412 crashTime = null; 9413 } 9414 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9415 // This process loses! 9416 Slog.w(TAG, "Process " + app.info.processName 9417 + " has crashed too many times: killing!"); 9418 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9419 app.userId, app.info.processName, app.uid); 9420 mStackSupervisor.handleAppCrashLocked(app); 9421 if (!app.persistent) { 9422 // We don't want to start this process again until the user 9423 // explicitly does so... but for persistent process, we really 9424 // need to keep it running. If a persistent process is actually 9425 // repeatedly crashing, then badness for everyone. 9426 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9427 app.info.processName); 9428 if (!app.isolated) { 9429 // XXX We don't have a way to mark isolated processes 9430 // as bad, since they don't have a peristent identity. 9431 mBadProcesses.put(app.info.processName, app.uid, 9432 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9433 mProcessCrashTimes.remove(app.info.processName, app.uid); 9434 } 9435 app.bad = true; 9436 app.removed = true; 9437 // Don't let services in this process be restarted and potentially 9438 // annoy the user repeatedly. Unless it is persistent, since those 9439 // processes run critical code. 9440 removeProcessLocked(app, false, false, "crash"); 9441 mStackSupervisor.resumeTopActivitiesLocked(); 9442 return false; 9443 } 9444 mStackSupervisor.resumeTopActivitiesLocked(); 9445 } else { 9446 mStackSupervisor.finishTopRunningActivityLocked(app); 9447 } 9448 9449 // Bump up the crash count of any services currently running in the proc. 9450 for (int i=app.services.size()-1; i>=0; i--) { 9451 // Any services running in the application need to be placed 9452 // back in the pending list. 9453 ServiceRecord sr = app.services.valueAt(i); 9454 sr.crashCount++; 9455 } 9456 9457 // If the crashing process is what we consider to be the "home process" and it has been 9458 // replaced by a third-party app, clear the package preferred activities from packages 9459 // with a home activity running in the process to prevent a repeatedly crashing app 9460 // from blocking the user to manually clear the list. 9461 final ArrayList<ActivityRecord> activities = app.activities; 9462 if (app == mHomeProcess && activities.size() > 0 9463 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9464 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9465 final ActivityRecord r = activities.get(activityNdx); 9466 if (r.isHomeActivity()) { 9467 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9468 try { 9469 ActivityThread.getPackageManager() 9470 .clearPackagePreferredActivities(r.packageName); 9471 } catch (RemoteException c) { 9472 // pm is in same process, this will never happen. 9473 } 9474 } 9475 } 9476 } 9477 9478 if (!app.isolated) { 9479 // XXX Can't keep track of crash times for isolated processes, 9480 // because they don't have a perisistent identity. 9481 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9482 } 9483 9484 return true; 9485 } 9486 9487 void startAppProblemLocked(ProcessRecord app) { 9488 if (app.userId == mCurrentUserId) { 9489 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9490 mContext, app.info.packageName, app.info.flags); 9491 } else { 9492 // If this app is not running under the current user, then we 9493 // can't give it a report button because that would require 9494 // launching the report UI under a different user. 9495 app.errorReportReceiver = null; 9496 } 9497 skipCurrentReceiverLocked(app); 9498 } 9499 9500 void skipCurrentReceiverLocked(ProcessRecord app) { 9501 for (BroadcastQueue queue : mBroadcastQueues) { 9502 queue.skipCurrentReceiverLocked(app); 9503 } 9504 } 9505 9506 /** 9507 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9508 * The application process will exit immediately after this call returns. 9509 * @param app object of the crashing app, null for the system server 9510 * @param crashInfo describing the exception 9511 */ 9512 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9513 ProcessRecord r = findAppProcess(app, "Crash"); 9514 final String processName = app == null ? "system_server" 9515 : (r == null ? "unknown" : r.processName); 9516 9517 handleApplicationCrashInner("crash", r, processName, crashInfo); 9518 } 9519 9520 /* Native crash reporting uses this inner version because it needs to be somewhat 9521 * decoupled from the AM-managed cleanup lifecycle 9522 */ 9523 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9524 ApplicationErrorReport.CrashInfo crashInfo) { 9525 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9526 UserHandle.getUserId(Binder.getCallingUid()), processName, 9527 r == null ? -1 : r.info.flags, 9528 crashInfo.exceptionClassName, 9529 crashInfo.exceptionMessage, 9530 crashInfo.throwFileName, 9531 crashInfo.throwLineNumber); 9532 9533 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9534 9535 crashApplication(r, crashInfo); 9536 } 9537 9538 public void handleApplicationStrictModeViolation( 9539 IBinder app, 9540 int violationMask, 9541 StrictMode.ViolationInfo info) { 9542 ProcessRecord r = findAppProcess(app, "StrictMode"); 9543 if (r == null) { 9544 return; 9545 } 9546 9547 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9548 Integer stackFingerprint = info.hashCode(); 9549 boolean logIt = true; 9550 synchronized (mAlreadyLoggedViolatedStacks) { 9551 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9552 logIt = false; 9553 // TODO: sub-sample into EventLog for these, with 9554 // the info.durationMillis? Then we'd get 9555 // the relative pain numbers, without logging all 9556 // the stack traces repeatedly. We'd want to do 9557 // likewise in the client code, which also does 9558 // dup suppression, before the Binder call. 9559 } else { 9560 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9561 mAlreadyLoggedViolatedStacks.clear(); 9562 } 9563 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9564 } 9565 } 9566 if (logIt) { 9567 logStrictModeViolationToDropBox(r, info); 9568 } 9569 } 9570 9571 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9572 AppErrorResult result = new AppErrorResult(); 9573 synchronized (this) { 9574 final long origId = Binder.clearCallingIdentity(); 9575 9576 Message msg = Message.obtain(); 9577 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9578 HashMap<String, Object> data = new HashMap<String, Object>(); 9579 data.put("result", result); 9580 data.put("app", r); 9581 data.put("violationMask", violationMask); 9582 data.put("info", info); 9583 msg.obj = data; 9584 mHandler.sendMessage(msg); 9585 9586 Binder.restoreCallingIdentity(origId); 9587 } 9588 int res = result.get(); 9589 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9590 } 9591 } 9592 9593 // Depending on the policy in effect, there could be a bunch of 9594 // these in quick succession so we try to batch these together to 9595 // minimize disk writes, number of dropbox entries, and maximize 9596 // compression, by having more fewer, larger records. 9597 private void logStrictModeViolationToDropBox( 9598 ProcessRecord process, 9599 StrictMode.ViolationInfo info) { 9600 if (info == null) { 9601 return; 9602 } 9603 final boolean isSystemApp = process == null || 9604 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9605 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9606 final String processName = process == null ? "unknown" : process.processName; 9607 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9608 final DropBoxManager dbox = (DropBoxManager) 9609 mContext.getSystemService(Context.DROPBOX_SERVICE); 9610 9611 // Exit early if the dropbox isn't configured to accept this report type. 9612 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9613 9614 boolean bufferWasEmpty; 9615 boolean needsFlush; 9616 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9617 synchronized (sb) { 9618 bufferWasEmpty = sb.length() == 0; 9619 appendDropBoxProcessHeaders(process, processName, sb); 9620 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9621 sb.append("System-App: ").append(isSystemApp).append("\n"); 9622 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9623 if (info.violationNumThisLoop != 0) { 9624 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9625 } 9626 if (info.numAnimationsRunning != 0) { 9627 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9628 } 9629 if (info.broadcastIntentAction != null) { 9630 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9631 } 9632 if (info.durationMillis != -1) { 9633 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9634 } 9635 if (info.numInstances != -1) { 9636 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9637 } 9638 if (info.tags != null) { 9639 for (String tag : info.tags) { 9640 sb.append("Span-Tag: ").append(tag).append("\n"); 9641 } 9642 } 9643 sb.append("\n"); 9644 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9645 sb.append(info.crashInfo.stackTrace); 9646 } 9647 sb.append("\n"); 9648 9649 // Only buffer up to ~64k. Various logging bits truncate 9650 // things at 128k. 9651 needsFlush = (sb.length() > 64 * 1024); 9652 } 9653 9654 // Flush immediately if the buffer's grown too large, or this 9655 // is a non-system app. Non-system apps are isolated with a 9656 // different tag & policy and not batched. 9657 // 9658 // Batching is useful during internal testing with 9659 // StrictMode settings turned up high. Without batching, 9660 // thousands of separate files could be created on boot. 9661 if (!isSystemApp || needsFlush) { 9662 new Thread("Error dump: " + dropboxTag) { 9663 @Override 9664 public void run() { 9665 String report; 9666 synchronized (sb) { 9667 report = sb.toString(); 9668 sb.delete(0, sb.length()); 9669 sb.trimToSize(); 9670 } 9671 if (report.length() != 0) { 9672 dbox.addText(dropboxTag, report); 9673 } 9674 } 9675 }.start(); 9676 return; 9677 } 9678 9679 // System app batching: 9680 if (!bufferWasEmpty) { 9681 // An existing dropbox-writing thread is outstanding, so 9682 // we don't need to start it up. The existing thread will 9683 // catch the buffer appends we just did. 9684 return; 9685 } 9686 9687 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9688 // (After this point, we shouldn't access AMS internal data structures.) 9689 new Thread("Error dump: " + dropboxTag) { 9690 @Override 9691 public void run() { 9692 // 5 second sleep to let stacks arrive and be batched together 9693 try { 9694 Thread.sleep(5000); // 5 seconds 9695 } catch (InterruptedException e) {} 9696 9697 String errorReport; 9698 synchronized (mStrictModeBuffer) { 9699 errorReport = mStrictModeBuffer.toString(); 9700 if (errorReport.length() == 0) { 9701 return; 9702 } 9703 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9704 mStrictModeBuffer.trimToSize(); 9705 } 9706 dbox.addText(dropboxTag, errorReport); 9707 } 9708 }.start(); 9709 } 9710 9711 /** 9712 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9713 * @param app object of the crashing app, null for the system server 9714 * @param tag reported by the caller 9715 * @param crashInfo describing the context of the error 9716 * @return true if the process should exit immediately (WTF is fatal) 9717 */ 9718 public boolean handleApplicationWtf(IBinder app, String tag, 9719 ApplicationErrorReport.CrashInfo crashInfo) { 9720 ProcessRecord r = findAppProcess(app, "WTF"); 9721 final String processName = app == null ? "system_server" 9722 : (r == null ? "unknown" : r.processName); 9723 9724 EventLog.writeEvent(EventLogTags.AM_WTF, 9725 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9726 processName, 9727 r == null ? -1 : r.info.flags, 9728 tag, crashInfo.exceptionMessage); 9729 9730 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9731 9732 if (r != null && r.pid != Process.myPid() && 9733 Settings.Global.getInt(mContext.getContentResolver(), 9734 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9735 crashApplication(r, crashInfo); 9736 return true; 9737 } else { 9738 return false; 9739 } 9740 } 9741 9742 /** 9743 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9744 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9745 */ 9746 private ProcessRecord findAppProcess(IBinder app, String reason) { 9747 if (app == null) { 9748 return null; 9749 } 9750 9751 synchronized (this) { 9752 final int NP = mProcessNames.getMap().size(); 9753 for (int ip=0; ip<NP; ip++) { 9754 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9755 final int NA = apps.size(); 9756 for (int ia=0; ia<NA; ia++) { 9757 ProcessRecord p = apps.valueAt(ia); 9758 if (p.thread != null && p.thread.asBinder() == app) { 9759 return p; 9760 } 9761 } 9762 } 9763 9764 Slog.w(TAG, "Can't find mystery application for " + reason 9765 + " from pid=" + Binder.getCallingPid() 9766 + " uid=" + Binder.getCallingUid() + ": " + app); 9767 return null; 9768 } 9769 } 9770 9771 /** 9772 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9773 * to append various headers to the dropbox log text. 9774 */ 9775 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9776 StringBuilder sb) { 9777 // Watchdog thread ends up invoking this function (with 9778 // a null ProcessRecord) to add the stack file to dropbox. 9779 // Do not acquire a lock on this (am) in such cases, as it 9780 // could cause a potential deadlock, if and when watchdog 9781 // is invoked due to unavailability of lock on am and it 9782 // would prevent watchdog from killing system_server. 9783 if (process == null) { 9784 sb.append("Process: ").append(processName).append("\n"); 9785 return; 9786 } 9787 // Note: ProcessRecord 'process' is guarded by the service 9788 // instance. (notably process.pkgList, which could otherwise change 9789 // concurrently during execution of this method) 9790 synchronized (this) { 9791 sb.append("Process: ").append(processName).append("\n"); 9792 int flags = process.info.flags; 9793 IPackageManager pm = AppGlobals.getPackageManager(); 9794 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 9795 for (int ip=0; ip<process.pkgList.size(); ip++) { 9796 String pkg = process.pkgList.keyAt(ip); 9797 sb.append("Package: ").append(pkg); 9798 try { 9799 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 9800 if (pi != null) { 9801 sb.append(" v").append(pi.versionCode); 9802 if (pi.versionName != null) { 9803 sb.append(" (").append(pi.versionName).append(")"); 9804 } 9805 } 9806 } catch (RemoteException e) { 9807 Slog.e(TAG, "Error getting package info: " + pkg, e); 9808 } 9809 sb.append("\n"); 9810 } 9811 } 9812 } 9813 9814 private static String processClass(ProcessRecord process) { 9815 if (process == null || process.pid == MY_PID) { 9816 return "system_server"; 9817 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9818 return "system_app"; 9819 } else { 9820 return "data_app"; 9821 } 9822 } 9823 9824 /** 9825 * Write a description of an error (crash, WTF, ANR) to the drop box. 9826 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 9827 * @param process which caused the error, null means the system server 9828 * @param activity which triggered the error, null if unknown 9829 * @param parent activity related to the error, null if unknown 9830 * @param subject line related to the error, null if absent 9831 * @param report in long form describing the error, null if absent 9832 * @param logFile to include in the report, null if none 9833 * @param crashInfo giving an application stack trace, null if absent 9834 */ 9835 public void addErrorToDropBox(String eventType, 9836 ProcessRecord process, String processName, ActivityRecord activity, 9837 ActivityRecord parent, String subject, 9838 final String report, final File logFile, 9839 final ApplicationErrorReport.CrashInfo crashInfo) { 9840 // NOTE -- this must never acquire the ActivityManagerService lock, 9841 // otherwise the watchdog may be prevented from resetting the system. 9842 9843 final String dropboxTag = processClass(process) + "_" + eventType; 9844 final DropBoxManager dbox = (DropBoxManager) 9845 mContext.getSystemService(Context.DROPBOX_SERVICE); 9846 9847 // Exit early if the dropbox isn't configured to accept this report type. 9848 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9849 9850 final StringBuilder sb = new StringBuilder(1024); 9851 appendDropBoxProcessHeaders(process, processName, sb); 9852 if (activity != null) { 9853 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 9854 } 9855 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 9856 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 9857 } 9858 if (parent != null && parent != activity) { 9859 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 9860 } 9861 if (subject != null) { 9862 sb.append("Subject: ").append(subject).append("\n"); 9863 } 9864 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9865 if (Debug.isDebuggerConnected()) { 9866 sb.append("Debugger: Connected\n"); 9867 } 9868 sb.append("\n"); 9869 9870 // Do the rest in a worker thread to avoid blocking the caller on I/O 9871 // (After this point, we shouldn't access AMS internal data structures.) 9872 Thread worker = new Thread("Error dump: " + dropboxTag) { 9873 @Override 9874 public void run() { 9875 if (report != null) { 9876 sb.append(report); 9877 } 9878 if (logFile != null) { 9879 try { 9880 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 9881 "\n\n[[TRUNCATED]]")); 9882 } catch (IOException e) { 9883 Slog.e(TAG, "Error reading " + logFile, e); 9884 } 9885 } 9886 if (crashInfo != null && crashInfo.stackTrace != null) { 9887 sb.append(crashInfo.stackTrace); 9888 } 9889 9890 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 9891 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 9892 if (lines > 0) { 9893 sb.append("\n"); 9894 9895 // Merge several logcat streams, and take the last N lines 9896 InputStreamReader input = null; 9897 try { 9898 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 9899 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 9900 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 9901 9902 try { logcat.getOutputStream().close(); } catch (IOException e) {} 9903 try { logcat.getErrorStream().close(); } catch (IOException e) {} 9904 input = new InputStreamReader(logcat.getInputStream()); 9905 9906 int num; 9907 char[] buf = new char[8192]; 9908 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 9909 } catch (IOException e) { 9910 Slog.e(TAG, "Error running logcat", e); 9911 } finally { 9912 if (input != null) try { input.close(); } catch (IOException e) {} 9913 } 9914 } 9915 9916 dbox.addText(dropboxTag, sb.toString()); 9917 } 9918 }; 9919 9920 if (process == null) { 9921 // If process is null, we are being called from some internal code 9922 // and may be about to die -- run this synchronously. 9923 worker.run(); 9924 } else { 9925 worker.start(); 9926 } 9927 } 9928 9929 /** 9930 * Bring up the "unexpected error" dialog box for a crashing app. 9931 * Deal with edge cases (intercepts from instrumented applications, 9932 * ActivityController, error intent receivers, that sort of thing). 9933 * @param r the application crashing 9934 * @param crashInfo describing the failure 9935 */ 9936 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 9937 long timeMillis = System.currentTimeMillis(); 9938 String shortMsg = crashInfo.exceptionClassName; 9939 String longMsg = crashInfo.exceptionMessage; 9940 String stackTrace = crashInfo.stackTrace; 9941 if (shortMsg != null && longMsg != null) { 9942 longMsg = shortMsg + ": " + longMsg; 9943 } else if (shortMsg != null) { 9944 longMsg = shortMsg; 9945 } 9946 9947 AppErrorResult result = new AppErrorResult(); 9948 synchronized (this) { 9949 if (mController != null) { 9950 try { 9951 String name = r != null ? r.processName : null; 9952 int pid = r != null ? r.pid : Binder.getCallingPid(); 9953 if (!mController.appCrashed(name, pid, 9954 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 9955 Slog.w(TAG, "Force-killing crashed app " + name 9956 + " at watcher's request"); 9957 Process.killProcess(pid); 9958 return; 9959 } 9960 } catch (RemoteException e) { 9961 mController = null; 9962 Watchdog.getInstance().setActivityController(null); 9963 } 9964 } 9965 9966 final long origId = Binder.clearCallingIdentity(); 9967 9968 // If this process is running instrumentation, finish it. 9969 if (r != null && r.instrumentationClass != null) { 9970 Slog.w(TAG, "Error in app " + r.processName 9971 + " running instrumentation " + r.instrumentationClass + ":"); 9972 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 9973 if (longMsg != null) Slog.w(TAG, " " + longMsg); 9974 Bundle info = new Bundle(); 9975 info.putString("shortMsg", shortMsg); 9976 info.putString("longMsg", longMsg); 9977 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 9978 Binder.restoreCallingIdentity(origId); 9979 return; 9980 } 9981 9982 // If we can't identify the process or it's already exceeded its crash quota, 9983 // quit right away without showing a crash dialog. 9984 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 9985 Binder.restoreCallingIdentity(origId); 9986 return; 9987 } 9988 9989 Message msg = Message.obtain(); 9990 msg.what = SHOW_ERROR_MSG; 9991 HashMap data = new HashMap(); 9992 data.put("result", result); 9993 data.put("app", r); 9994 msg.obj = data; 9995 mHandler.sendMessage(msg); 9996 9997 Binder.restoreCallingIdentity(origId); 9998 } 9999 10000 int res = result.get(); 10001 10002 Intent appErrorIntent = null; 10003 synchronized (this) { 10004 if (r != null && !r.isolated) { 10005 // XXX Can't keep track of crash time for isolated processes, 10006 // since they don't have a persistent identity. 10007 mProcessCrashTimes.put(r.info.processName, r.uid, 10008 SystemClock.uptimeMillis()); 10009 } 10010 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10011 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10012 } 10013 } 10014 10015 if (appErrorIntent != null) { 10016 try { 10017 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10018 } catch (ActivityNotFoundException e) { 10019 Slog.w(TAG, "bug report receiver dissappeared", e); 10020 } 10021 } 10022 } 10023 10024 Intent createAppErrorIntentLocked(ProcessRecord r, 10025 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10026 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10027 if (report == null) { 10028 return null; 10029 } 10030 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10031 result.setComponent(r.errorReportReceiver); 10032 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10033 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10034 return result; 10035 } 10036 10037 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10038 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10039 if (r.errorReportReceiver == null) { 10040 return null; 10041 } 10042 10043 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10044 return null; 10045 } 10046 10047 ApplicationErrorReport report = new ApplicationErrorReport(); 10048 report.packageName = r.info.packageName; 10049 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10050 report.processName = r.processName; 10051 report.time = timeMillis; 10052 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10053 10054 if (r.crashing || r.forceCrashReport) { 10055 report.type = ApplicationErrorReport.TYPE_CRASH; 10056 report.crashInfo = crashInfo; 10057 } else if (r.notResponding) { 10058 report.type = ApplicationErrorReport.TYPE_ANR; 10059 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10060 10061 report.anrInfo.activity = r.notRespondingReport.tag; 10062 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10063 report.anrInfo.info = r.notRespondingReport.longMsg; 10064 } 10065 10066 return report; 10067 } 10068 10069 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10070 enforceNotIsolatedCaller("getProcessesInErrorState"); 10071 // assume our apps are happy - lazy create the list 10072 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10073 10074 final boolean allUsers = ActivityManager.checkUidPermission( 10075 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10076 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10077 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10078 10079 synchronized (this) { 10080 10081 // iterate across all processes 10082 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10083 ProcessRecord app = mLruProcesses.get(i); 10084 if (!allUsers && app.userId != userId) { 10085 continue; 10086 } 10087 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10088 // This one's in trouble, so we'll generate a report for it 10089 // crashes are higher priority (in case there's a crash *and* an anr) 10090 ActivityManager.ProcessErrorStateInfo report = null; 10091 if (app.crashing) { 10092 report = app.crashingReport; 10093 } else if (app.notResponding) { 10094 report = app.notRespondingReport; 10095 } 10096 10097 if (report != null) { 10098 if (errList == null) { 10099 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10100 } 10101 errList.add(report); 10102 } else { 10103 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10104 " crashing = " + app.crashing + 10105 " notResponding = " + app.notResponding); 10106 } 10107 } 10108 } 10109 } 10110 10111 return errList; 10112 } 10113 10114 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10115 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10116 if (currApp != null) { 10117 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10118 } 10119 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10120 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10121 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10122 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10123 if (currApp != null) { 10124 currApp.lru = 0; 10125 } 10126 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10127 } else if (adj >= ProcessList.SERVICE_ADJ) { 10128 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10129 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10130 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10131 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10132 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10133 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10134 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10135 } else { 10136 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10137 } 10138 } 10139 10140 private void fillInProcMemInfo(ProcessRecord app, 10141 ActivityManager.RunningAppProcessInfo outInfo) { 10142 outInfo.pid = app.pid; 10143 outInfo.uid = app.info.uid; 10144 if (mHeavyWeightProcess == app) { 10145 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10146 } 10147 if (app.persistent) { 10148 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10149 } 10150 if (app.activities.size() > 0) { 10151 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10152 } 10153 outInfo.lastTrimLevel = app.trimMemoryLevel; 10154 int adj = app.curAdj; 10155 outInfo.importance = oomAdjToImportance(adj, outInfo); 10156 outInfo.importanceReasonCode = app.adjTypeCode; 10157 } 10158 10159 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10160 enforceNotIsolatedCaller("getRunningAppProcesses"); 10161 // Lazy instantiation of list 10162 List<ActivityManager.RunningAppProcessInfo> runList = null; 10163 final boolean allUsers = ActivityManager.checkUidPermission( 10164 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10165 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10166 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10167 synchronized (this) { 10168 // Iterate across all processes 10169 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10170 ProcessRecord app = mLruProcesses.get(i); 10171 if (!allUsers && app.userId != userId) { 10172 continue; 10173 } 10174 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10175 // Generate process state info for running application 10176 ActivityManager.RunningAppProcessInfo currApp = 10177 new ActivityManager.RunningAppProcessInfo(app.processName, 10178 app.pid, app.getPackageList()); 10179 fillInProcMemInfo(app, currApp); 10180 if (app.adjSource instanceof ProcessRecord) { 10181 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10182 currApp.importanceReasonImportance = oomAdjToImportance( 10183 app.adjSourceOom, null); 10184 } else if (app.adjSource instanceof ActivityRecord) { 10185 ActivityRecord r = (ActivityRecord)app.adjSource; 10186 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10187 } 10188 if (app.adjTarget instanceof ComponentName) { 10189 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10190 } 10191 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10192 // + " lru=" + currApp.lru); 10193 if (runList == null) { 10194 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10195 } 10196 runList.add(currApp); 10197 } 10198 } 10199 } 10200 return runList; 10201 } 10202 10203 public List<ApplicationInfo> getRunningExternalApplications() { 10204 enforceNotIsolatedCaller("getRunningExternalApplications"); 10205 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10206 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10207 if (runningApps != null && runningApps.size() > 0) { 10208 Set<String> extList = new HashSet<String>(); 10209 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10210 if (app.pkgList != null) { 10211 for (String pkg : app.pkgList) { 10212 extList.add(pkg); 10213 } 10214 } 10215 } 10216 IPackageManager pm = AppGlobals.getPackageManager(); 10217 for (String pkg : extList) { 10218 try { 10219 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10220 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10221 retList.add(info); 10222 } 10223 } catch (RemoteException e) { 10224 } 10225 } 10226 } 10227 return retList; 10228 } 10229 10230 @Override 10231 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10232 enforceNotIsolatedCaller("getMyMemoryState"); 10233 synchronized (this) { 10234 ProcessRecord proc; 10235 synchronized (mPidsSelfLocked) { 10236 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10237 } 10238 fillInProcMemInfo(proc, outInfo); 10239 } 10240 } 10241 10242 @Override 10243 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10244 if (checkCallingPermission(android.Manifest.permission.DUMP) 10245 != PackageManager.PERMISSION_GRANTED) { 10246 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10247 + Binder.getCallingPid() 10248 + ", uid=" + Binder.getCallingUid() 10249 + " without permission " 10250 + android.Manifest.permission.DUMP); 10251 return; 10252 } 10253 10254 boolean dumpAll = false; 10255 boolean dumpClient = false; 10256 String dumpPackage = null; 10257 10258 int opti = 0; 10259 while (opti < args.length) { 10260 String opt = args[opti]; 10261 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10262 break; 10263 } 10264 opti++; 10265 if ("-a".equals(opt)) { 10266 dumpAll = true; 10267 } else if ("-c".equals(opt)) { 10268 dumpClient = true; 10269 } else if ("-h".equals(opt)) { 10270 pw.println("Activity manager dump options:"); 10271 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10272 pw.println(" cmd may be one of:"); 10273 pw.println(" a[ctivities]: activity stack state"); 10274 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10275 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10276 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10277 pw.println(" o[om]: out of memory management"); 10278 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10279 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10280 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10281 pw.println(" service [COMP_SPEC]: service client-side state"); 10282 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10283 pw.println(" all: dump all activities"); 10284 pw.println(" top: dump the top activity"); 10285 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10286 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10287 pw.println(" a partial substring in a component name, a"); 10288 pw.println(" hex object identifier."); 10289 pw.println(" -a: include all available server state."); 10290 pw.println(" -c: include client state."); 10291 return; 10292 } else { 10293 pw.println("Unknown argument: " + opt + "; use -h for help"); 10294 } 10295 } 10296 10297 long origId = Binder.clearCallingIdentity(); 10298 boolean more = false; 10299 // Is the caller requesting to dump a particular piece of data? 10300 if (opti < args.length) { 10301 String cmd = args[opti]; 10302 opti++; 10303 if ("activities".equals(cmd) || "a".equals(cmd)) { 10304 synchronized (this) { 10305 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10306 } 10307 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10308 String[] newArgs; 10309 String name; 10310 if (opti >= args.length) { 10311 name = null; 10312 newArgs = EMPTY_STRING_ARRAY; 10313 } else { 10314 name = args[opti]; 10315 opti++; 10316 newArgs = new String[args.length - opti]; 10317 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10318 args.length - opti); 10319 } 10320 synchronized (this) { 10321 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10322 } 10323 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10324 String[] newArgs; 10325 String name; 10326 if (opti >= args.length) { 10327 name = null; 10328 newArgs = EMPTY_STRING_ARRAY; 10329 } else { 10330 name = args[opti]; 10331 opti++; 10332 newArgs = new String[args.length - opti]; 10333 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10334 args.length - opti); 10335 } 10336 synchronized (this) { 10337 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10338 } 10339 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10340 String[] newArgs; 10341 String name; 10342 if (opti >= args.length) { 10343 name = null; 10344 newArgs = EMPTY_STRING_ARRAY; 10345 } else { 10346 name = args[opti]; 10347 opti++; 10348 newArgs = new String[args.length - opti]; 10349 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10350 args.length - opti); 10351 } 10352 synchronized (this) { 10353 dumpProcessesLocked(fd, pw, args, opti, true, name); 10354 } 10355 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10356 synchronized (this) { 10357 dumpOomLocked(fd, pw, args, opti, true); 10358 } 10359 } else if ("provider".equals(cmd)) { 10360 String[] newArgs; 10361 String name; 10362 if (opti >= args.length) { 10363 name = null; 10364 newArgs = EMPTY_STRING_ARRAY; 10365 } else { 10366 name = args[opti]; 10367 opti++; 10368 newArgs = new String[args.length - opti]; 10369 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10370 } 10371 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10372 pw.println("No providers match: " + name); 10373 pw.println("Use -h for help."); 10374 } 10375 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10376 synchronized (this) { 10377 dumpProvidersLocked(fd, pw, args, opti, true, null); 10378 } 10379 } else if ("service".equals(cmd)) { 10380 String[] newArgs; 10381 String name; 10382 if (opti >= args.length) { 10383 name = null; 10384 newArgs = EMPTY_STRING_ARRAY; 10385 } else { 10386 name = args[opti]; 10387 opti++; 10388 newArgs = new String[args.length - opti]; 10389 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10390 args.length - opti); 10391 } 10392 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10393 pw.println("No services match: " + name); 10394 pw.println("Use -h for help."); 10395 } 10396 } else if ("package".equals(cmd)) { 10397 String[] newArgs; 10398 if (opti >= args.length) { 10399 pw.println("package: no package name specified"); 10400 pw.println("Use -h for help."); 10401 } else { 10402 dumpPackage = args[opti]; 10403 opti++; 10404 newArgs = new String[args.length - opti]; 10405 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10406 args.length - opti); 10407 args = newArgs; 10408 opti = 0; 10409 more = true; 10410 } 10411 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10412 synchronized (this) { 10413 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10414 } 10415 } else { 10416 // Dumping a single activity? 10417 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10418 pw.println("Bad activity command, or no activities match: " + cmd); 10419 pw.println("Use -h for help."); 10420 } 10421 } 10422 if (!more) { 10423 Binder.restoreCallingIdentity(origId); 10424 return; 10425 } 10426 } 10427 10428 // No piece of data specified, dump everything. 10429 synchronized (this) { 10430 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10431 pw.println(); 10432 if (dumpAll) { 10433 pw.println("-------------------------------------------------------------------------------"); 10434 } 10435 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10436 pw.println(); 10437 if (dumpAll) { 10438 pw.println("-------------------------------------------------------------------------------"); 10439 } 10440 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10441 pw.println(); 10442 if (dumpAll) { 10443 pw.println("-------------------------------------------------------------------------------"); 10444 } 10445 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10446 pw.println(); 10447 if (dumpAll) { 10448 pw.println("-------------------------------------------------------------------------------"); 10449 } 10450 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10451 pw.println(); 10452 if (dumpAll) { 10453 pw.println("-------------------------------------------------------------------------------"); 10454 } 10455 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10456 } 10457 Binder.restoreCallingIdentity(origId); 10458 } 10459 10460 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10461 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10462 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10463 10464 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10465 dumpPackage); 10466 boolean needSep = printedAnything; 10467 10468 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10469 dumpPackage, needSep, " mFocusedActivity: "); 10470 if (printed) { 10471 printedAnything = true; 10472 needSep = false; 10473 } 10474 10475 if (dumpPackage == null) { 10476 if (needSep) { 10477 pw.println(); 10478 } 10479 needSep = true; 10480 printedAnything = true; 10481 mStackSupervisor.dump(pw, " "); 10482 } 10483 10484 if (mRecentTasks.size() > 0) { 10485 boolean printedHeader = false; 10486 10487 final int N = mRecentTasks.size(); 10488 for (int i=0; i<N; i++) { 10489 TaskRecord tr = mRecentTasks.get(i); 10490 if (dumpPackage != null) { 10491 if (tr.realActivity == null || 10492 !dumpPackage.equals(tr.realActivity)) { 10493 continue; 10494 } 10495 } 10496 if (!printedHeader) { 10497 if (needSep) { 10498 pw.println(); 10499 } 10500 pw.println(" Recent tasks:"); 10501 printedHeader = true; 10502 printedAnything = true; 10503 } 10504 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10505 pw.println(tr); 10506 if (dumpAll) { 10507 mRecentTasks.get(i).dump(pw, " "); 10508 } 10509 } 10510 } 10511 10512 if (!printedAnything) { 10513 pw.println(" (nothing)"); 10514 } 10515 } 10516 10517 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10518 int opti, boolean dumpAll, String dumpPackage) { 10519 boolean needSep = false; 10520 boolean printedAnything = false; 10521 int numPers = 0; 10522 10523 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10524 10525 if (dumpAll) { 10526 final int NP = mProcessNames.getMap().size(); 10527 for (int ip=0; ip<NP; ip++) { 10528 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10529 final int NA = procs.size(); 10530 for (int ia=0; ia<NA; ia++) { 10531 ProcessRecord r = procs.valueAt(ia); 10532 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10533 continue; 10534 } 10535 if (!needSep) { 10536 pw.println(" All known processes:"); 10537 needSep = true; 10538 printedAnything = true; 10539 } 10540 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10541 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10542 pw.print(" "); pw.println(r); 10543 r.dump(pw, " "); 10544 if (r.persistent) { 10545 numPers++; 10546 } 10547 } 10548 } 10549 } 10550 10551 if (mIsolatedProcesses.size() > 0) { 10552 boolean printed = false; 10553 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10554 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10555 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10556 continue; 10557 } 10558 if (!printed) { 10559 if (needSep) { 10560 pw.println(); 10561 } 10562 pw.println(" Isolated process list (sorted by uid):"); 10563 printedAnything = true; 10564 printed = true; 10565 needSep = true; 10566 } 10567 pw.println(String.format("%sIsolated #%2d: %s", 10568 " ", i, r.toString())); 10569 } 10570 } 10571 10572 if (mLruProcesses.size() > 0) { 10573 if (needSep) { 10574 pw.println(); 10575 } 10576 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10577 pw.print(" total, non-act at "); 10578 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10579 pw.print(", non-svc at "); 10580 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10581 pw.println("):"); 10582 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10583 needSep = true; 10584 printedAnything = true; 10585 } 10586 10587 if (dumpAll || dumpPackage != null) { 10588 synchronized (mPidsSelfLocked) { 10589 boolean printed = false; 10590 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10591 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10592 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10593 continue; 10594 } 10595 if (!printed) { 10596 if (needSep) pw.println(); 10597 needSep = true; 10598 pw.println(" PID mappings:"); 10599 printed = true; 10600 printedAnything = true; 10601 } 10602 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10603 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10604 } 10605 } 10606 } 10607 10608 if (mForegroundProcesses.size() > 0) { 10609 synchronized (mPidsSelfLocked) { 10610 boolean printed = false; 10611 for (int i=0; i<mForegroundProcesses.size(); i++) { 10612 ProcessRecord r = mPidsSelfLocked.get( 10613 mForegroundProcesses.valueAt(i).pid); 10614 if (dumpPackage != null && (r == null 10615 || !r.pkgList.containsKey(dumpPackage))) { 10616 continue; 10617 } 10618 if (!printed) { 10619 if (needSep) pw.println(); 10620 needSep = true; 10621 pw.println(" Foreground Processes:"); 10622 printed = true; 10623 printedAnything = true; 10624 } 10625 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10626 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10627 } 10628 } 10629 } 10630 10631 if (mPersistentStartingProcesses.size() > 0) { 10632 if (needSep) pw.println(); 10633 needSep = true; 10634 printedAnything = true; 10635 pw.println(" Persisent processes that are starting:"); 10636 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10637 "Starting Norm", "Restarting PERS", dumpPackage); 10638 } 10639 10640 if (mRemovedProcesses.size() > 0) { 10641 if (needSep) pw.println(); 10642 needSep = true; 10643 printedAnything = true; 10644 pw.println(" Processes that are being removed:"); 10645 dumpProcessList(pw, this, mRemovedProcesses, " ", 10646 "Removed Norm", "Removed PERS", dumpPackage); 10647 } 10648 10649 if (mProcessesOnHold.size() > 0) { 10650 if (needSep) pw.println(); 10651 needSep = true; 10652 printedAnything = true; 10653 pw.println(" Processes that are on old until the system is ready:"); 10654 dumpProcessList(pw, this, mProcessesOnHold, " ", 10655 "OnHold Norm", "OnHold PERS", dumpPackage); 10656 } 10657 10658 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10659 10660 if (mProcessCrashTimes.getMap().size() > 0) { 10661 boolean printed = false; 10662 long now = SystemClock.uptimeMillis(); 10663 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10664 final int NP = pmap.size(); 10665 for (int ip=0; ip<NP; ip++) { 10666 String pname = pmap.keyAt(ip); 10667 SparseArray<Long> uids = pmap.valueAt(ip); 10668 final int N = uids.size(); 10669 for (int i=0; i<N; i++) { 10670 int puid = uids.keyAt(i); 10671 ProcessRecord r = mProcessNames.get(pname, puid); 10672 if (dumpPackage != null && (r == null 10673 || !r.pkgList.containsKey(dumpPackage))) { 10674 continue; 10675 } 10676 if (!printed) { 10677 if (needSep) pw.println(); 10678 needSep = true; 10679 pw.println(" Time since processes crashed:"); 10680 printed = true; 10681 printedAnything = true; 10682 } 10683 pw.print(" Process "); pw.print(pname); 10684 pw.print(" uid "); pw.print(puid); 10685 pw.print(": last crashed "); 10686 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10687 pw.println(" ago"); 10688 } 10689 } 10690 } 10691 10692 if (mBadProcesses.getMap().size() > 0) { 10693 boolean printed = false; 10694 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10695 final int NP = pmap.size(); 10696 for (int ip=0; ip<NP; ip++) { 10697 String pname = pmap.keyAt(ip); 10698 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10699 final int N = uids.size(); 10700 for (int i=0; i<N; i++) { 10701 int puid = uids.keyAt(i); 10702 ProcessRecord r = mProcessNames.get(pname, puid); 10703 if (dumpPackage != null && (r == null 10704 || !r.pkgList.containsKey(dumpPackage))) { 10705 continue; 10706 } 10707 if (!printed) { 10708 if (needSep) pw.println(); 10709 needSep = true; 10710 pw.println(" Bad processes:"); 10711 printedAnything = true; 10712 } 10713 BadProcessInfo info = uids.valueAt(i); 10714 pw.print(" Bad process "); pw.print(pname); 10715 pw.print(" uid "); pw.print(puid); 10716 pw.print(": crashed at time "); pw.println(info.time); 10717 if (info.shortMsg != null) { 10718 pw.print(" Short msg: "); pw.println(info.shortMsg); 10719 } 10720 if (info.longMsg != null) { 10721 pw.print(" Long msg: "); pw.println(info.longMsg); 10722 } 10723 if (info.stack != null) { 10724 pw.println(" Stack:"); 10725 int lastPos = 0; 10726 for (int pos=0; pos<info.stack.length(); pos++) { 10727 if (info.stack.charAt(pos) == '\n') { 10728 pw.print(" "); 10729 pw.write(info.stack, lastPos, pos-lastPos); 10730 pw.println(); 10731 lastPos = pos+1; 10732 } 10733 } 10734 if (lastPos < info.stack.length()) { 10735 pw.print(" "); 10736 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10737 pw.println(); 10738 } 10739 } 10740 } 10741 } 10742 } 10743 10744 if (dumpPackage == null) { 10745 pw.println(); 10746 needSep = false; 10747 pw.println(" mStartedUsers:"); 10748 for (int i=0; i<mStartedUsers.size(); i++) { 10749 UserStartedState uss = mStartedUsers.valueAt(i); 10750 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10751 pw.print(": "); uss.dump("", pw); 10752 } 10753 pw.print(" mStartedUserArray: ["); 10754 for (int i=0; i<mStartedUserArray.length; i++) { 10755 if (i > 0) pw.print(", "); 10756 pw.print(mStartedUserArray[i]); 10757 } 10758 pw.println("]"); 10759 pw.print(" mUserLru: ["); 10760 for (int i=0; i<mUserLru.size(); i++) { 10761 if (i > 0) pw.print(", "); 10762 pw.print(mUserLru.get(i)); 10763 } 10764 pw.println("]"); 10765 if (dumpAll) { 10766 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10767 } 10768 } 10769 if (mHomeProcess != null && (dumpPackage == null 10770 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10771 if (needSep) { 10772 pw.println(); 10773 needSep = false; 10774 } 10775 pw.println(" mHomeProcess: " + mHomeProcess); 10776 } 10777 if (mPreviousProcess != null && (dumpPackage == null 10778 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 10779 if (needSep) { 10780 pw.println(); 10781 needSep = false; 10782 } 10783 pw.println(" mPreviousProcess: " + mPreviousProcess); 10784 } 10785 if (dumpAll) { 10786 StringBuilder sb = new StringBuilder(128); 10787 sb.append(" mPreviousProcessVisibleTime: "); 10788 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 10789 pw.println(sb); 10790 } 10791 if (mHeavyWeightProcess != null && (dumpPackage == null 10792 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 10793 if (needSep) { 10794 pw.println(); 10795 needSep = false; 10796 } 10797 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10798 } 10799 if (dumpPackage == null) { 10800 pw.println(" mConfiguration: " + mConfiguration); 10801 } 10802 if (dumpAll) { 10803 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 10804 if (mCompatModePackages.getPackages().size() > 0) { 10805 boolean printed = false; 10806 for (Map.Entry<String, Integer> entry 10807 : mCompatModePackages.getPackages().entrySet()) { 10808 String pkg = entry.getKey(); 10809 int mode = entry.getValue(); 10810 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 10811 continue; 10812 } 10813 if (!printed) { 10814 pw.println(" mScreenCompatPackages:"); 10815 printed = true; 10816 } 10817 pw.print(" "); pw.print(pkg); pw.print(": "); 10818 pw.print(mode); pw.println(); 10819 } 10820 } 10821 } 10822 if (dumpPackage == null) { 10823 if (mSleeping || mWentToSleep || mLockScreenShown) { 10824 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 10825 + " mLockScreenShown " + mLockScreenShown); 10826 } 10827 if (mShuttingDown) { 10828 pw.println(" mShuttingDown=" + mShuttingDown); 10829 } 10830 } 10831 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 10832 || mOrigWaitForDebugger) { 10833 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 10834 || dumpPackage.equals(mOrigDebugApp)) { 10835 if (needSep) { 10836 pw.println(); 10837 needSep = false; 10838 } 10839 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 10840 + " mDebugTransient=" + mDebugTransient 10841 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 10842 } 10843 } 10844 if (mOpenGlTraceApp != null) { 10845 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 10846 if (needSep) { 10847 pw.println(); 10848 needSep = false; 10849 } 10850 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 10851 } 10852 } 10853 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 10854 || mProfileFd != null) { 10855 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 10856 if (needSep) { 10857 pw.println(); 10858 needSep = false; 10859 } 10860 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 10861 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 10862 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 10863 + mAutoStopProfiler); 10864 } 10865 } 10866 if (dumpPackage == null) { 10867 if (mAlwaysFinishActivities || mController != null) { 10868 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 10869 + " mController=" + mController); 10870 } 10871 if (dumpAll) { 10872 pw.println(" Total persistent processes: " + numPers); 10873 pw.println(" mStartRunning=" + mStartRunning 10874 + " mProcessesReady=" + mProcessesReady 10875 + " mSystemReady=" + mSystemReady); 10876 pw.println(" mBooting=" + mBooting 10877 + " mBooted=" + mBooted 10878 + " mFactoryTest=" + mFactoryTest); 10879 pw.print(" mLastPowerCheckRealtime="); 10880 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 10881 pw.println(""); 10882 pw.print(" mLastPowerCheckUptime="); 10883 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 10884 pw.println(""); 10885 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 10886 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 10887 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 10888 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 10889 + " (" + mLruProcesses.size() + " total)" 10890 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 10891 + " mNumServiceProcs=" + mNumServiceProcs 10892 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 10893 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 10894 + " mLastMemoryLevel" + mLastMemoryLevel 10895 + " mLastNumProcesses" + mLastNumProcesses); 10896 long now = SystemClock.uptimeMillis(); 10897 pw.print(" mLastIdleTime="); 10898 TimeUtils.formatDuration(now, mLastIdleTime, pw); 10899 pw.print(" mLowRamSinceLastIdle="); 10900 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 10901 pw.println(); 10902 } 10903 } 10904 10905 if (!printedAnything) { 10906 pw.println(" (nothing)"); 10907 } 10908 } 10909 10910 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 10911 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 10912 if (mProcessesToGc.size() > 0) { 10913 boolean printed = false; 10914 long now = SystemClock.uptimeMillis(); 10915 for (int i=0; i<mProcessesToGc.size(); i++) { 10916 ProcessRecord proc = mProcessesToGc.get(i); 10917 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 10918 continue; 10919 } 10920 if (!printed) { 10921 if (needSep) pw.println(); 10922 needSep = true; 10923 pw.println(" Processes that are waiting to GC:"); 10924 printed = true; 10925 } 10926 pw.print(" Process "); pw.println(proc); 10927 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 10928 pw.print(", last gced="); 10929 pw.print(now-proc.lastRequestedGc); 10930 pw.print(" ms ago, last lowMem="); 10931 pw.print(now-proc.lastLowMemory); 10932 pw.println(" ms ago"); 10933 10934 } 10935 } 10936 return needSep; 10937 } 10938 10939 void printOomLevel(PrintWriter pw, String name, int adj) { 10940 pw.print(" "); 10941 if (adj >= 0) { 10942 pw.print(' '); 10943 if (adj < 10) pw.print(' '); 10944 } else { 10945 if (adj > -10) pw.print(' '); 10946 } 10947 pw.print(adj); 10948 pw.print(": "); 10949 pw.print(name); 10950 pw.print(" ("); 10951 pw.print(mProcessList.getMemLevel(adj)/1024); 10952 pw.println(" kB)"); 10953 } 10954 10955 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10956 int opti, boolean dumpAll) { 10957 boolean needSep = false; 10958 10959 if (mLruProcesses.size() > 0) { 10960 if (needSep) pw.println(); 10961 needSep = true; 10962 pw.println(" OOM levels:"); 10963 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 10964 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 10965 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 10966 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 10967 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 10968 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 10969 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 10970 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 10971 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 10972 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 10973 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 10974 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 10975 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 10976 10977 if (needSep) pw.println(); 10978 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 10979 pw.print(" total, non-act at "); 10980 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10981 pw.print(", non-svc at "); 10982 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10983 pw.println("):"); 10984 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 10985 needSep = true; 10986 } 10987 10988 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 10989 10990 pw.println(); 10991 pw.println(" mHomeProcess: " + mHomeProcess); 10992 pw.println(" mPreviousProcess: " + mPreviousProcess); 10993 if (mHeavyWeightProcess != null) { 10994 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10995 } 10996 10997 return true; 10998 } 10999 11000 /** 11001 * There are three ways to call this: 11002 * - no provider specified: dump all the providers 11003 * - a flattened component name that matched an existing provider was specified as the 11004 * first arg: dump that one provider 11005 * - the first arg isn't the flattened component name of an existing provider: 11006 * dump all providers whose component contains the first arg as a substring 11007 */ 11008 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11009 int opti, boolean dumpAll) { 11010 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11011 } 11012 11013 static class ItemMatcher { 11014 ArrayList<ComponentName> components; 11015 ArrayList<String> strings; 11016 ArrayList<Integer> objects; 11017 boolean all; 11018 11019 ItemMatcher() { 11020 all = true; 11021 } 11022 11023 void build(String name) { 11024 ComponentName componentName = ComponentName.unflattenFromString(name); 11025 if (componentName != null) { 11026 if (components == null) { 11027 components = new ArrayList<ComponentName>(); 11028 } 11029 components.add(componentName); 11030 all = false; 11031 } else { 11032 int objectId = 0; 11033 // Not a '/' separated full component name; maybe an object ID? 11034 try { 11035 objectId = Integer.parseInt(name, 16); 11036 if (objects == null) { 11037 objects = new ArrayList<Integer>(); 11038 } 11039 objects.add(objectId); 11040 all = false; 11041 } catch (RuntimeException e) { 11042 // Not an integer; just do string match. 11043 if (strings == null) { 11044 strings = new ArrayList<String>(); 11045 } 11046 strings.add(name); 11047 all = false; 11048 } 11049 } 11050 } 11051 11052 int build(String[] args, int opti) { 11053 for (; opti<args.length; opti++) { 11054 String name = args[opti]; 11055 if ("--".equals(name)) { 11056 return opti+1; 11057 } 11058 build(name); 11059 } 11060 return opti; 11061 } 11062 11063 boolean match(Object object, ComponentName comp) { 11064 if (all) { 11065 return true; 11066 } 11067 if (components != null) { 11068 for (int i=0; i<components.size(); i++) { 11069 if (components.get(i).equals(comp)) { 11070 return true; 11071 } 11072 } 11073 } 11074 if (objects != null) { 11075 for (int i=0; i<objects.size(); i++) { 11076 if (System.identityHashCode(object) == objects.get(i)) { 11077 return true; 11078 } 11079 } 11080 } 11081 if (strings != null) { 11082 String flat = comp.flattenToString(); 11083 for (int i=0; i<strings.size(); i++) { 11084 if (flat.contains(strings.get(i))) { 11085 return true; 11086 } 11087 } 11088 } 11089 return false; 11090 } 11091 } 11092 11093 /** 11094 * There are three things that cmd can be: 11095 * - a flattened component name that matches an existing activity 11096 * - the cmd arg isn't the flattened component name of an existing activity: 11097 * dump all activity whose component contains the cmd as a substring 11098 * - A hex number of the ActivityRecord object instance. 11099 */ 11100 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11101 int opti, boolean dumpAll) { 11102 ArrayList<ActivityRecord> activities; 11103 11104 synchronized (this) { 11105 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11106 } 11107 11108 if (activities.size() <= 0) { 11109 return false; 11110 } 11111 11112 String[] newArgs = new String[args.length - opti]; 11113 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11114 11115 TaskRecord lastTask = null; 11116 boolean needSep = false; 11117 for (int i=activities.size()-1; i>=0; i--) { 11118 ActivityRecord r = activities.get(i); 11119 if (needSep) { 11120 pw.println(); 11121 } 11122 needSep = true; 11123 synchronized (this) { 11124 if (lastTask != r.task) { 11125 lastTask = r.task; 11126 pw.print("TASK "); pw.print(lastTask.affinity); 11127 pw.print(" id="); pw.println(lastTask.taskId); 11128 if (dumpAll) { 11129 lastTask.dump(pw, " "); 11130 } 11131 } 11132 } 11133 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11134 } 11135 return true; 11136 } 11137 11138 /** 11139 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11140 * there is a thread associated with the activity. 11141 */ 11142 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11143 final ActivityRecord r, String[] args, boolean dumpAll) { 11144 String innerPrefix = prefix + " "; 11145 synchronized (this) { 11146 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11147 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11148 pw.print(" pid="); 11149 if (r.app != null) pw.println(r.app.pid); 11150 else pw.println("(not running)"); 11151 if (dumpAll) { 11152 r.dump(pw, innerPrefix); 11153 } 11154 } 11155 if (r.app != null && r.app.thread != null) { 11156 // flush anything that is already in the PrintWriter since the thread is going 11157 // to write to the file descriptor directly 11158 pw.flush(); 11159 try { 11160 TransferPipe tp = new TransferPipe(); 11161 try { 11162 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11163 r.appToken, innerPrefix, args); 11164 tp.go(fd); 11165 } finally { 11166 tp.kill(); 11167 } 11168 } catch (IOException e) { 11169 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11170 } catch (RemoteException e) { 11171 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11172 } 11173 } 11174 } 11175 11176 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11177 int opti, boolean dumpAll, String dumpPackage) { 11178 boolean needSep = false; 11179 boolean onlyHistory = false; 11180 boolean printedAnything = false; 11181 11182 if ("history".equals(dumpPackage)) { 11183 if (opti < args.length && "-s".equals(args[opti])) { 11184 dumpAll = false; 11185 } 11186 onlyHistory = true; 11187 dumpPackage = null; 11188 } 11189 11190 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11191 if (!onlyHistory && dumpAll) { 11192 if (mRegisteredReceivers.size() > 0) { 11193 boolean printed = false; 11194 Iterator it = mRegisteredReceivers.values().iterator(); 11195 while (it.hasNext()) { 11196 ReceiverList r = (ReceiverList)it.next(); 11197 if (dumpPackage != null && (r.app == null || 11198 !dumpPackage.equals(r.app.info.packageName))) { 11199 continue; 11200 } 11201 if (!printed) { 11202 pw.println(" Registered Receivers:"); 11203 needSep = true; 11204 printed = true; 11205 printedAnything = true; 11206 } 11207 pw.print(" * "); pw.println(r); 11208 r.dump(pw, " "); 11209 } 11210 } 11211 11212 if (mReceiverResolver.dump(pw, needSep ? 11213 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11214 " ", dumpPackage, false)) { 11215 needSep = true; 11216 printedAnything = true; 11217 } 11218 } 11219 11220 for (BroadcastQueue q : mBroadcastQueues) { 11221 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11222 printedAnything |= needSep; 11223 } 11224 11225 needSep = true; 11226 11227 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11228 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11229 if (needSep) { 11230 pw.println(); 11231 } 11232 needSep = true; 11233 printedAnything = true; 11234 pw.print(" Sticky broadcasts for user "); 11235 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11236 StringBuilder sb = new StringBuilder(128); 11237 for (Map.Entry<String, ArrayList<Intent>> ent 11238 : mStickyBroadcasts.valueAt(user).entrySet()) { 11239 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11240 if (dumpAll) { 11241 pw.println(":"); 11242 ArrayList<Intent> intents = ent.getValue(); 11243 final int N = intents.size(); 11244 for (int i=0; i<N; i++) { 11245 sb.setLength(0); 11246 sb.append(" Intent: "); 11247 intents.get(i).toShortString(sb, false, true, false, false); 11248 pw.println(sb.toString()); 11249 Bundle bundle = intents.get(i).getExtras(); 11250 if (bundle != null) { 11251 pw.print(" "); 11252 pw.println(bundle.toString()); 11253 } 11254 } 11255 } else { 11256 pw.println(""); 11257 } 11258 } 11259 } 11260 } 11261 11262 if (!onlyHistory && dumpAll) { 11263 pw.println(); 11264 for (BroadcastQueue queue : mBroadcastQueues) { 11265 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11266 + queue.mBroadcastsScheduled); 11267 } 11268 pw.println(" mHandler:"); 11269 mHandler.dump(new PrintWriterPrinter(pw), " "); 11270 needSep = true; 11271 printedAnything = true; 11272 } 11273 11274 if (!printedAnything) { 11275 pw.println(" (nothing)"); 11276 } 11277 } 11278 11279 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11280 int opti, boolean dumpAll, String dumpPackage) { 11281 boolean needSep; 11282 boolean printedAnything = false; 11283 11284 ItemMatcher matcher = new ItemMatcher(); 11285 matcher.build(args, opti); 11286 11287 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11288 11289 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11290 printedAnything |= needSep; 11291 11292 if (mLaunchingProviders.size() > 0) { 11293 boolean printed = false; 11294 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11295 ContentProviderRecord r = mLaunchingProviders.get(i); 11296 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11297 continue; 11298 } 11299 if (!printed) { 11300 if (needSep) pw.println(); 11301 needSep = true; 11302 pw.println(" Launching content providers:"); 11303 printed = true; 11304 printedAnything = true; 11305 } 11306 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11307 pw.println(r); 11308 } 11309 } 11310 11311 if (mGrantedUriPermissions.size() > 0) { 11312 boolean printed = false; 11313 int dumpUid = -2; 11314 if (dumpPackage != null) { 11315 try { 11316 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11317 } catch (NameNotFoundException e) { 11318 dumpUid = -1; 11319 } 11320 } 11321 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11322 int uid = mGrantedUriPermissions.keyAt(i); 11323 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11324 continue; 11325 } 11326 ArrayMap<Uri, UriPermission> perms 11327 = mGrantedUriPermissions.valueAt(i); 11328 if (!printed) { 11329 if (needSep) pw.println(); 11330 needSep = true; 11331 pw.println(" Granted Uri Permissions:"); 11332 printed = true; 11333 printedAnything = true; 11334 } 11335 pw.print(" * UID "); pw.print(uid); 11336 pw.println(" holds:"); 11337 for (UriPermission perm : perms.values()) { 11338 pw.print(" "); pw.println(perm); 11339 if (dumpAll) { 11340 perm.dump(pw, " "); 11341 } 11342 } 11343 } 11344 } 11345 11346 if (!printedAnything) { 11347 pw.println(" (nothing)"); 11348 } 11349 } 11350 11351 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11352 int opti, boolean dumpAll, String dumpPackage) { 11353 boolean printed = false; 11354 11355 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11356 11357 if (mIntentSenderRecords.size() > 0) { 11358 Iterator<WeakReference<PendingIntentRecord>> it 11359 = mIntentSenderRecords.values().iterator(); 11360 while (it.hasNext()) { 11361 WeakReference<PendingIntentRecord> ref = it.next(); 11362 PendingIntentRecord rec = ref != null ? ref.get(): null; 11363 if (dumpPackage != null && (rec == null 11364 || !dumpPackage.equals(rec.key.packageName))) { 11365 continue; 11366 } 11367 printed = true; 11368 if (rec != null) { 11369 pw.print(" * "); pw.println(rec); 11370 if (dumpAll) { 11371 rec.dump(pw, " "); 11372 } 11373 } else { 11374 pw.print(" * "); pw.println(ref); 11375 } 11376 } 11377 } 11378 11379 if (!printed) { 11380 pw.println(" (nothing)"); 11381 } 11382 } 11383 11384 private static final int dumpProcessList(PrintWriter pw, 11385 ActivityManagerService service, List list, 11386 String prefix, String normalLabel, String persistentLabel, 11387 String dumpPackage) { 11388 int numPers = 0; 11389 final int N = list.size()-1; 11390 for (int i=N; i>=0; i--) { 11391 ProcessRecord r = (ProcessRecord)list.get(i); 11392 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11393 continue; 11394 } 11395 pw.println(String.format("%s%s #%2d: %s", 11396 prefix, (r.persistent ? persistentLabel : normalLabel), 11397 i, r.toString())); 11398 if (r.persistent) { 11399 numPers++; 11400 } 11401 } 11402 return numPers; 11403 } 11404 11405 private static final boolean dumpProcessOomList(PrintWriter pw, 11406 ActivityManagerService service, List<ProcessRecord> origList, 11407 String prefix, String normalLabel, String persistentLabel, 11408 boolean inclDetails, String dumpPackage) { 11409 11410 ArrayList<Pair<ProcessRecord, Integer>> list 11411 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11412 for (int i=0; i<origList.size(); i++) { 11413 ProcessRecord r = origList.get(i); 11414 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11415 continue; 11416 } 11417 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11418 } 11419 11420 if (list.size() <= 0) { 11421 return false; 11422 } 11423 11424 Comparator<Pair<ProcessRecord, Integer>> comparator 11425 = new Comparator<Pair<ProcessRecord, Integer>>() { 11426 @Override 11427 public int compare(Pair<ProcessRecord, Integer> object1, 11428 Pair<ProcessRecord, Integer> object2) { 11429 if (object1.first.setAdj != object2.first.setAdj) { 11430 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11431 } 11432 if (object1.second.intValue() != object2.second.intValue()) { 11433 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11434 } 11435 return 0; 11436 } 11437 }; 11438 11439 Collections.sort(list, comparator); 11440 11441 final long curRealtime = SystemClock.elapsedRealtime(); 11442 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11443 final long curUptime = SystemClock.uptimeMillis(); 11444 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11445 11446 for (int i=list.size()-1; i>=0; i--) { 11447 ProcessRecord r = list.get(i).first; 11448 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11449 char schedGroup; 11450 switch (r.setSchedGroup) { 11451 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11452 schedGroup = 'B'; 11453 break; 11454 case Process.THREAD_GROUP_DEFAULT: 11455 schedGroup = 'F'; 11456 break; 11457 default: 11458 schedGroup = '?'; 11459 break; 11460 } 11461 char foreground; 11462 if (r.foregroundActivities) { 11463 foreground = 'A'; 11464 } else if (r.foregroundServices) { 11465 foreground = 'S'; 11466 } else { 11467 foreground = ' '; 11468 } 11469 String procState = ProcessList.makeProcStateString(r.curProcState); 11470 pw.print(prefix); 11471 pw.print(r.persistent ? persistentLabel : normalLabel); 11472 pw.print(" #"); 11473 int num = (origList.size()-1)-list.get(i).second; 11474 if (num < 10) pw.print(' '); 11475 pw.print(num); 11476 pw.print(": "); 11477 pw.print(oomAdj); 11478 pw.print(' '); 11479 pw.print(schedGroup); 11480 pw.print('/'); 11481 pw.print(foreground); 11482 pw.print('/'); 11483 pw.print(procState); 11484 pw.print(" trm:"); 11485 if (r.trimMemoryLevel < 10) pw.print(' '); 11486 pw.print(r.trimMemoryLevel); 11487 pw.print(' '); 11488 pw.print(r.toShortString()); 11489 pw.print(" ("); 11490 pw.print(r.adjType); 11491 pw.println(')'); 11492 if (r.adjSource != null || r.adjTarget != null) { 11493 pw.print(prefix); 11494 pw.print(" "); 11495 if (r.adjTarget instanceof ComponentName) { 11496 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11497 } else if (r.adjTarget != null) { 11498 pw.print(r.adjTarget.toString()); 11499 } else { 11500 pw.print("{null}"); 11501 } 11502 pw.print("<="); 11503 if (r.adjSource instanceof ProcessRecord) { 11504 pw.print("Proc{"); 11505 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11506 pw.println("}"); 11507 } else if (r.adjSource != null) { 11508 pw.println(r.adjSource.toString()); 11509 } else { 11510 pw.println("{null}"); 11511 } 11512 } 11513 if (inclDetails) { 11514 pw.print(prefix); 11515 pw.print(" "); 11516 pw.print("oom: max="); pw.print(r.maxAdj); 11517 pw.print(" curRaw="); pw.print(r.curRawAdj); 11518 pw.print(" setRaw="); pw.print(r.setRawAdj); 11519 pw.print(" cur="); pw.print(r.curAdj); 11520 pw.print(" set="); pw.println(r.setAdj); 11521 pw.print(prefix); 11522 pw.print(" "); 11523 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11524 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11525 pw.print(" lastPss="); pw.print(r.lastPss); 11526 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11527 pw.print(prefix); 11528 pw.print(" "); 11529 pw.print("keeping="); pw.print(r.keeping); 11530 pw.print(" cached="); pw.print(r.cached); 11531 pw.print(" empty="); pw.print(r.empty); 11532 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11533 11534 if (!r.keeping) { 11535 if (r.lastWakeTime != 0) { 11536 long wtime; 11537 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11538 synchronized (stats) { 11539 wtime = stats.getProcessWakeTime(r.info.uid, 11540 r.pid, curRealtime); 11541 } 11542 long timeUsed = wtime - r.lastWakeTime; 11543 pw.print(prefix); 11544 pw.print(" "); 11545 pw.print("keep awake over "); 11546 TimeUtils.formatDuration(realtimeSince, pw); 11547 pw.print(" used "); 11548 TimeUtils.formatDuration(timeUsed, pw); 11549 pw.print(" ("); 11550 pw.print((timeUsed*100)/realtimeSince); 11551 pw.println("%)"); 11552 } 11553 if (r.lastCpuTime != 0) { 11554 long timeUsed = r.curCpuTime - r.lastCpuTime; 11555 pw.print(prefix); 11556 pw.print(" "); 11557 pw.print("run cpu over "); 11558 TimeUtils.formatDuration(uptimeSince, pw); 11559 pw.print(" used "); 11560 TimeUtils.formatDuration(timeUsed, pw); 11561 pw.print(" ("); 11562 pw.print((timeUsed*100)/uptimeSince); 11563 pw.println("%)"); 11564 } 11565 } 11566 } 11567 } 11568 return true; 11569 } 11570 11571 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11572 ArrayList<ProcessRecord> procs; 11573 synchronized (this) { 11574 if (args != null && args.length > start 11575 && args[start].charAt(0) != '-') { 11576 procs = new ArrayList<ProcessRecord>(); 11577 int pid = -1; 11578 try { 11579 pid = Integer.parseInt(args[start]); 11580 } catch (NumberFormatException e) { 11581 } 11582 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11583 ProcessRecord proc = mLruProcesses.get(i); 11584 if (proc.pid == pid) { 11585 procs.add(proc); 11586 } else if (proc.processName.equals(args[start])) { 11587 procs.add(proc); 11588 } 11589 } 11590 if (procs.size() <= 0) { 11591 return null; 11592 } 11593 } else { 11594 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11595 } 11596 } 11597 return procs; 11598 } 11599 11600 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11601 PrintWriter pw, String[] args) { 11602 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11603 if (procs == null) { 11604 pw.println("No process found for: " + args[0]); 11605 return; 11606 } 11607 11608 long uptime = SystemClock.uptimeMillis(); 11609 long realtime = SystemClock.elapsedRealtime(); 11610 pw.println("Applications Graphics Acceleration Info:"); 11611 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11612 11613 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11614 ProcessRecord r = procs.get(i); 11615 if (r.thread != null) { 11616 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11617 pw.flush(); 11618 try { 11619 TransferPipe tp = new TransferPipe(); 11620 try { 11621 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11622 tp.go(fd); 11623 } finally { 11624 tp.kill(); 11625 } 11626 } catch (IOException e) { 11627 pw.println("Failure while dumping the app: " + r); 11628 pw.flush(); 11629 } catch (RemoteException e) { 11630 pw.println("Got a RemoteException while dumping the app " + r); 11631 pw.flush(); 11632 } 11633 } 11634 } 11635 } 11636 11637 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11638 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11639 if (procs == null) { 11640 pw.println("No process found for: " + args[0]); 11641 return; 11642 } 11643 11644 pw.println("Applications Database Info:"); 11645 11646 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11647 ProcessRecord r = procs.get(i); 11648 if (r.thread != null) { 11649 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11650 pw.flush(); 11651 try { 11652 TransferPipe tp = new TransferPipe(); 11653 try { 11654 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11655 tp.go(fd); 11656 } finally { 11657 tp.kill(); 11658 } 11659 } catch (IOException e) { 11660 pw.println("Failure while dumping the app: " + r); 11661 pw.flush(); 11662 } catch (RemoteException e) { 11663 pw.println("Got a RemoteException while dumping the app " + r); 11664 pw.flush(); 11665 } 11666 } 11667 } 11668 } 11669 11670 final static class MemItem { 11671 final boolean isProc; 11672 final String label; 11673 final String shortLabel; 11674 final long pss; 11675 final int id; 11676 final boolean hasActivities; 11677 ArrayList<MemItem> subitems; 11678 11679 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11680 boolean _hasActivities) { 11681 isProc = true; 11682 label = _label; 11683 shortLabel = _shortLabel; 11684 pss = _pss; 11685 id = _id; 11686 hasActivities = _hasActivities; 11687 } 11688 11689 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11690 isProc = false; 11691 label = _label; 11692 shortLabel = _shortLabel; 11693 pss = _pss; 11694 id = _id; 11695 hasActivities = false; 11696 } 11697 } 11698 11699 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11700 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11701 if (sort && !isCompact) { 11702 Collections.sort(items, new Comparator<MemItem>() { 11703 @Override 11704 public int compare(MemItem lhs, MemItem rhs) { 11705 if (lhs.pss < rhs.pss) { 11706 return 1; 11707 } else if (lhs.pss > rhs.pss) { 11708 return -1; 11709 } 11710 return 0; 11711 } 11712 }); 11713 } 11714 11715 for (int i=0; i<items.size(); i++) { 11716 MemItem mi = items.get(i); 11717 if (!isCompact) { 11718 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11719 } else if (mi.isProc) { 11720 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11721 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11722 pw.println(mi.hasActivities ? ",a" : ",e"); 11723 } else { 11724 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11725 pw.println(mi.pss); 11726 } 11727 if (mi.subitems != null) { 11728 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11729 true, isCompact); 11730 } 11731 } 11732 } 11733 11734 // These are in KB. 11735 static final long[] DUMP_MEM_BUCKETS = new long[] { 11736 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11737 120*1024, 160*1024, 200*1024, 11738 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11739 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11740 }; 11741 11742 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11743 boolean stackLike) { 11744 int start = label.lastIndexOf('.'); 11745 if (start >= 0) start++; 11746 else start = 0; 11747 int end = label.length(); 11748 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11749 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11750 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11751 out.append(bucket); 11752 out.append(stackLike ? "MB." : "MB "); 11753 out.append(label, start, end); 11754 return; 11755 } 11756 } 11757 out.append(memKB/1024); 11758 out.append(stackLike ? "MB." : "MB "); 11759 out.append(label, start, end); 11760 } 11761 11762 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11763 ProcessList.NATIVE_ADJ, 11764 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11765 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11766 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11767 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11768 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11769 }; 11770 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11771 "Native", 11772 "System", "Persistent", "Foreground", 11773 "Visible", "Perceptible", 11774 "Heavy Weight", "Backup", 11775 "A Services", "Home", 11776 "Previous", "B Services", "Cached" 11777 }; 11778 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 11779 "native", 11780 "sys", "pers", "fore", 11781 "vis", "percept", 11782 "heavy", "backup", 11783 "servicea", "home", 11784 "prev", "serviceb", "cached" 11785 }; 11786 11787 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 11788 long realtime, boolean isCheckinRequest, boolean isCompact) { 11789 if (isCheckinRequest || isCompact) { 11790 // short checkin version 11791 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 11792 } else { 11793 pw.println("Applications Memory Usage (kB):"); 11794 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11795 } 11796 } 11797 11798 final void dumpApplicationMemoryUsage(FileDescriptor fd, 11799 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 11800 boolean dumpDetails = false; 11801 boolean dumpFullDetails = false; 11802 boolean dumpDalvik = false; 11803 boolean oomOnly = false; 11804 boolean isCompact = false; 11805 boolean localOnly = false; 11806 11807 int opti = 0; 11808 while (opti < args.length) { 11809 String opt = args[opti]; 11810 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11811 break; 11812 } 11813 opti++; 11814 if ("-a".equals(opt)) { 11815 dumpDetails = true; 11816 dumpFullDetails = true; 11817 dumpDalvik = true; 11818 } else if ("-d".equals(opt)) { 11819 dumpDalvik = true; 11820 } else if ("-c".equals(opt)) { 11821 isCompact = true; 11822 } else if ("--oom".equals(opt)) { 11823 oomOnly = true; 11824 } else if ("--local".equals(opt)) { 11825 localOnly = true; 11826 } else if ("-h".equals(opt)) { 11827 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 11828 pw.println(" -a: include all available information for each process."); 11829 pw.println(" -d: include dalvik details when dumping process details."); 11830 pw.println(" -c: dump in a compact machine-parseable representation."); 11831 pw.println(" --oom: only show processes organized by oom adj."); 11832 pw.println(" --local: only collect details locally, don't call process."); 11833 pw.println("If [process] is specified it can be the name or "); 11834 pw.println("pid of a specific process to dump."); 11835 return; 11836 } else { 11837 pw.println("Unknown argument: " + opt + "; use -h for help"); 11838 } 11839 } 11840 11841 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 11842 long uptime = SystemClock.uptimeMillis(); 11843 long realtime = SystemClock.elapsedRealtime(); 11844 final long[] tmpLong = new long[1]; 11845 11846 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 11847 if (procs == null) { 11848 // No Java processes. Maybe they want to print a native process. 11849 if (args != null && args.length > opti 11850 && args[opti].charAt(0) != '-') { 11851 ArrayList<ProcessCpuTracker.Stats> nativeProcs 11852 = new ArrayList<ProcessCpuTracker.Stats>(); 11853 updateCpuStatsNow(); 11854 int findPid = -1; 11855 try { 11856 findPid = Integer.parseInt(args[opti]); 11857 } catch (NumberFormatException e) { 11858 } 11859 synchronized (mProcessCpuThread) { 11860 final int N = mProcessCpuTracker.countStats(); 11861 for (int i=0; i<N; i++) { 11862 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 11863 if (st.pid == findPid || (st.baseName != null 11864 && st.baseName.equals(args[opti]))) { 11865 nativeProcs.add(st); 11866 } 11867 } 11868 } 11869 if (nativeProcs.size() > 0) { 11870 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 11871 isCompact); 11872 Debug.MemoryInfo mi = null; 11873 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 11874 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 11875 final int pid = r.pid; 11876 if (!isCheckinRequest && dumpDetails) { 11877 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 11878 } 11879 if (mi == null) { 11880 mi = new Debug.MemoryInfo(); 11881 } 11882 if (dumpDetails || (!brief && !oomOnly)) { 11883 Debug.getMemoryInfo(pid, mi); 11884 } else { 11885 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11886 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11887 } 11888 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11889 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 11890 if (isCheckinRequest) { 11891 pw.println(); 11892 } 11893 } 11894 return; 11895 } 11896 } 11897 pw.println("No process found for: " + args[opti]); 11898 return; 11899 } 11900 11901 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 11902 dumpDetails = true; 11903 } 11904 11905 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 11906 11907 String[] innerArgs = new String[args.length-opti]; 11908 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 11909 11910 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 11911 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 11912 long nativePss=0, dalvikPss=0, otherPss=0; 11913 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 11914 11915 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 11916 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 11917 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 11918 11919 long totalPss = 0; 11920 long cachedPss = 0; 11921 11922 Debug.MemoryInfo mi = null; 11923 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11924 final ProcessRecord r = procs.get(i); 11925 final IApplicationThread thread; 11926 final int pid; 11927 final int oomAdj; 11928 final boolean hasActivities; 11929 synchronized (this) { 11930 thread = r.thread; 11931 pid = r.pid; 11932 oomAdj = r.getSetAdjWithServices(); 11933 hasActivities = r.activities.size() > 0; 11934 } 11935 if (thread != null) { 11936 if (!isCheckinRequest && dumpDetails) { 11937 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 11938 } 11939 if (mi == null) { 11940 mi = new Debug.MemoryInfo(); 11941 } 11942 if (dumpDetails || (!brief && !oomOnly)) { 11943 Debug.getMemoryInfo(pid, mi); 11944 } else { 11945 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11946 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11947 } 11948 if (dumpDetails) { 11949 if (localOnly) { 11950 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11951 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 11952 if (isCheckinRequest) { 11953 pw.println(); 11954 } 11955 } else { 11956 try { 11957 pw.flush(); 11958 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 11959 dumpDalvik, innerArgs); 11960 } catch (RemoteException e) { 11961 if (!isCheckinRequest) { 11962 pw.println("Got RemoteException!"); 11963 pw.flush(); 11964 } 11965 } 11966 } 11967 } 11968 11969 final long myTotalPss = mi.getTotalPss(); 11970 final long myTotalUss = mi.getTotalUss(); 11971 11972 synchronized (this) { 11973 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 11974 // Record this for posterity if the process has been stable. 11975 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 11976 } 11977 } 11978 11979 if (!isCheckinRequest && mi != null) { 11980 totalPss += myTotalPss; 11981 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 11982 (hasActivities ? " / activities)" : ")"), 11983 r.processName, myTotalPss, pid, hasActivities); 11984 procMems.add(pssItem); 11985 procMemsMap.put(pid, pssItem); 11986 11987 nativePss += mi.nativePss; 11988 dalvikPss += mi.dalvikPss; 11989 otherPss += mi.otherPss; 11990 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 11991 long mem = mi.getOtherPss(j); 11992 miscPss[j] += mem; 11993 otherPss -= mem; 11994 } 11995 11996 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 11997 cachedPss += myTotalPss; 11998 } 11999 12000 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12001 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12002 || oomIndex == (oomPss.length-1)) { 12003 oomPss[oomIndex] += myTotalPss; 12004 if (oomProcs[oomIndex] == null) { 12005 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12006 } 12007 oomProcs[oomIndex].add(pssItem); 12008 break; 12009 } 12010 } 12011 } 12012 } 12013 } 12014 12015 if (!isCheckinRequest && procs.size() > 1) { 12016 // If we are showing aggregations, also look for native processes to 12017 // include so that our aggregations are more accurate. 12018 updateCpuStatsNow(); 12019 synchronized (mProcessCpuThread) { 12020 final int N = mProcessCpuTracker.countStats(); 12021 for (int i=0; i<N; i++) { 12022 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12023 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12024 if (mi == null) { 12025 mi = new Debug.MemoryInfo(); 12026 } 12027 if (!brief && !oomOnly) { 12028 Debug.getMemoryInfo(st.pid, mi); 12029 } else { 12030 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12031 mi.nativePrivateDirty = (int)tmpLong[0]; 12032 } 12033 12034 final long myTotalPss = mi.getTotalPss(); 12035 totalPss += myTotalPss; 12036 12037 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12038 st.name, myTotalPss, st.pid, false); 12039 procMems.add(pssItem); 12040 12041 nativePss += mi.nativePss; 12042 dalvikPss += mi.dalvikPss; 12043 otherPss += mi.otherPss; 12044 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12045 long mem = mi.getOtherPss(j); 12046 miscPss[j] += mem; 12047 otherPss -= mem; 12048 } 12049 oomPss[0] += myTotalPss; 12050 if (oomProcs[0] == null) { 12051 oomProcs[0] = new ArrayList<MemItem>(); 12052 } 12053 oomProcs[0].add(pssItem); 12054 } 12055 } 12056 } 12057 12058 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12059 12060 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12061 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12062 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12063 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12064 String label = Debug.MemoryInfo.getOtherLabel(j); 12065 catMems.add(new MemItem(label, label, miscPss[j], j)); 12066 } 12067 12068 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12069 for (int j=0; j<oomPss.length; j++) { 12070 if (oomPss[j] != 0) { 12071 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12072 : DUMP_MEM_OOM_LABEL[j]; 12073 MemItem item = new MemItem(label, label, oomPss[j], 12074 DUMP_MEM_OOM_ADJ[j]); 12075 item.subitems = oomProcs[j]; 12076 oomMems.add(item); 12077 } 12078 } 12079 12080 if (!brief && !oomOnly && !isCompact) { 12081 pw.println(); 12082 pw.println("Total PSS by process:"); 12083 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12084 pw.println(); 12085 } 12086 if (!isCompact) { 12087 pw.println("Total PSS by OOM adjustment:"); 12088 } 12089 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12090 if (!brief && !oomOnly) { 12091 PrintWriter out = categoryPw != null ? categoryPw : pw; 12092 if (!isCompact) { 12093 out.println(); 12094 out.println("Total PSS by category:"); 12095 } 12096 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12097 } 12098 if (!isCompact) { 12099 pw.println(); 12100 } 12101 MemInfoReader memInfo = new MemInfoReader(); 12102 memInfo.readMemInfo(); 12103 if (!brief) { 12104 if (!isCompact) { 12105 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12106 pw.println(" kB"); 12107 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12108 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12109 pw.print(cachedPss); pw.print(" cached pss + "); 12110 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12111 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12112 } else { 12113 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12114 pw.print(cachedPss + memInfo.getCachedSizeKb() 12115 + memInfo.getFreeSizeKb()); pw.print(","); 12116 pw.println(totalPss - cachedPss); 12117 } 12118 } 12119 if (!isCompact) { 12120 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12121 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12122 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12123 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12124 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12125 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12126 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12127 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12128 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12129 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12130 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12131 } 12132 if (!brief) { 12133 if (memInfo.getZramTotalSizeKb() != 0) { 12134 if (!isCompact) { 12135 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12136 pw.print(" kB physical used for "); 12137 pw.print(memInfo.getSwapTotalSizeKb() 12138 - memInfo.getSwapFreeSizeKb()); 12139 pw.print(" kB in swap ("); 12140 pw.print(memInfo.getSwapTotalSizeKb()); 12141 pw.println(" kB total swap)"); 12142 } else { 12143 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12144 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12145 pw.println(memInfo.getSwapFreeSizeKb()); 12146 } 12147 } 12148 final int[] SINGLE_LONG_FORMAT = new int[] { 12149 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12150 }; 12151 long[] longOut = new long[1]; 12152 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12153 SINGLE_LONG_FORMAT, null, longOut, null); 12154 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12155 longOut[0] = 0; 12156 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12157 SINGLE_LONG_FORMAT, null, longOut, null); 12158 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12159 longOut[0] = 0; 12160 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12161 SINGLE_LONG_FORMAT, null, longOut, null); 12162 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12163 longOut[0] = 0; 12164 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12165 SINGLE_LONG_FORMAT, null, longOut, null); 12166 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12167 if (!isCompact) { 12168 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12169 pw.print(" KSM: "); pw.print(sharing); 12170 pw.print(" kB saved from shared "); 12171 pw.print(shared); pw.println(" kB"); 12172 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12173 pw.print(voltile); pw.println(" kB volatile"); 12174 } 12175 pw.print(" Tuning: "); 12176 pw.print(ActivityManager.staticGetMemoryClass()); 12177 pw.print(" (large "); 12178 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12179 pw.print("), oom "); 12180 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12181 pw.print(" kB"); 12182 pw.print(", restore limit "); 12183 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12184 pw.print(" kB"); 12185 if (ActivityManager.isLowRamDeviceStatic()) { 12186 pw.print(" (low-ram)"); 12187 } 12188 if (ActivityManager.isHighEndGfx()) { 12189 pw.print(" (high-end-gfx)"); 12190 } 12191 pw.println(); 12192 } else { 12193 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12194 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12195 pw.println(voltile); 12196 pw.print("tuning,"); 12197 pw.print(ActivityManager.staticGetMemoryClass()); 12198 pw.print(','); 12199 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12200 pw.print(','); 12201 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12202 if (ActivityManager.isLowRamDeviceStatic()) { 12203 pw.print(",low-ram"); 12204 } 12205 if (ActivityManager.isHighEndGfx()) { 12206 pw.print(",high-end-gfx"); 12207 } 12208 pw.println(); 12209 } 12210 } 12211 } 12212 } 12213 12214 /** 12215 * Searches array of arguments for the specified string 12216 * @param args array of argument strings 12217 * @param value value to search for 12218 * @return true if the value is contained in the array 12219 */ 12220 private static boolean scanArgs(String[] args, String value) { 12221 if (args != null) { 12222 for (String arg : args) { 12223 if (value.equals(arg)) { 12224 return true; 12225 } 12226 } 12227 } 12228 return false; 12229 } 12230 12231 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12232 ContentProviderRecord cpr, boolean always) { 12233 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12234 12235 if (!inLaunching || always) { 12236 synchronized (cpr) { 12237 cpr.launchingApp = null; 12238 cpr.notifyAll(); 12239 } 12240 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12241 String names[] = cpr.info.authority.split(";"); 12242 for (int j = 0; j < names.length; j++) { 12243 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12244 } 12245 } 12246 12247 for (int i=0; i<cpr.connections.size(); i++) { 12248 ContentProviderConnection conn = cpr.connections.get(i); 12249 if (conn.waiting) { 12250 // If this connection is waiting for the provider, then we don't 12251 // need to mess with its process unless we are always removing 12252 // or for some reason the provider is not currently launching. 12253 if (inLaunching && !always) { 12254 continue; 12255 } 12256 } 12257 ProcessRecord capp = conn.client; 12258 conn.dead = true; 12259 if (conn.stableCount > 0) { 12260 if (!capp.persistent && capp.thread != null 12261 && capp.pid != 0 12262 && capp.pid != MY_PID) { 12263 killUnneededProcessLocked(capp, "depends on provider " 12264 + cpr.name.flattenToShortString() 12265 + " in dying proc " + (proc != null ? proc.processName : "??")); 12266 } 12267 } else if (capp.thread != null && conn.provider.provider != null) { 12268 try { 12269 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12270 } catch (RemoteException e) { 12271 } 12272 // In the protocol here, we don't expect the client to correctly 12273 // clean up this connection, we'll just remove it. 12274 cpr.connections.remove(i); 12275 conn.client.conProviders.remove(conn); 12276 } 12277 } 12278 12279 if (inLaunching && always) { 12280 mLaunchingProviders.remove(cpr); 12281 } 12282 return inLaunching; 12283 } 12284 12285 /** 12286 * Main code for cleaning up a process when it has gone away. This is 12287 * called both as a result of the process dying, or directly when stopping 12288 * a process when running in single process mode. 12289 */ 12290 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12291 boolean restarting, boolean allowRestart, int index) { 12292 if (index >= 0) { 12293 removeLruProcessLocked(app); 12294 ProcessList.remove(app.pid); 12295 } 12296 12297 mProcessesToGc.remove(app); 12298 mPendingPssProcesses.remove(app); 12299 12300 // Dismiss any open dialogs. 12301 if (app.crashDialog != null && !app.forceCrashReport) { 12302 app.crashDialog.dismiss(); 12303 app.crashDialog = null; 12304 } 12305 if (app.anrDialog != null) { 12306 app.anrDialog.dismiss(); 12307 app.anrDialog = null; 12308 } 12309 if (app.waitDialog != null) { 12310 app.waitDialog.dismiss(); 12311 app.waitDialog = null; 12312 } 12313 12314 app.crashing = false; 12315 app.notResponding = false; 12316 12317 app.resetPackageList(mProcessStats); 12318 app.unlinkDeathRecipient(); 12319 app.makeInactive(mProcessStats); 12320 app.forcingToForeground = null; 12321 app.foregroundServices = false; 12322 app.foregroundActivities = false; 12323 app.hasShownUi = false; 12324 app.hasAboveClient = false; 12325 12326 mServices.killServicesLocked(app, allowRestart); 12327 12328 boolean restart = false; 12329 12330 // Remove published content providers. 12331 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12332 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12333 final boolean always = app.bad || !allowRestart; 12334 if (removeDyingProviderLocked(app, cpr, always) || always) { 12335 // We left the provider in the launching list, need to 12336 // restart it. 12337 restart = true; 12338 } 12339 12340 cpr.provider = null; 12341 cpr.proc = null; 12342 } 12343 app.pubProviders.clear(); 12344 12345 // Take care of any launching providers waiting for this process. 12346 if (checkAppInLaunchingProvidersLocked(app, false)) { 12347 restart = true; 12348 } 12349 12350 // Unregister from connected content providers. 12351 if (!app.conProviders.isEmpty()) { 12352 for (int i=0; i<app.conProviders.size(); i++) { 12353 ContentProviderConnection conn = app.conProviders.get(i); 12354 conn.provider.connections.remove(conn); 12355 } 12356 app.conProviders.clear(); 12357 } 12358 12359 // At this point there may be remaining entries in mLaunchingProviders 12360 // where we were the only one waiting, so they are no longer of use. 12361 // Look for these and clean up if found. 12362 // XXX Commented out for now. Trying to figure out a way to reproduce 12363 // the actual situation to identify what is actually going on. 12364 if (false) { 12365 for (int i=0; i<mLaunchingProviders.size(); i++) { 12366 ContentProviderRecord cpr = (ContentProviderRecord) 12367 mLaunchingProviders.get(i); 12368 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12369 synchronized (cpr) { 12370 cpr.launchingApp = null; 12371 cpr.notifyAll(); 12372 } 12373 } 12374 } 12375 } 12376 12377 skipCurrentReceiverLocked(app); 12378 12379 // Unregister any receivers. 12380 for (int i=app.receivers.size()-1; i>=0; i--) { 12381 removeReceiverLocked(app.receivers.valueAt(i)); 12382 } 12383 app.receivers.clear(); 12384 12385 // If the app is undergoing backup, tell the backup manager about it 12386 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12387 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12388 + mBackupTarget.appInfo + " died during backup"); 12389 try { 12390 IBackupManager bm = IBackupManager.Stub.asInterface( 12391 ServiceManager.getService(Context.BACKUP_SERVICE)); 12392 bm.agentDisconnected(app.info.packageName); 12393 } catch (RemoteException e) { 12394 // can't happen; backup manager is local 12395 } 12396 } 12397 12398 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12399 ProcessChangeItem item = mPendingProcessChanges.get(i); 12400 if (item.pid == app.pid) { 12401 mPendingProcessChanges.remove(i); 12402 mAvailProcessChanges.add(item); 12403 } 12404 } 12405 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12406 12407 // If the caller is restarting this app, then leave it in its 12408 // current lists and let the caller take care of it. 12409 if (restarting) { 12410 return; 12411 } 12412 12413 if (!app.persistent || app.isolated) { 12414 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12415 "Removing non-persistent process during cleanup: " + app); 12416 mProcessNames.remove(app.processName, app.uid); 12417 mIsolatedProcesses.remove(app.uid); 12418 if (mHeavyWeightProcess == app) { 12419 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12420 mHeavyWeightProcess.userId, 0)); 12421 mHeavyWeightProcess = null; 12422 } 12423 } else if (!app.removed) { 12424 // This app is persistent, so we need to keep its record around. 12425 // If it is not already on the pending app list, add it there 12426 // and start a new process for it. 12427 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12428 mPersistentStartingProcesses.add(app); 12429 restart = true; 12430 } 12431 } 12432 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12433 "Clean-up removing on hold: " + app); 12434 mProcessesOnHold.remove(app); 12435 12436 if (app == mHomeProcess) { 12437 mHomeProcess = null; 12438 } 12439 if (app == mPreviousProcess) { 12440 mPreviousProcess = null; 12441 } 12442 12443 if (restart && !app.isolated) { 12444 // We have components that still need to be running in the 12445 // process, so re-launch it. 12446 mProcessNames.put(app.processName, app.uid, app); 12447 startProcessLocked(app, "restart", app.processName); 12448 } else if (app.pid > 0 && app.pid != MY_PID) { 12449 // Goodbye! 12450 synchronized (mPidsSelfLocked) { 12451 mPidsSelfLocked.remove(app.pid); 12452 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12453 } 12454 app.setPid(0); 12455 } 12456 } 12457 12458 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12459 // Look through the content providers we are waiting to have launched, 12460 // and if any run in this process then either schedule a restart of 12461 // the process or kill the client waiting for it if this process has 12462 // gone bad. 12463 int NL = mLaunchingProviders.size(); 12464 boolean restart = false; 12465 for (int i=0; i<NL; i++) { 12466 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12467 if (cpr.launchingApp == app) { 12468 if (!alwaysBad && !app.bad) { 12469 restart = true; 12470 } else { 12471 removeDyingProviderLocked(app, cpr, true); 12472 // cpr should have been removed from mLaunchingProviders 12473 NL = mLaunchingProviders.size(); 12474 i--; 12475 } 12476 } 12477 } 12478 return restart; 12479 } 12480 12481 // ========================================================= 12482 // SERVICES 12483 // ========================================================= 12484 12485 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12486 int flags) { 12487 enforceNotIsolatedCaller("getServices"); 12488 synchronized (this) { 12489 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12490 } 12491 } 12492 12493 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12494 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12495 synchronized (this) { 12496 return mServices.getRunningServiceControlPanelLocked(name); 12497 } 12498 } 12499 12500 public ComponentName startService(IApplicationThread caller, Intent service, 12501 String resolvedType, int userId) { 12502 enforceNotIsolatedCaller("startService"); 12503 // Refuse possible leaked file descriptors 12504 if (service != null && service.hasFileDescriptors() == true) { 12505 throw new IllegalArgumentException("File descriptors passed in Intent"); 12506 } 12507 12508 if (DEBUG_SERVICE) 12509 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12510 synchronized(this) { 12511 final int callingPid = Binder.getCallingPid(); 12512 final int callingUid = Binder.getCallingUid(); 12513 final long origId = Binder.clearCallingIdentity(); 12514 ComponentName res = mServices.startServiceLocked(caller, service, 12515 resolvedType, callingPid, callingUid, userId); 12516 Binder.restoreCallingIdentity(origId); 12517 return res; 12518 } 12519 } 12520 12521 ComponentName startServiceInPackage(int uid, 12522 Intent service, String resolvedType, int userId) { 12523 synchronized(this) { 12524 if (DEBUG_SERVICE) 12525 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12526 final long origId = Binder.clearCallingIdentity(); 12527 ComponentName res = mServices.startServiceLocked(null, service, 12528 resolvedType, -1, uid, userId); 12529 Binder.restoreCallingIdentity(origId); 12530 return res; 12531 } 12532 } 12533 12534 public int stopService(IApplicationThread caller, Intent service, 12535 String resolvedType, int userId) { 12536 enforceNotIsolatedCaller("stopService"); 12537 // Refuse possible leaked file descriptors 12538 if (service != null && service.hasFileDescriptors() == true) { 12539 throw new IllegalArgumentException("File descriptors passed in Intent"); 12540 } 12541 12542 synchronized(this) { 12543 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12544 } 12545 } 12546 12547 public IBinder peekService(Intent service, String resolvedType) { 12548 enforceNotIsolatedCaller("peekService"); 12549 // Refuse possible leaked file descriptors 12550 if (service != null && service.hasFileDescriptors() == true) { 12551 throw new IllegalArgumentException("File descriptors passed in Intent"); 12552 } 12553 synchronized(this) { 12554 return mServices.peekServiceLocked(service, resolvedType); 12555 } 12556 } 12557 12558 public boolean stopServiceToken(ComponentName className, IBinder token, 12559 int startId) { 12560 synchronized(this) { 12561 return mServices.stopServiceTokenLocked(className, token, startId); 12562 } 12563 } 12564 12565 public void setServiceForeground(ComponentName className, IBinder token, 12566 int id, Notification notification, boolean removeNotification) { 12567 synchronized(this) { 12568 mServices.setServiceForegroundLocked(className, token, id, notification, 12569 removeNotification); 12570 } 12571 } 12572 12573 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12574 boolean requireFull, String name, String callerPackage) { 12575 final int callingUserId = UserHandle.getUserId(callingUid); 12576 if (callingUserId != userId) { 12577 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12578 if ((requireFull || checkComponentPermission( 12579 android.Manifest.permission.INTERACT_ACROSS_USERS, 12580 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12581 && checkComponentPermission( 12582 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12583 callingPid, callingUid, -1, true) 12584 != PackageManager.PERMISSION_GRANTED) { 12585 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12586 // In this case, they would like to just execute as their 12587 // owner user instead of failing. 12588 userId = callingUserId; 12589 } else { 12590 StringBuilder builder = new StringBuilder(128); 12591 builder.append("Permission Denial: "); 12592 builder.append(name); 12593 if (callerPackage != null) { 12594 builder.append(" from "); 12595 builder.append(callerPackage); 12596 } 12597 builder.append(" asks to run as user "); 12598 builder.append(userId); 12599 builder.append(" but is calling from user "); 12600 builder.append(UserHandle.getUserId(callingUid)); 12601 builder.append("; this requires "); 12602 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12603 if (!requireFull) { 12604 builder.append(" or "); 12605 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12606 } 12607 String msg = builder.toString(); 12608 Slog.w(TAG, msg); 12609 throw new SecurityException(msg); 12610 } 12611 } 12612 } 12613 if (userId == UserHandle.USER_CURRENT 12614 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12615 // Note that we may be accessing this outside of a lock... 12616 // shouldn't be a big deal, if this is being called outside 12617 // of a locked context there is intrinsically a race with 12618 // the value the caller will receive and someone else changing it. 12619 userId = mCurrentUserId; 12620 } 12621 if (!allowAll && userId < 0) { 12622 throw new IllegalArgumentException( 12623 "Call does not support special user #" + userId); 12624 } 12625 } 12626 return userId; 12627 } 12628 12629 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12630 String className, int flags) { 12631 boolean result = false; 12632 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12633 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12634 if (ActivityManager.checkUidPermission( 12635 android.Manifest.permission.INTERACT_ACROSS_USERS, 12636 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12637 ComponentName comp = new ComponentName(aInfo.packageName, className); 12638 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12639 + " requests FLAG_SINGLE_USER, but app does not hold " 12640 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12641 Slog.w(TAG, msg); 12642 throw new SecurityException(msg); 12643 } 12644 result = true; 12645 } 12646 } else if (componentProcessName == aInfo.packageName) { 12647 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12648 } else if ("system".equals(componentProcessName)) { 12649 result = true; 12650 } 12651 if (DEBUG_MU) { 12652 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12653 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12654 } 12655 return result; 12656 } 12657 12658 public int bindService(IApplicationThread caller, IBinder token, 12659 Intent service, String resolvedType, 12660 IServiceConnection connection, int flags, int userId) { 12661 enforceNotIsolatedCaller("bindService"); 12662 // Refuse possible leaked file descriptors 12663 if (service != null && service.hasFileDescriptors() == true) { 12664 throw new IllegalArgumentException("File descriptors passed in Intent"); 12665 } 12666 12667 synchronized(this) { 12668 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12669 connection, flags, userId); 12670 } 12671 } 12672 12673 public boolean unbindService(IServiceConnection connection) { 12674 synchronized (this) { 12675 return mServices.unbindServiceLocked(connection); 12676 } 12677 } 12678 12679 public void publishService(IBinder token, Intent intent, IBinder service) { 12680 // Refuse possible leaked file descriptors 12681 if (intent != null && intent.hasFileDescriptors() == true) { 12682 throw new IllegalArgumentException("File descriptors passed in Intent"); 12683 } 12684 12685 synchronized(this) { 12686 if (!(token instanceof ServiceRecord)) { 12687 throw new IllegalArgumentException("Invalid service token"); 12688 } 12689 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12690 } 12691 } 12692 12693 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12694 // Refuse possible leaked file descriptors 12695 if (intent != null && intent.hasFileDescriptors() == true) { 12696 throw new IllegalArgumentException("File descriptors passed in Intent"); 12697 } 12698 12699 synchronized(this) { 12700 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12701 } 12702 } 12703 12704 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12705 synchronized(this) { 12706 if (!(token instanceof ServiceRecord)) { 12707 throw new IllegalArgumentException("Invalid service token"); 12708 } 12709 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12710 } 12711 } 12712 12713 // ========================================================= 12714 // BACKUP AND RESTORE 12715 // ========================================================= 12716 12717 // Cause the target app to be launched if necessary and its backup agent 12718 // instantiated. The backup agent will invoke backupAgentCreated() on the 12719 // activity manager to announce its creation. 12720 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12721 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12722 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12723 12724 synchronized(this) { 12725 // !!! TODO: currently no check here that we're already bound 12726 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12727 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12728 synchronized (stats) { 12729 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12730 } 12731 12732 // Backup agent is now in use, its package can't be stopped. 12733 try { 12734 AppGlobals.getPackageManager().setPackageStoppedState( 12735 app.packageName, false, UserHandle.getUserId(app.uid)); 12736 } catch (RemoteException e) { 12737 } catch (IllegalArgumentException e) { 12738 Slog.w(TAG, "Failed trying to unstop package " 12739 + app.packageName + ": " + e); 12740 } 12741 12742 BackupRecord r = new BackupRecord(ss, app, backupMode); 12743 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12744 ? new ComponentName(app.packageName, app.backupAgentName) 12745 : new ComponentName("android", "FullBackupAgent"); 12746 // startProcessLocked() returns existing proc's record if it's already running 12747 ProcessRecord proc = startProcessLocked(app.processName, app, 12748 false, 0, "backup", hostingName, false, false, false); 12749 if (proc == null) { 12750 Slog.e(TAG, "Unable to start backup agent process " + r); 12751 return false; 12752 } 12753 12754 r.app = proc; 12755 mBackupTarget = r; 12756 mBackupAppName = app.packageName; 12757 12758 // Try not to kill the process during backup 12759 updateOomAdjLocked(proc); 12760 12761 // If the process is already attached, schedule the creation of the backup agent now. 12762 // If it is not yet live, this will be done when it attaches to the framework. 12763 if (proc.thread != null) { 12764 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12765 try { 12766 proc.thread.scheduleCreateBackupAgent(app, 12767 compatibilityInfoForPackageLocked(app), backupMode); 12768 } catch (RemoteException e) { 12769 // Will time out on the backup manager side 12770 } 12771 } else { 12772 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12773 } 12774 // Invariants: at this point, the target app process exists and the application 12775 // is either already running or in the process of coming up. mBackupTarget and 12776 // mBackupAppName describe the app, so that when it binds back to the AM we 12777 // know that it's scheduled for a backup-agent operation. 12778 } 12779 12780 return true; 12781 } 12782 12783 @Override 12784 public void clearPendingBackup() { 12785 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 12786 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 12787 12788 synchronized (this) { 12789 mBackupTarget = null; 12790 mBackupAppName = null; 12791 } 12792 } 12793 12794 // A backup agent has just come up 12795 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12796 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12797 + " = " + agent); 12798 12799 synchronized(this) { 12800 if (!agentPackageName.equals(mBackupAppName)) { 12801 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12802 return; 12803 } 12804 } 12805 12806 long oldIdent = Binder.clearCallingIdentity(); 12807 try { 12808 IBackupManager bm = IBackupManager.Stub.asInterface( 12809 ServiceManager.getService(Context.BACKUP_SERVICE)); 12810 bm.agentConnected(agentPackageName, agent); 12811 } catch (RemoteException e) { 12812 // can't happen; the backup manager service is local 12813 } catch (Exception e) { 12814 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12815 e.printStackTrace(); 12816 } finally { 12817 Binder.restoreCallingIdentity(oldIdent); 12818 } 12819 } 12820 12821 // done with this agent 12822 public void unbindBackupAgent(ApplicationInfo appInfo) { 12823 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12824 if (appInfo == null) { 12825 Slog.w(TAG, "unbind backup agent for null app"); 12826 return; 12827 } 12828 12829 synchronized(this) { 12830 try { 12831 if (mBackupAppName == null) { 12832 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12833 return; 12834 } 12835 12836 if (!mBackupAppName.equals(appInfo.packageName)) { 12837 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12838 return; 12839 } 12840 12841 // Not backing this app up any more; reset its OOM adjustment 12842 final ProcessRecord proc = mBackupTarget.app; 12843 updateOomAdjLocked(proc); 12844 12845 // If the app crashed during backup, 'thread' will be null here 12846 if (proc.thread != null) { 12847 try { 12848 proc.thread.scheduleDestroyBackupAgent(appInfo, 12849 compatibilityInfoForPackageLocked(appInfo)); 12850 } catch (Exception e) { 12851 Slog.e(TAG, "Exception when unbinding backup agent:"); 12852 e.printStackTrace(); 12853 } 12854 } 12855 } finally { 12856 mBackupTarget = null; 12857 mBackupAppName = null; 12858 } 12859 } 12860 } 12861 // ========================================================= 12862 // BROADCASTS 12863 // ========================================================= 12864 12865 private final List getStickiesLocked(String action, IntentFilter filter, 12866 List cur, int userId) { 12867 final ContentResolver resolver = mContext.getContentResolver(); 12868 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12869 if (stickies == null) { 12870 return cur; 12871 } 12872 final ArrayList<Intent> list = stickies.get(action); 12873 if (list == null) { 12874 return cur; 12875 } 12876 int N = list.size(); 12877 for (int i=0; i<N; i++) { 12878 Intent intent = list.get(i); 12879 if (filter.match(resolver, intent, true, TAG) >= 0) { 12880 if (cur == null) { 12881 cur = new ArrayList<Intent>(); 12882 } 12883 cur.add(intent); 12884 } 12885 } 12886 return cur; 12887 } 12888 12889 boolean isPendingBroadcastProcessLocked(int pid) { 12890 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12891 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12892 } 12893 12894 void skipPendingBroadcastLocked(int pid) { 12895 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 12896 for (BroadcastQueue queue : mBroadcastQueues) { 12897 queue.skipPendingBroadcastLocked(pid); 12898 } 12899 } 12900 12901 // The app just attached; send any pending broadcasts that it should receive 12902 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 12903 boolean didSomething = false; 12904 for (BroadcastQueue queue : mBroadcastQueues) { 12905 didSomething |= queue.sendPendingBroadcastsLocked(app); 12906 } 12907 return didSomething; 12908 } 12909 12910 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 12911 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 12912 enforceNotIsolatedCaller("registerReceiver"); 12913 int callingUid; 12914 int callingPid; 12915 synchronized(this) { 12916 ProcessRecord callerApp = null; 12917 if (caller != null) { 12918 callerApp = getRecordForAppLocked(caller); 12919 if (callerApp == null) { 12920 throw new SecurityException( 12921 "Unable to find app for caller " + caller 12922 + " (pid=" + Binder.getCallingPid() 12923 + ") when registering receiver " + receiver); 12924 } 12925 if (callerApp.info.uid != Process.SYSTEM_UID && 12926 !callerApp.pkgList.containsKey(callerPackage) && 12927 !"android".equals(callerPackage)) { 12928 throw new SecurityException("Given caller package " + callerPackage 12929 + " is not running in process " + callerApp); 12930 } 12931 callingUid = callerApp.info.uid; 12932 callingPid = callerApp.pid; 12933 } else { 12934 callerPackage = null; 12935 callingUid = Binder.getCallingUid(); 12936 callingPid = Binder.getCallingPid(); 12937 } 12938 12939 userId = this.handleIncomingUser(callingPid, callingUid, userId, 12940 true, true, "registerReceiver", callerPackage); 12941 12942 List allSticky = null; 12943 12944 // Look for any matching sticky broadcasts... 12945 Iterator actions = filter.actionsIterator(); 12946 if (actions != null) { 12947 while (actions.hasNext()) { 12948 String action = (String)actions.next(); 12949 allSticky = getStickiesLocked(action, filter, allSticky, 12950 UserHandle.USER_ALL); 12951 allSticky = getStickiesLocked(action, filter, allSticky, 12952 UserHandle.getUserId(callingUid)); 12953 } 12954 } else { 12955 allSticky = getStickiesLocked(null, filter, allSticky, 12956 UserHandle.USER_ALL); 12957 allSticky = getStickiesLocked(null, filter, allSticky, 12958 UserHandle.getUserId(callingUid)); 12959 } 12960 12961 // The first sticky in the list is returned directly back to 12962 // the client. 12963 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 12964 12965 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 12966 + ": " + sticky); 12967 12968 if (receiver == null) { 12969 return sticky; 12970 } 12971 12972 ReceiverList rl 12973 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12974 if (rl == null) { 12975 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 12976 userId, receiver); 12977 if (rl.app != null) { 12978 rl.app.receivers.add(rl); 12979 } else { 12980 try { 12981 receiver.asBinder().linkToDeath(rl, 0); 12982 } catch (RemoteException e) { 12983 return sticky; 12984 } 12985 rl.linkedToDeath = true; 12986 } 12987 mRegisteredReceivers.put(receiver.asBinder(), rl); 12988 } else if (rl.uid != callingUid) { 12989 throw new IllegalArgumentException( 12990 "Receiver requested to register for uid " + callingUid 12991 + " was previously registered for uid " + rl.uid); 12992 } else if (rl.pid != callingPid) { 12993 throw new IllegalArgumentException( 12994 "Receiver requested to register for pid " + callingPid 12995 + " was previously registered for pid " + rl.pid); 12996 } else if (rl.userId != userId) { 12997 throw new IllegalArgumentException( 12998 "Receiver requested to register for user " + userId 12999 + " was previously registered for user " + rl.userId); 13000 } 13001 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13002 permission, callingUid, userId); 13003 rl.add(bf); 13004 if (!bf.debugCheck()) { 13005 Slog.w(TAG, "==> For Dynamic broadast"); 13006 } 13007 mReceiverResolver.addFilter(bf); 13008 13009 // Enqueue broadcasts for all existing stickies that match 13010 // this filter. 13011 if (allSticky != null) { 13012 ArrayList receivers = new ArrayList(); 13013 receivers.add(bf); 13014 13015 int N = allSticky.size(); 13016 for (int i=0; i<N; i++) { 13017 Intent intent = (Intent)allSticky.get(i); 13018 BroadcastQueue queue = broadcastQueueForIntent(intent); 13019 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13020 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13021 null, null, false, true, true, -1); 13022 queue.enqueueParallelBroadcastLocked(r); 13023 queue.scheduleBroadcastsLocked(); 13024 } 13025 } 13026 13027 return sticky; 13028 } 13029 } 13030 13031 public void unregisterReceiver(IIntentReceiver receiver) { 13032 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13033 13034 final long origId = Binder.clearCallingIdentity(); 13035 try { 13036 boolean doTrim = false; 13037 13038 synchronized(this) { 13039 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13040 if (rl != null) { 13041 if (rl.curBroadcast != null) { 13042 BroadcastRecord r = rl.curBroadcast; 13043 final boolean doNext = finishReceiverLocked( 13044 receiver.asBinder(), r.resultCode, r.resultData, 13045 r.resultExtras, r.resultAbort); 13046 if (doNext) { 13047 doTrim = true; 13048 r.queue.processNextBroadcast(false); 13049 } 13050 } 13051 13052 if (rl.app != null) { 13053 rl.app.receivers.remove(rl); 13054 } 13055 removeReceiverLocked(rl); 13056 if (rl.linkedToDeath) { 13057 rl.linkedToDeath = false; 13058 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13059 } 13060 } 13061 } 13062 13063 // If we actually concluded any broadcasts, we might now be able 13064 // to trim the recipients' apps from our working set 13065 if (doTrim) { 13066 trimApplications(); 13067 return; 13068 } 13069 13070 } finally { 13071 Binder.restoreCallingIdentity(origId); 13072 } 13073 } 13074 13075 void removeReceiverLocked(ReceiverList rl) { 13076 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13077 int N = rl.size(); 13078 for (int i=0; i<N; i++) { 13079 mReceiverResolver.removeFilter(rl.get(i)); 13080 } 13081 } 13082 13083 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13084 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13085 ProcessRecord r = mLruProcesses.get(i); 13086 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13087 try { 13088 r.thread.dispatchPackageBroadcast(cmd, packages); 13089 } catch (RemoteException ex) { 13090 } 13091 } 13092 } 13093 } 13094 13095 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13096 int[] users) { 13097 List<ResolveInfo> receivers = null; 13098 try { 13099 HashSet<ComponentName> singleUserReceivers = null; 13100 boolean scannedFirstReceivers = false; 13101 for (int user : users) { 13102 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13103 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13104 if (user != 0 && newReceivers != null) { 13105 // If this is not the primary user, we need to check for 13106 // any receivers that should be filtered out. 13107 for (int i=0; i<newReceivers.size(); i++) { 13108 ResolveInfo ri = newReceivers.get(i); 13109 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13110 newReceivers.remove(i); 13111 i--; 13112 } 13113 } 13114 } 13115 if (newReceivers != null && newReceivers.size() == 0) { 13116 newReceivers = null; 13117 } 13118 if (receivers == null) { 13119 receivers = newReceivers; 13120 } else if (newReceivers != null) { 13121 // We need to concatenate the additional receivers 13122 // found with what we have do far. This would be easy, 13123 // but we also need to de-dup any receivers that are 13124 // singleUser. 13125 if (!scannedFirstReceivers) { 13126 // Collect any single user receivers we had already retrieved. 13127 scannedFirstReceivers = true; 13128 for (int i=0; i<receivers.size(); i++) { 13129 ResolveInfo ri = receivers.get(i); 13130 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13131 ComponentName cn = new ComponentName( 13132 ri.activityInfo.packageName, ri.activityInfo.name); 13133 if (singleUserReceivers == null) { 13134 singleUserReceivers = new HashSet<ComponentName>(); 13135 } 13136 singleUserReceivers.add(cn); 13137 } 13138 } 13139 } 13140 // Add the new results to the existing results, tracking 13141 // and de-dupping single user receivers. 13142 for (int i=0; i<newReceivers.size(); i++) { 13143 ResolveInfo ri = newReceivers.get(i); 13144 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13145 ComponentName cn = new ComponentName( 13146 ri.activityInfo.packageName, ri.activityInfo.name); 13147 if (singleUserReceivers == null) { 13148 singleUserReceivers = new HashSet<ComponentName>(); 13149 } 13150 if (!singleUserReceivers.contains(cn)) { 13151 singleUserReceivers.add(cn); 13152 receivers.add(ri); 13153 } 13154 } else { 13155 receivers.add(ri); 13156 } 13157 } 13158 } 13159 } 13160 } catch (RemoteException ex) { 13161 // pm is in same process, this will never happen. 13162 } 13163 return receivers; 13164 } 13165 13166 private final int broadcastIntentLocked(ProcessRecord callerApp, 13167 String callerPackage, Intent intent, String resolvedType, 13168 IIntentReceiver resultTo, int resultCode, String resultData, 13169 Bundle map, String requiredPermission, int appOp, 13170 boolean ordered, boolean sticky, int callingPid, int callingUid, 13171 int userId) { 13172 intent = new Intent(intent); 13173 13174 // By default broadcasts do not go to stopped apps. 13175 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13176 13177 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13178 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13179 + " ordered=" + ordered + " userid=" + userId); 13180 if ((resultTo != null) && !ordered) { 13181 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13182 } 13183 13184 userId = handleIncomingUser(callingPid, callingUid, userId, 13185 true, false, "broadcast", callerPackage); 13186 13187 // Make sure that the user who is receiving this broadcast is started. 13188 // If not, we will just skip it. 13189 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13190 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13191 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13192 Slog.w(TAG, "Skipping broadcast of " + intent 13193 + ": user " + userId + " is stopped"); 13194 return ActivityManager.BROADCAST_SUCCESS; 13195 } 13196 } 13197 13198 /* 13199 * Prevent non-system code (defined here to be non-persistent 13200 * processes) from sending protected broadcasts. 13201 */ 13202 int callingAppId = UserHandle.getAppId(callingUid); 13203 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13204 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13205 callingUid == 0) { 13206 // Always okay. 13207 } else if (callerApp == null || !callerApp.persistent) { 13208 try { 13209 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13210 intent.getAction())) { 13211 String msg = "Permission Denial: not allowed to send broadcast " 13212 + intent.getAction() + " from pid=" 13213 + callingPid + ", uid=" + callingUid; 13214 Slog.w(TAG, msg); 13215 throw new SecurityException(msg); 13216 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13217 // Special case for compatibility: we don't want apps to send this, 13218 // but historically it has not been protected and apps may be using it 13219 // to poke their own app widget. So, instead of making it protected, 13220 // just limit it to the caller. 13221 if (callerApp == null) { 13222 String msg = "Permission Denial: not allowed to send broadcast " 13223 + intent.getAction() + " from unknown caller."; 13224 Slog.w(TAG, msg); 13225 throw new SecurityException(msg); 13226 } else if (intent.getComponent() != null) { 13227 // They are good enough to send to an explicit component... verify 13228 // it is being sent to the calling app. 13229 if (!intent.getComponent().getPackageName().equals( 13230 callerApp.info.packageName)) { 13231 String msg = "Permission Denial: not allowed to send broadcast " 13232 + intent.getAction() + " to " 13233 + intent.getComponent().getPackageName() + " from " 13234 + callerApp.info.packageName; 13235 Slog.w(TAG, msg); 13236 throw new SecurityException(msg); 13237 } 13238 } else { 13239 // Limit broadcast to their own package. 13240 intent.setPackage(callerApp.info.packageName); 13241 } 13242 } 13243 } catch (RemoteException e) { 13244 Slog.w(TAG, "Remote exception", e); 13245 return ActivityManager.BROADCAST_SUCCESS; 13246 } 13247 } 13248 13249 // Handle special intents: if this broadcast is from the package 13250 // manager about a package being removed, we need to remove all of 13251 // its activities from the history stack. 13252 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13253 intent.getAction()); 13254 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13255 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13256 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13257 || uidRemoved) { 13258 if (checkComponentPermission( 13259 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13260 callingPid, callingUid, -1, true) 13261 == PackageManager.PERMISSION_GRANTED) { 13262 if (uidRemoved) { 13263 final Bundle intentExtras = intent.getExtras(); 13264 final int uid = intentExtras != null 13265 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13266 if (uid >= 0) { 13267 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13268 synchronized (bs) { 13269 bs.removeUidStatsLocked(uid); 13270 } 13271 mAppOpsService.uidRemoved(uid); 13272 } 13273 } else { 13274 // If resources are unavailable just force stop all 13275 // those packages and flush the attribute cache as well. 13276 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13277 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13278 if (list != null && (list.length > 0)) { 13279 for (String pkg : list) { 13280 forceStopPackageLocked(pkg, -1, false, true, true, false, userId, 13281 "storage unmount"); 13282 } 13283 sendPackageBroadcastLocked( 13284 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13285 } 13286 } else { 13287 Uri data = intent.getData(); 13288 String ssp; 13289 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13290 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13291 intent.getAction()); 13292 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13293 forceStopPackageLocked(ssp, UserHandle.getAppId( 13294 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13295 false, userId, removed ? "pkg removed" : "pkg changed"); 13296 } 13297 if (removed) { 13298 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13299 new String[] {ssp}, userId); 13300 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13301 mAppOpsService.packageRemoved( 13302 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13303 13304 // Remove all permissions granted from/to this package 13305 removeUriPermissionsForPackageLocked(ssp, userId, true); 13306 } 13307 } 13308 } 13309 } 13310 } 13311 } else { 13312 String msg = "Permission Denial: " + intent.getAction() 13313 + " broadcast from " + callerPackage + " (pid=" + callingPid 13314 + ", uid=" + callingUid + ")" 13315 + " requires " 13316 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13317 Slog.w(TAG, msg); 13318 throw new SecurityException(msg); 13319 } 13320 13321 // Special case for adding a package: by default turn on compatibility 13322 // mode. 13323 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13324 Uri data = intent.getData(); 13325 String ssp; 13326 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13327 mCompatModePackages.handlePackageAddedLocked(ssp, 13328 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13329 } 13330 } 13331 13332 /* 13333 * If this is the time zone changed action, queue up a message that will reset the timezone 13334 * of all currently running processes. This message will get queued up before the broadcast 13335 * happens. 13336 */ 13337 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13338 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13339 } 13340 13341 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13342 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13343 } 13344 13345 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13346 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13347 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13348 } 13349 13350 // Add to the sticky list if requested. 13351 if (sticky) { 13352 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13353 callingPid, callingUid) 13354 != PackageManager.PERMISSION_GRANTED) { 13355 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13356 + callingPid + ", uid=" + callingUid 13357 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13358 Slog.w(TAG, msg); 13359 throw new SecurityException(msg); 13360 } 13361 if (requiredPermission != null) { 13362 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13363 + " and enforce permission " + requiredPermission); 13364 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13365 } 13366 if (intent.getComponent() != null) { 13367 throw new SecurityException( 13368 "Sticky broadcasts can't target a specific component"); 13369 } 13370 // We use userId directly here, since the "all" target is maintained 13371 // as a separate set of sticky broadcasts. 13372 if (userId != UserHandle.USER_ALL) { 13373 // But first, if this is not a broadcast to all users, then 13374 // make sure it doesn't conflict with an existing broadcast to 13375 // all users. 13376 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13377 UserHandle.USER_ALL); 13378 if (stickies != null) { 13379 ArrayList<Intent> list = stickies.get(intent.getAction()); 13380 if (list != null) { 13381 int N = list.size(); 13382 int i; 13383 for (i=0; i<N; i++) { 13384 if (intent.filterEquals(list.get(i))) { 13385 throw new IllegalArgumentException( 13386 "Sticky broadcast " + intent + " for user " 13387 + userId + " conflicts with existing global broadcast"); 13388 } 13389 } 13390 } 13391 } 13392 } 13393 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13394 if (stickies == null) { 13395 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13396 mStickyBroadcasts.put(userId, stickies); 13397 } 13398 ArrayList<Intent> list = stickies.get(intent.getAction()); 13399 if (list == null) { 13400 list = new ArrayList<Intent>(); 13401 stickies.put(intent.getAction(), list); 13402 } 13403 int N = list.size(); 13404 int i; 13405 for (i=0; i<N; i++) { 13406 if (intent.filterEquals(list.get(i))) { 13407 // This sticky already exists, replace it. 13408 list.set(i, new Intent(intent)); 13409 break; 13410 } 13411 } 13412 if (i >= N) { 13413 list.add(new Intent(intent)); 13414 } 13415 } 13416 13417 int[] users; 13418 if (userId == UserHandle.USER_ALL) { 13419 // Caller wants broadcast to go to all started users. 13420 users = mStartedUserArray; 13421 } else { 13422 // Caller wants broadcast to go to one specific user. 13423 users = new int[] {userId}; 13424 } 13425 13426 // Figure out who all will receive this broadcast. 13427 List receivers = null; 13428 List<BroadcastFilter> registeredReceivers = null; 13429 // Need to resolve the intent to interested receivers... 13430 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13431 == 0) { 13432 receivers = collectReceiverComponents(intent, resolvedType, users); 13433 } 13434 if (intent.getComponent() == null) { 13435 registeredReceivers = mReceiverResolver.queryIntent(intent, 13436 resolvedType, false, userId); 13437 } 13438 13439 final boolean replacePending = 13440 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13441 13442 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13443 + " replacePending=" + replacePending); 13444 13445 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13446 if (!ordered && NR > 0) { 13447 // If we are not serializing this broadcast, then send the 13448 // registered receivers separately so they don't wait for the 13449 // components to be launched. 13450 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13451 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13452 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13453 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13454 ordered, sticky, false, userId); 13455 if (DEBUG_BROADCAST) Slog.v( 13456 TAG, "Enqueueing parallel broadcast " + r); 13457 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13458 if (!replaced) { 13459 queue.enqueueParallelBroadcastLocked(r); 13460 queue.scheduleBroadcastsLocked(); 13461 } 13462 registeredReceivers = null; 13463 NR = 0; 13464 } 13465 13466 // Merge into one list. 13467 int ir = 0; 13468 if (receivers != null) { 13469 // A special case for PACKAGE_ADDED: do not allow the package 13470 // being added to see this broadcast. This prevents them from 13471 // using this as a back door to get run as soon as they are 13472 // installed. Maybe in the future we want to have a special install 13473 // broadcast or such for apps, but we'd like to deliberately make 13474 // this decision. 13475 String skipPackages[] = null; 13476 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13477 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13478 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13479 Uri data = intent.getData(); 13480 if (data != null) { 13481 String pkgName = data.getSchemeSpecificPart(); 13482 if (pkgName != null) { 13483 skipPackages = new String[] { pkgName }; 13484 } 13485 } 13486 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13487 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13488 } 13489 if (skipPackages != null && (skipPackages.length > 0)) { 13490 for (String skipPackage : skipPackages) { 13491 if (skipPackage != null) { 13492 int NT = receivers.size(); 13493 for (int it=0; it<NT; it++) { 13494 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13495 if (curt.activityInfo.packageName.equals(skipPackage)) { 13496 receivers.remove(it); 13497 it--; 13498 NT--; 13499 } 13500 } 13501 } 13502 } 13503 } 13504 13505 int NT = receivers != null ? receivers.size() : 0; 13506 int it = 0; 13507 ResolveInfo curt = null; 13508 BroadcastFilter curr = null; 13509 while (it < NT && ir < NR) { 13510 if (curt == null) { 13511 curt = (ResolveInfo)receivers.get(it); 13512 } 13513 if (curr == null) { 13514 curr = registeredReceivers.get(ir); 13515 } 13516 if (curr.getPriority() >= curt.priority) { 13517 // Insert this broadcast record into the final list. 13518 receivers.add(it, curr); 13519 ir++; 13520 curr = null; 13521 it++; 13522 NT++; 13523 } else { 13524 // Skip to the next ResolveInfo in the final list. 13525 it++; 13526 curt = null; 13527 } 13528 } 13529 } 13530 while (ir < NR) { 13531 if (receivers == null) { 13532 receivers = new ArrayList(); 13533 } 13534 receivers.add(registeredReceivers.get(ir)); 13535 ir++; 13536 } 13537 13538 if ((receivers != null && receivers.size() > 0) 13539 || resultTo != null) { 13540 BroadcastQueue queue = broadcastQueueForIntent(intent); 13541 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13542 callerPackage, callingPid, callingUid, resolvedType, 13543 requiredPermission, appOp, receivers, resultTo, resultCode, 13544 resultData, map, ordered, sticky, false, userId); 13545 if (DEBUG_BROADCAST) Slog.v( 13546 TAG, "Enqueueing ordered broadcast " + r 13547 + ": prev had " + queue.mOrderedBroadcasts.size()); 13548 if (DEBUG_BROADCAST) { 13549 int seq = r.intent.getIntExtra("seq", -1); 13550 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13551 } 13552 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13553 if (!replaced) { 13554 queue.enqueueOrderedBroadcastLocked(r); 13555 queue.scheduleBroadcastsLocked(); 13556 } 13557 } 13558 13559 return ActivityManager.BROADCAST_SUCCESS; 13560 } 13561 13562 final Intent verifyBroadcastLocked(Intent intent) { 13563 // Refuse possible leaked file descriptors 13564 if (intent != null && intent.hasFileDescriptors() == true) { 13565 throw new IllegalArgumentException("File descriptors passed in Intent"); 13566 } 13567 13568 int flags = intent.getFlags(); 13569 13570 if (!mProcessesReady) { 13571 // if the caller really truly claims to know what they're doing, go 13572 // ahead and allow the broadcast without launching any receivers 13573 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13574 intent = new Intent(intent); 13575 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13576 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13577 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13578 + " before boot completion"); 13579 throw new IllegalStateException("Cannot broadcast before boot completed"); 13580 } 13581 } 13582 13583 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13584 throw new IllegalArgumentException( 13585 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13586 } 13587 13588 return intent; 13589 } 13590 13591 public final int broadcastIntent(IApplicationThread caller, 13592 Intent intent, String resolvedType, IIntentReceiver resultTo, 13593 int resultCode, String resultData, Bundle map, 13594 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13595 enforceNotIsolatedCaller("broadcastIntent"); 13596 synchronized(this) { 13597 intent = verifyBroadcastLocked(intent); 13598 13599 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13600 final int callingPid = Binder.getCallingPid(); 13601 final int callingUid = Binder.getCallingUid(); 13602 final long origId = Binder.clearCallingIdentity(); 13603 int res = broadcastIntentLocked(callerApp, 13604 callerApp != null ? callerApp.info.packageName : null, 13605 intent, resolvedType, resultTo, 13606 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13607 callingPid, callingUid, userId); 13608 Binder.restoreCallingIdentity(origId); 13609 return res; 13610 } 13611 } 13612 13613 int broadcastIntentInPackage(String packageName, int uid, 13614 Intent intent, String resolvedType, IIntentReceiver resultTo, 13615 int resultCode, String resultData, Bundle map, 13616 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13617 synchronized(this) { 13618 intent = verifyBroadcastLocked(intent); 13619 13620 final long origId = Binder.clearCallingIdentity(); 13621 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13622 resultTo, resultCode, resultData, map, requiredPermission, 13623 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13624 Binder.restoreCallingIdentity(origId); 13625 return res; 13626 } 13627 } 13628 13629 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13630 // Refuse possible leaked file descriptors 13631 if (intent != null && intent.hasFileDescriptors() == true) { 13632 throw new IllegalArgumentException("File descriptors passed in Intent"); 13633 } 13634 13635 userId = handleIncomingUser(Binder.getCallingPid(), 13636 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13637 13638 synchronized(this) { 13639 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13640 != PackageManager.PERMISSION_GRANTED) { 13641 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13642 + Binder.getCallingPid() 13643 + ", uid=" + Binder.getCallingUid() 13644 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13645 Slog.w(TAG, msg); 13646 throw new SecurityException(msg); 13647 } 13648 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13649 if (stickies != null) { 13650 ArrayList<Intent> list = stickies.get(intent.getAction()); 13651 if (list != null) { 13652 int N = list.size(); 13653 int i; 13654 for (i=0; i<N; i++) { 13655 if (intent.filterEquals(list.get(i))) { 13656 list.remove(i); 13657 break; 13658 } 13659 } 13660 if (list.size() <= 0) { 13661 stickies.remove(intent.getAction()); 13662 } 13663 } 13664 if (stickies.size() <= 0) { 13665 mStickyBroadcasts.remove(userId); 13666 } 13667 } 13668 } 13669 } 13670 13671 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13672 String resultData, Bundle resultExtras, boolean resultAbort) { 13673 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13674 if (r == null) { 13675 Slog.w(TAG, "finishReceiver called but not found on queue"); 13676 return false; 13677 } 13678 13679 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13680 } 13681 13682 void backgroundServicesFinishedLocked(int userId) { 13683 for (BroadcastQueue queue : mBroadcastQueues) { 13684 queue.backgroundServicesFinishedLocked(userId); 13685 } 13686 } 13687 13688 public void finishReceiver(IBinder who, int resultCode, String resultData, 13689 Bundle resultExtras, boolean resultAbort) { 13690 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13691 13692 // Refuse possible leaked file descriptors 13693 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13694 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13695 } 13696 13697 final long origId = Binder.clearCallingIdentity(); 13698 try { 13699 boolean doNext = false; 13700 BroadcastRecord r; 13701 13702 synchronized(this) { 13703 r = broadcastRecordForReceiverLocked(who); 13704 if (r != null) { 13705 doNext = r.queue.finishReceiverLocked(r, resultCode, 13706 resultData, resultExtras, resultAbort, true); 13707 } 13708 } 13709 13710 if (doNext) { 13711 r.queue.processNextBroadcast(false); 13712 } 13713 trimApplications(); 13714 } finally { 13715 Binder.restoreCallingIdentity(origId); 13716 } 13717 } 13718 13719 // ========================================================= 13720 // INSTRUMENTATION 13721 // ========================================================= 13722 13723 public boolean startInstrumentation(ComponentName className, 13724 String profileFile, int flags, Bundle arguments, 13725 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13726 int userId) { 13727 enforceNotIsolatedCaller("startInstrumentation"); 13728 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13729 userId, false, true, "startInstrumentation", null); 13730 // Refuse possible leaked file descriptors 13731 if (arguments != null && arguments.hasFileDescriptors()) { 13732 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13733 } 13734 13735 synchronized(this) { 13736 InstrumentationInfo ii = null; 13737 ApplicationInfo ai = null; 13738 try { 13739 ii = mContext.getPackageManager().getInstrumentationInfo( 13740 className, STOCK_PM_FLAGS); 13741 ai = AppGlobals.getPackageManager().getApplicationInfo( 13742 ii.targetPackage, STOCK_PM_FLAGS, userId); 13743 } catch (PackageManager.NameNotFoundException e) { 13744 } catch (RemoteException e) { 13745 } 13746 if (ii == null) { 13747 reportStartInstrumentationFailure(watcher, className, 13748 "Unable to find instrumentation info for: " + className); 13749 return false; 13750 } 13751 if (ai == null) { 13752 reportStartInstrumentationFailure(watcher, className, 13753 "Unable to find instrumentation target package: " + ii.targetPackage); 13754 return false; 13755 } 13756 13757 int match = mContext.getPackageManager().checkSignatures( 13758 ii.targetPackage, ii.packageName); 13759 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13760 String msg = "Permission Denial: starting instrumentation " 13761 + className + " from pid=" 13762 + Binder.getCallingPid() 13763 + ", uid=" + Binder.getCallingPid() 13764 + " not allowed because package " + ii.packageName 13765 + " does not have a signature matching the target " 13766 + ii.targetPackage; 13767 reportStartInstrumentationFailure(watcher, className, msg); 13768 throw new SecurityException(msg); 13769 } 13770 13771 final long origId = Binder.clearCallingIdentity(); 13772 // Instrumentation can kill and relaunch even persistent processes 13773 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId, 13774 "start instr"); 13775 ProcessRecord app = addAppLocked(ai, false); 13776 app.instrumentationClass = className; 13777 app.instrumentationInfo = ai; 13778 app.instrumentationProfileFile = profileFile; 13779 app.instrumentationArguments = arguments; 13780 app.instrumentationWatcher = watcher; 13781 app.instrumentationUiAutomationConnection = uiAutomationConnection; 13782 app.instrumentationResultClass = className; 13783 Binder.restoreCallingIdentity(origId); 13784 } 13785 13786 return true; 13787 } 13788 13789 /** 13790 * Report errors that occur while attempting to start Instrumentation. Always writes the 13791 * error to the logs, but if somebody is watching, send the report there too. This enables 13792 * the "am" command to report errors with more information. 13793 * 13794 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13795 * @param cn The component name of the instrumentation. 13796 * @param report The error report. 13797 */ 13798 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13799 ComponentName cn, String report) { 13800 Slog.w(TAG, report); 13801 try { 13802 if (watcher != null) { 13803 Bundle results = new Bundle(); 13804 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13805 results.putString("Error", report); 13806 watcher.instrumentationStatus(cn, -1, results); 13807 } 13808 } catch (RemoteException e) { 13809 Slog.w(TAG, e); 13810 } 13811 } 13812 13813 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13814 if (app.instrumentationWatcher != null) { 13815 try { 13816 // NOTE: IInstrumentationWatcher *must* be oneway here 13817 app.instrumentationWatcher.instrumentationFinished( 13818 app.instrumentationClass, 13819 resultCode, 13820 results); 13821 } catch (RemoteException e) { 13822 } 13823 } 13824 if (app.instrumentationUiAutomationConnection != null) { 13825 try { 13826 app.instrumentationUiAutomationConnection.shutdown(); 13827 } catch (RemoteException re) { 13828 /* ignore */ 13829 } 13830 // Only a UiAutomation can set this flag and now that 13831 // it is finished we make sure it is reset to its default. 13832 mUserIsMonkey = false; 13833 } 13834 app.instrumentationWatcher = null; 13835 app.instrumentationUiAutomationConnection = null; 13836 app.instrumentationClass = null; 13837 app.instrumentationInfo = null; 13838 app.instrumentationProfileFile = null; 13839 app.instrumentationArguments = null; 13840 13841 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId, 13842 "finished inst"); 13843 } 13844 13845 public void finishInstrumentation(IApplicationThread target, 13846 int resultCode, Bundle results) { 13847 int userId = UserHandle.getCallingUserId(); 13848 // Refuse possible leaked file descriptors 13849 if (results != null && results.hasFileDescriptors()) { 13850 throw new IllegalArgumentException("File descriptors passed in Intent"); 13851 } 13852 13853 synchronized(this) { 13854 ProcessRecord app = getRecordForAppLocked(target); 13855 if (app == null) { 13856 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13857 return; 13858 } 13859 final long origId = Binder.clearCallingIdentity(); 13860 finishInstrumentationLocked(app, resultCode, results); 13861 Binder.restoreCallingIdentity(origId); 13862 } 13863 } 13864 13865 // ========================================================= 13866 // CONFIGURATION 13867 // ========================================================= 13868 13869 public ConfigurationInfo getDeviceConfigurationInfo() { 13870 ConfigurationInfo config = new ConfigurationInfo(); 13871 synchronized (this) { 13872 config.reqTouchScreen = mConfiguration.touchscreen; 13873 config.reqKeyboardType = mConfiguration.keyboard; 13874 config.reqNavigation = mConfiguration.navigation; 13875 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13876 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13877 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13878 } 13879 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13880 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13881 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13882 } 13883 config.reqGlEsVersion = GL_ES_VERSION; 13884 } 13885 return config; 13886 } 13887 13888 ActivityStack getFocusedStack() { 13889 return mStackSupervisor.getFocusedStack(); 13890 } 13891 13892 public Configuration getConfiguration() { 13893 Configuration ci; 13894 synchronized(this) { 13895 ci = new Configuration(mConfiguration); 13896 } 13897 return ci; 13898 } 13899 13900 public void updatePersistentConfiguration(Configuration values) { 13901 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13902 "updateConfiguration()"); 13903 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 13904 "updateConfiguration()"); 13905 if (values == null) { 13906 throw new NullPointerException("Configuration must not be null"); 13907 } 13908 13909 synchronized(this) { 13910 final long origId = Binder.clearCallingIdentity(); 13911 updateConfigurationLocked(values, null, true, false); 13912 Binder.restoreCallingIdentity(origId); 13913 } 13914 } 13915 13916 public void updateConfiguration(Configuration values) { 13917 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13918 "updateConfiguration()"); 13919 13920 synchronized(this) { 13921 if (values == null && mWindowManager != null) { 13922 // sentinel: fetch the current configuration from the window manager 13923 values = mWindowManager.computeNewConfiguration(); 13924 } 13925 13926 if (mWindowManager != null) { 13927 mProcessList.applyDisplaySize(mWindowManager); 13928 } 13929 13930 final long origId = Binder.clearCallingIdentity(); 13931 if (values != null) { 13932 Settings.System.clearConfiguration(values); 13933 } 13934 updateConfigurationLocked(values, null, false, false); 13935 Binder.restoreCallingIdentity(origId); 13936 } 13937 } 13938 13939 /** 13940 * Do either or both things: (1) change the current configuration, and (2) 13941 * make sure the given activity is running with the (now) current 13942 * configuration. Returns true if the activity has been left running, or 13943 * false if <var>starting</var> is being destroyed to match the new 13944 * configuration. 13945 * @param persistent TODO 13946 */ 13947 boolean updateConfigurationLocked(Configuration values, 13948 ActivityRecord starting, boolean persistent, boolean initLocale) { 13949 int changes = 0; 13950 13951 if (values != null) { 13952 Configuration newConfig = new Configuration(mConfiguration); 13953 changes = newConfig.updateFrom(values); 13954 if (changes != 0) { 13955 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13956 Slog.i(TAG, "Updating configuration to: " + values); 13957 } 13958 13959 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 13960 13961 if (values.locale != null && !initLocale) { 13962 saveLocaleLocked(values.locale, 13963 !values.locale.equals(mConfiguration.locale), 13964 values.userSetLocale); 13965 } 13966 13967 mConfigurationSeq++; 13968 if (mConfigurationSeq <= 0) { 13969 mConfigurationSeq = 1; 13970 } 13971 newConfig.seq = mConfigurationSeq; 13972 mConfiguration = newConfig; 13973 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 13974 13975 final Configuration configCopy = new Configuration(mConfiguration); 13976 13977 // TODO: If our config changes, should we auto dismiss any currently 13978 // showing dialogs? 13979 mShowDialogs = shouldShowDialogs(newConfig); 13980 13981 AttributeCache ac = AttributeCache.instance(); 13982 if (ac != null) { 13983 ac.updateConfiguration(configCopy); 13984 } 13985 13986 // Make sure all resources in our process are updated 13987 // right now, so that anyone who is going to retrieve 13988 // resource values after we return will be sure to get 13989 // the new ones. This is especially important during 13990 // boot, where the first config change needs to guarantee 13991 // all resources have that config before following boot 13992 // code is executed. 13993 mSystemThread.applyConfigurationToResources(configCopy); 13994 13995 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 13996 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 13997 msg.obj = new Configuration(configCopy); 13998 mHandler.sendMessage(msg); 13999 } 14000 14001 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14002 ProcessRecord app = mLruProcesses.get(i); 14003 try { 14004 if (app.thread != null) { 14005 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14006 + app.processName + " new config " + mConfiguration); 14007 app.thread.scheduleConfigurationChanged(configCopy); 14008 } 14009 } catch (Exception e) { 14010 } 14011 } 14012 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14013 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14014 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14015 | Intent.FLAG_RECEIVER_FOREGROUND); 14016 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14017 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14018 Process.SYSTEM_UID, UserHandle.USER_ALL); 14019 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14020 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14021 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14022 broadcastIntentLocked(null, null, intent, 14023 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14024 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14025 } 14026 } 14027 } 14028 14029 boolean kept = true; 14030 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14031 // mainStack is null during startup. 14032 if (mainStack != null) { 14033 if (changes != 0 && starting == null) { 14034 // If the configuration changed, and the caller is not already 14035 // in the process of starting an activity, then find the top 14036 // activity to check if its configuration needs to change. 14037 starting = mainStack.topRunningActivityLocked(null); 14038 } 14039 14040 if (starting != null) { 14041 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14042 // And we need to make sure at this point that all other activities 14043 // are made visible with the correct configuration. 14044 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14045 } 14046 } 14047 14048 if (values != null && mWindowManager != null) { 14049 mWindowManager.setNewConfiguration(mConfiguration); 14050 } 14051 14052 return kept; 14053 } 14054 14055 /** 14056 * Decide based on the configuration whether we should shouw the ANR, 14057 * crash, etc dialogs. The idea is that if there is no affordnace to 14058 * press the on-screen buttons, we shouldn't show the dialog. 14059 * 14060 * A thought: SystemUI might also want to get told about this, the Power 14061 * dialog / global actions also might want different behaviors. 14062 */ 14063 private static final boolean shouldShowDialogs(Configuration config) { 14064 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14065 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14066 } 14067 14068 /** 14069 * Save the locale. You must be inside a synchronized (this) block. 14070 */ 14071 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14072 if(isDiff) { 14073 SystemProperties.set("user.language", l.getLanguage()); 14074 SystemProperties.set("user.region", l.getCountry()); 14075 } 14076 14077 if(isPersist) { 14078 SystemProperties.set("persist.sys.language", l.getLanguage()); 14079 SystemProperties.set("persist.sys.country", l.getCountry()); 14080 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14081 } 14082 } 14083 14084 @Override 14085 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14086 ActivityRecord srec = ActivityRecord.forToken(token); 14087 return srec != null && srec.task.affinity != null && 14088 srec.task.affinity.equals(destAffinity); 14089 } 14090 14091 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14092 Intent resultData) { 14093 14094 synchronized (this) { 14095 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14096 if (stack != null) { 14097 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14098 } 14099 return false; 14100 } 14101 } 14102 14103 public int getLaunchedFromUid(IBinder activityToken) { 14104 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14105 if (srec == null) { 14106 return -1; 14107 } 14108 return srec.launchedFromUid; 14109 } 14110 14111 public String getLaunchedFromPackage(IBinder activityToken) { 14112 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14113 if (srec == null) { 14114 return null; 14115 } 14116 return srec.launchedFromPackage; 14117 } 14118 14119 // ========================================================= 14120 // LIFETIME MANAGEMENT 14121 // ========================================================= 14122 14123 // Returns which broadcast queue the app is the current [or imminent] receiver 14124 // on, or 'null' if the app is not an active broadcast recipient. 14125 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14126 BroadcastRecord r = app.curReceiver; 14127 if (r != null) { 14128 return r.queue; 14129 } 14130 14131 // It's not the current receiver, but it might be starting up to become one 14132 synchronized (this) { 14133 for (BroadcastQueue queue : mBroadcastQueues) { 14134 r = queue.mPendingBroadcast; 14135 if (r != null && r.curApp == app) { 14136 // found it; report which queue it's in 14137 return queue; 14138 } 14139 } 14140 } 14141 14142 return null; 14143 } 14144 14145 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14146 boolean doingAll, long now) { 14147 if (mAdjSeq == app.adjSeq) { 14148 // This adjustment has already been computed. 14149 return app.curRawAdj; 14150 } 14151 14152 if (app.thread == null) { 14153 app.adjSeq = mAdjSeq; 14154 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14155 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14156 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14157 } 14158 14159 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14160 app.adjSource = null; 14161 app.adjTarget = null; 14162 app.empty = false; 14163 app.cached = false; 14164 14165 final int activitiesSize = app.activities.size(); 14166 14167 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14168 // The max adjustment doesn't allow this app to be anything 14169 // below foreground, so it is not worth doing work for it. 14170 app.adjType = "fixed"; 14171 app.adjSeq = mAdjSeq; 14172 app.curRawAdj = app.maxAdj; 14173 app.foregroundActivities = false; 14174 app.keeping = true; 14175 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14176 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14177 // System process can do UI, and when they do we want to have 14178 // them trim their memory after the user leaves the UI. To 14179 // facilitate this, here we need to determine whether or not it 14180 // is currently showing UI. 14181 app.systemNoUi = true; 14182 if (app == TOP_APP) { 14183 app.systemNoUi = false; 14184 } else if (activitiesSize > 0) { 14185 for (int j = 0; j < activitiesSize; j++) { 14186 final ActivityRecord r = app.activities.get(j); 14187 if (r.visible) { 14188 app.systemNoUi = false; 14189 } 14190 } 14191 } 14192 if (!app.systemNoUi) { 14193 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14194 } 14195 return (app.curAdj=app.maxAdj); 14196 } 14197 14198 app.keeping = false; 14199 app.systemNoUi = false; 14200 14201 // Determine the importance of the process, starting with most 14202 // important to least, and assign an appropriate OOM adjustment. 14203 int adj; 14204 int schedGroup; 14205 int procState; 14206 boolean foregroundActivities = false; 14207 boolean interesting = false; 14208 BroadcastQueue queue; 14209 if (app == TOP_APP) { 14210 // The last app on the list is the foreground app. 14211 adj = ProcessList.FOREGROUND_APP_ADJ; 14212 schedGroup = Process.THREAD_GROUP_DEFAULT; 14213 app.adjType = "top-activity"; 14214 foregroundActivities = true; 14215 interesting = true; 14216 procState = ActivityManager.PROCESS_STATE_TOP; 14217 } else if (app.instrumentationClass != null) { 14218 // Don't want to kill running instrumentation. 14219 adj = ProcessList.FOREGROUND_APP_ADJ; 14220 schedGroup = Process.THREAD_GROUP_DEFAULT; 14221 app.adjType = "instrumentation"; 14222 interesting = true; 14223 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14224 } else if ((queue = isReceivingBroadcast(app)) != null) { 14225 // An app that is currently receiving a broadcast also 14226 // counts as being in the foreground for OOM killer purposes. 14227 // It's placed in a sched group based on the nature of the 14228 // broadcast as reflected by which queue it's active in. 14229 adj = ProcessList.FOREGROUND_APP_ADJ; 14230 schedGroup = (queue == mFgBroadcastQueue) 14231 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14232 app.adjType = "broadcast"; 14233 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14234 } else if (app.executingServices.size() > 0) { 14235 // An app that is currently executing a service callback also 14236 // counts as being in the foreground. 14237 adj = ProcessList.FOREGROUND_APP_ADJ; 14238 schedGroup = app.execServicesFg ? 14239 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14240 app.adjType = "exec-service"; 14241 procState = ActivityManager.PROCESS_STATE_SERVICE; 14242 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14243 } else { 14244 // As far as we know the process is empty. We may change our mind later. 14245 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14246 // At this point we don't actually know the adjustment. Use the cached adj 14247 // value that the caller wants us to. 14248 adj = cachedAdj; 14249 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14250 app.cached = true; 14251 app.empty = true; 14252 app.adjType = "cch-empty"; 14253 } 14254 14255 // Examine all activities if not already foreground. 14256 if (!foregroundActivities && activitiesSize > 0) { 14257 for (int j = 0; j < activitiesSize; j++) { 14258 final ActivityRecord r = app.activities.get(j); 14259 if (r.app != app) { 14260 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14261 + app + "?!?"); 14262 continue; 14263 } 14264 if (r.visible) { 14265 // App has a visible activity; only upgrade adjustment. 14266 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14267 adj = ProcessList.VISIBLE_APP_ADJ; 14268 app.adjType = "visible"; 14269 } 14270 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14271 procState = ActivityManager.PROCESS_STATE_TOP; 14272 } 14273 schedGroup = Process.THREAD_GROUP_DEFAULT; 14274 app.cached = false; 14275 app.empty = false; 14276 foregroundActivities = true; 14277 break; 14278 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14279 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14280 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14281 app.adjType = "pausing"; 14282 } 14283 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14284 procState = ActivityManager.PROCESS_STATE_TOP; 14285 } 14286 schedGroup = Process.THREAD_GROUP_DEFAULT; 14287 app.cached = false; 14288 app.empty = false; 14289 foregroundActivities = true; 14290 } else if (r.state == ActivityState.STOPPING) { 14291 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14292 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14293 app.adjType = "stopping"; 14294 } 14295 // For the process state, we will at this point consider the 14296 // process to be cached. It will be cached either as an activity 14297 // or empty depending on whether the activity is finishing. We do 14298 // this so that we can treat the process as cached for purposes of 14299 // memory trimming (determing current memory level, trim command to 14300 // send to process) since there can be an arbitrary number of stopping 14301 // processes and they should soon all go into the cached state. 14302 if (!r.finishing) { 14303 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14304 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14305 } 14306 } 14307 app.cached = false; 14308 app.empty = false; 14309 foregroundActivities = true; 14310 } else { 14311 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14312 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14313 app.adjType = "cch-act"; 14314 } 14315 } 14316 } 14317 } 14318 14319 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14320 if (app.foregroundServices) { 14321 // The user is aware of this app, so make it visible. 14322 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14323 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14324 app.cached = false; 14325 app.adjType = "fg-service"; 14326 schedGroup = Process.THREAD_GROUP_DEFAULT; 14327 } else if (app.forcingToForeground != null) { 14328 // The user is aware of this app, so make it visible. 14329 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14330 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14331 app.cached = false; 14332 app.adjType = "force-fg"; 14333 app.adjSource = app.forcingToForeground; 14334 schedGroup = Process.THREAD_GROUP_DEFAULT; 14335 } 14336 } 14337 14338 if (app.foregroundServices) { 14339 interesting = true; 14340 } 14341 14342 if (app == mHeavyWeightProcess) { 14343 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14344 // We don't want to kill the current heavy-weight process. 14345 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14346 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14347 app.cached = false; 14348 app.adjType = "heavy"; 14349 } 14350 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14351 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14352 } 14353 } 14354 14355 if (app == mHomeProcess) { 14356 if (adj > ProcessList.HOME_APP_ADJ) { 14357 // This process is hosting what we currently consider to be the 14358 // home app, so we don't want to let it go into the background. 14359 adj = ProcessList.HOME_APP_ADJ; 14360 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14361 app.cached = false; 14362 app.adjType = "home"; 14363 } 14364 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14365 procState = ActivityManager.PROCESS_STATE_HOME; 14366 } 14367 } 14368 14369 if (app == mPreviousProcess && app.activities.size() > 0) { 14370 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14371 // This was the previous process that showed UI to the user. 14372 // We want to try to keep it around more aggressively, to give 14373 // a good experience around switching between two apps. 14374 adj = ProcessList.PREVIOUS_APP_ADJ; 14375 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14376 app.cached = false; 14377 app.adjType = "previous"; 14378 } 14379 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14380 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14381 } 14382 } 14383 14384 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14385 + " reason=" + app.adjType); 14386 14387 // By default, we use the computed adjustment. It may be changed if 14388 // there are applications dependent on our services or providers, but 14389 // this gives us a baseline and makes sure we don't get into an 14390 // infinite recursion. 14391 app.adjSeq = mAdjSeq; 14392 app.curRawAdj = adj; 14393 app.hasStartedServices = false; 14394 14395 if (mBackupTarget != null && app == mBackupTarget.app) { 14396 // If possible we want to avoid killing apps while they're being backed up 14397 if (adj > ProcessList.BACKUP_APP_ADJ) { 14398 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14399 adj = ProcessList.BACKUP_APP_ADJ; 14400 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14401 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14402 } 14403 app.adjType = "backup"; 14404 app.cached = false; 14405 } 14406 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14407 procState = ActivityManager.PROCESS_STATE_BACKUP; 14408 } 14409 } 14410 14411 boolean mayBeTop = false; 14412 14413 for (int is = app.services.size()-1; 14414 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14415 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14416 || procState > ActivityManager.PROCESS_STATE_TOP); 14417 is--) { 14418 ServiceRecord s = app.services.valueAt(is); 14419 if (s.startRequested) { 14420 app.hasStartedServices = true; 14421 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14422 procState = ActivityManager.PROCESS_STATE_SERVICE; 14423 } 14424 if (app.hasShownUi && app != mHomeProcess) { 14425 // If this process has shown some UI, let it immediately 14426 // go to the LRU list because it may be pretty heavy with 14427 // UI stuff. We'll tag it with a label just to help 14428 // debug and understand what is going on. 14429 if (adj > ProcessList.SERVICE_ADJ) { 14430 app.adjType = "cch-started-ui-services"; 14431 } 14432 } else { 14433 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14434 // This service has seen some activity within 14435 // recent memory, so we will keep its process ahead 14436 // of the background processes. 14437 if (adj > ProcessList.SERVICE_ADJ) { 14438 adj = ProcessList.SERVICE_ADJ; 14439 app.adjType = "started-services"; 14440 app.cached = false; 14441 } 14442 } 14443 // If we have let the service slide into the background 14444 // state, still have some text describing what it is doing 14445 // even though the service no longer has an impact. 14446 if (adj > ProcessList.SERVICE_ADJ) { 14447 app.adjType = "cch-started-services"; 14448 } 14449 } 14450 // Don't kill this process because it is doing work; it 14451 // has said it is doing work. 14452 app.keeping = true; 14453 } 14454 for (int conni = s.connections.size()-1; 14455 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14456 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14457 || procState > ActivityManager.PROCESS_STATE_TOP); 14458 conni--) { 14459 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14460 for (int i = 0; 14461 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14462 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14463 || procState > ActivityManager.PROCESS_STATE_TOP); 14464 i++) { 14465 // XXX should compute this based on the max of 14466 // all connected clients. 14467 ConnectionRecord cr = clist.get(i); 14468 if (cr.binding.client == app) { 14469 // Binding to ourself is not interesting. 14470 continue; 14471 } 14472 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14473 ProcessRecord client = cr.binding.client; 14474 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14475 TOP_APP, doingAll, now); 14476 int clientProcState = client.curProcState; 14477 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14478 // If the other app is cached for any reason, for purposes here 14479 // we are going to consider it empty. The specific cached state 14480 // doesn't propagate except under certain conditions. 14481 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14482 } 14483 String adjType = null; 14484 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14485 // Not doing bind OOM management, so treat 14486 // this guy more like a started service. 14487 if (app.hasShownUi && app != mHomeProcess) { 14488 // If this process has shown some UI, let it immediately 14489 // go to the LRU list because it may be pretty heavy with 14490 // UI stuff. We'll tag it with a label just to help 14491 // debug and understand what is going on. 14492 if (adj > clientAdj) { 14493 adjType = "cch-bound-ui-services"; 14494 } 14495 app.cached = false; 14496 clientAdj = adj; 14497 clientProcState = procState; 14498 } else { 14499 if (now >= (s.lastActivity 14500 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14501 // This service has not seen activity within 14502 // recent memory, so allow it to drop to the 14503 // LRU list if there is no other reason to keep 14504 // it around. We'll also tag it with a label just 14505 // to help debug and undertand what is going on. 14506 if (adj > clientAdj) { 14507 adjType = "cch-bound-services"; 14508 } 14509 clientAdj = adj; 14510 } 14511 } 14512 } 14513 if (adj > clientAdj) { 14514 // If this process has recently shown UI, and 14515 // the process that is binding to it is less 14516 // important than being visible, then we don't 14517 // care about the binding as much as we care 14518 // about letting this process get into the LRU 14519 // list to be killed and restarted if needed for 14520 // memory. 14521 if (app.hasShownUi && app != mHomeProcess 14522 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14523 adjType = "cch-bound-ui-services"; 14524 } else { 14525 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14526 |Context.BIND_IMPORTANT)) != 0) { 14527 adj = clientAdj; 14528 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14529 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14530 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14531 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14532 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14533 adj = clientAdj; 14534 } else { 14535 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14536 adj = ProcessList.VISIBLE_APP_ADJ; 14537 } 14538 } 14539 if (!client.cached) { 14540 app.cached = false; 14541 } 14542 if (client.keeping) { 14543 app.keeping = true; 14544 } 14545 adjType = "service"; 14546 } 14547 } 14548 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14549 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14550 schedGroup = Process.THREAD_GROUP_DEFAULT; 14551 } 14552 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14553 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14554 // Special handling of clients who are in the top state. 14555 // We *may* want to consider this process to be in the 14556 // top state as well, but only if there is not another 14557 // reason for it to be running. Being on the top is a 14558 // special state, meaning you are specifically running 14559 // for the current top app. If the process is already 14560 // running in the background for some other reason, it 14561 // is more important to continue considering it to be 14562 // in the background state. 14563 mayBeTop = true; 14564 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14565 } else { 14566 // Special handling for above-top states (persistent 14567 // processes). These should not bring the current process 14568 // into the top state, since they are not on top. Instead 14569 // give them the best state after that. 14570 clientProcState = 14571 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14572 } 14573 } 14574 } else { 14575 if (clientProcState < 14576 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14577 clientProcState = 14578 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14579 } 14580 } 14581 if (procState > clientProcState) { 14582 procState = clientProcState; 14583 } 14584 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14585 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14586 app.pendingUiClean = true; 14587 } 14588 if (adjType != null) { 14589 app.adjType = adjType; 14590 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14591 .REASON_SERVICE_IN_USE; 14592 app.adjSource = cr.binding.client; 14593 app.adjSourceOom = clientAdj; 14594 app.adjTarget = s.name; 14595 } 14596 } 14597 final ActivityRecord a = cr.activity; 14598 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14599 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14600 (a.visible || a.state == ActivityState.RESUMED 14601 || a.state == ActivityState.PAUSING)) { 14602 adj = ProcessList.FOREGROUND_APP_ADJ; 14603 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14604 schedGroup = Process.THREAD_GROUP_DEFAULT; 14605 } 14606 app.cached = false; 14607 app.adjType = "service"; 14608 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14609 .REASON_SERVICE_IN_USE; 14610 app.adjSource = a; 14611 app.adjSourceOom = adj; 14612 app.adjTarget = s.name; 14613 } 14614 } 14615 } 14616 } 14617 } 14618 14619 for (int provi = app.pubProviders.size()-1; 14620 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14621 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14622 || procState > ActivityManager.PROCESS_STATE_TOP); 14623 provi--) { 14624 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14625 for (int i = cpr.connections.size()-1; 14626 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14627 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14628 || procState > ActivityManager.PROCESS_STATE_TOP); 14629 i--) { 14630 ContentProviderConnection conn = cpr.connections.get(i); 14631 ProcessRecord client = conn.client; 14632 if (client == app) { 14633 // Being our own client is not interesting. 14634 continue; 14635 } 14636 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14637 int clientProcState = client.curProcState; 14638 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14639 // If the other app is cached for any reason, for purposes here 14640 // we are going to consider it empty. 14641 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14642 } 14643 if (adj > clientAdj) { 14644 if (app.hasShownUi && app != mHomeProcess 14645 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14646 app.adjType = "cch-ui-provider"; 14647 } else { 14648 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14649 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14650 app.adjType = "provider"; 14651 } 14652 app.cached &= client.cached; 14653 app.keeping |= client.keeping; 14654 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14655 .REASON_PROVIDER_IN_USE; 14656 app.adjSource = client; 14657 app.adjSourceOom = clientAdj; 14658 app.adjTarget = cpr.name; 14659 } 14660 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14661 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14662 // Special handling of clients who are in the top state. 14663 // We *may* want to consider this process to be in the 14664 // top state as well, but only if there is not another 14665 // reason for it to be running. Being on the top is a 14666 // special state, meaning you are specifically running 14667 // for the current top app. If the process is already 14668 // running in the background for some other reason, it 14669 // is more important to continue considering it to be 14670 // in the background state. 14671 mayBeTop = true; 14672 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14673 } else { 14674 // Special handling for above-top states (persistent 14675 // processes). These should not bring the current process 14676 // into the top state, since they are not on top. Instead 14677 // give them the best state after that. 14678 clientProcState = 14679 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14680 } 14681 } 14682 if (procState > clientProcState) { 14683 procState = clientProcState; 14684 } 14685 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14686 schedGroup = Process.THREAD_GROUP_DEFAULT; 14687 } 14688 } 14689 // If the provider has external (non-framework) process 14690 // dependencies, ensure that its adjustment is at least 14691 // FOREGROUND_APP_ADJ. 14692 if (cpr.hasExternalProcessHandles()) { 14693 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14694 adj = ProcessList.FOREGROUND_APP_ADJ; 14695 schedGroup = Process.THREAD_GROUP_DEFAULT; 14696 app.cached = false; 14697 app.keeping = true; 14698 app.adjType = "provider"; 14699 app.adjTarget = cpr.name; 14700 } 14701 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14702 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14703 } 14704 } 14705 } 14706 14707 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14708 // A client of one of our services or providers is in the top state. We 14709 // *may* want to be in the top state, but not if we are already running in 14710 // the background for some other reason. For the decision here, we are going 14711 // to pick out a few specific states that we want to remain in when a client 14712 // is top (states that tend to be longer-term) and otherwise allow it to go 14713 // to the top state. 14714 switch (procState) { 14715 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14716 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14717 case ActivityManager.PROCESS_STATE_SERVICE: 14718 // These all are longer-term states, so pull them up to the top 14719 // of the background states, but not all the way to the top state. 14720 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14721 break; 14722 default: 14723 // Otherwise, top is a better choice, so take it. 14724 procState = ActivityManager.PROCESS_STATE_TOP; 14725 break; 14726 } 14727 } 14728 14729 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14730 // This is a cached process, but with client activities. Mark it so. 14731 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14732 app.adjType = "cch-client-act"; 14733 } 14734 14735 if (adj == ProcessList.SERVICE_ADJ) { 14736 if (doingAll) { 14737 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14738 mNewNumServiceProcs++; 14739 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14740 if (!app.serviceb) { 14741 // This service isn't far enough down on the LRU list to 14742 // normally be a B service, but if we are low on RAM and it 14743 // is large we want to force it down since we would prefer to 14744 // keep launcher over it. 14745 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 14746 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 14747 app.serviceHighRam = true; 14748 app.serviceb = true; 14749 //Slog.i(TAG, "ADJ " + app + " high ram!"); 14750 } else { 14751 mNewNumAServiceProcs++; 14752 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 14753 } 14754 } else { 14755 app.serviceHighRam = false; 14756 } 14757 } 14758 if (app.serviceb) { 14759 adj = ProcessList.SERVICE_B_ADJ; 14760 } 14761 } 14762 14763 app.curRawAdj = adj; 14764 14765 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14766 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14767 if (adj > app.maxAdj) { 14768 adj = app.maxAdj; 14769 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14770 schedGroup = Process.THREAD_GROUP_DEFAULT; 14771 } 14772 } 14773 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 14774 app.keeping = true; 14775 } 14776 14777 // Do final modification to adj. Everything we do between here and applying 14778 // the final setAdj must be done in this function, because we will also use 14779 // it when computing the final cached adj later. Note that we don't need to 14780 // worry about this for max adj above, since max adj will always be used to 14781 // keep it out of the cached vaues. 14782 adj = app.modifyRawOomAdj(adj); 14783 14784 app.curProcState = procState; 14785 14786 int importance = app.memImportance; 14787 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14788 app.curAdj = adj; 14789 app.curSchedGroup = schedGroup; 14790 if (!interesting) { 14791 // For this reporting, if there is not something explicitly 14792 // interesting in this process then we will push it to the 14793 // background importance. 14794 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14795 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 14796 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14797 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14798 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14799 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14800 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14801 } else if (adj >= ProcessList.SERVICE_ADJ) { 14802 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14803 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14804 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14805 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14806 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14807 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14808 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14809 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14810 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14811 } else { 14812 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14813 } 14814 } 14815 14816 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14817 if (foregroundActivities != app.foregroundActivities) { 14818 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14819 } 14820 if (changes != 0) { 14821 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14822 app.memImportance = importance; 14823 app.foregroundActivities = foregroundActivities; 14824 int i = mPendingProcessChanges.size()-1; 14825 ProcessChangeItem item = null; 14826 while (i >= 0) { 14827 item = mPendingProcessChanges.get(i); 14828 if (item.pid == app.pid) { 14829 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14830 break; 14831 } 14832 i--; 14833 } 14834 if (i < 0) { 14835 // No existing item in pending changes; need a new one. 14836 final int NA = mAvailProcessChanges.size(); 14837 if (NA > 0) { 14838 item = mAvailProcessChanges.remove(NA-1); 14839 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14840 } else { 14841 item = new ProcessChangeItem(); 14842 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14843 } 14844 item.changes = 0; 14845 item.pid = app.pid; 14846 item.uid = app.info.uid; 14847 if (mPendingProcessChanges.size() == 0) { 14848 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14849 "*** Enqueueing dispatch processes changed!"); 14850 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14851 } 14852 mPendingProcessChanges.add(item); 14853 } 14854 item.changes |= changes; 14855 item.importance = importance; 14856 item.foregroundActivities = foregroundActivities; 14857 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14858 + Integer.toHexString(System.identityHashCode(item)) 14859 + " " + app.toShortString() + ": changes=" + item.changes 14860 + " importance=" + item.importance 14861 + " foreground=" + item.foregroundActivities 14862 + " type=" + app.adjType + " source=" + app.adjSource 14863 + " target=" + app.adjTarget); 14864 } 14865 14866 return app.curRawAdj; 14867 } 14868 14869 /** 14870 * Schedule PSS collection of a process. 14871 */ 14872 void requestPssLocked(ProcessRecord proc, int procState) { 14873 if (mPendingPssProcesses.contains(proc)) { 14874 return; 14875 } 14876 if (mPendingPssProcesses.size() == 0) { 14877 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14878 } 14879 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 14880 proc.pssProcState = procState; 14881 mPendingPssProcesses.add(proc); 14882 } 14883 14884 /** 14885 * Schedule PSS collection of all processes. 14886 */ 14887 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 14888 if (!always) { 14889 if (now < (mLastFullPssTime + 14890 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 14891 return; 14892 } 14893 } 14894 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 14895 mLastFullPssTime = now; 14896 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 14897 mPendingPssProcesses.clear(); 14898 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14899 ProcessRecord app = mLruProcesses.get(i); 14900 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 14901 app.pssProcState = app.setProcState; 14902 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 14903 mSleeping, now); 14904 mPendingPssProcesses.add(app); 14905 } 14906 } 14907 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14908 } 14909 14910 /** 14911 * Ask a given process to GC right now. 14912 */ 14913 final void performAppGcLocked(ProcessRecord app) { 14914 try { 14915 app.lastRequestedGc = SystemClock.uptimeMillis(); 14916 if (app.thread != null) { 14917 if (app.reportLowMemory) { 14918 app.reportLowMemory = false; 14919 app.thread.scheduleLowMemory(); 14920 } else { 14921 app.thread.processInBackground(); 14922 } 14923 } 14924 } catch (Exception e) { 14925 // whatever. 14926 } 14927 } 14928 14929 /** 14930 * Returns true if things are idle enough to perform GCs. 14931 */ 14932 private final boolean canGcNowLocked() { 14933 boolean processingBroadcasts = false; 14934 for (BroadcastQueue q : mBroadcastQueues) { 14935 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 14936 processingBroadcasts = true; 14937 } 14938 } 14939 return !processingBroadcasts 14940 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 14941 } 14942 14943 /** 14944 * Perform GCs on all processes that are waiting for it, but only 14945 * if things are idle. 14946 */ 14947 final void performAppGcsLocked() { 14948 final int N = mProcessesToGc.size(); 14949 if (N <= 0) { 14950 return; 14951 } 14952 if (canGcNowLocked()) { 14953 while (mProcessesToGc.size() > 0) { 14954 ProcessRecord proc = mProcessesToGc.remove(0); 14955 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 14956 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 14957 <= SystemClock.uptimeMillis()) { 14958 // To avoid spamming the system, we will GC processes one 14959 // at a time, waiting a few seconds between each. 14960 performAppGcLocked(proc); 14961 scheduleAppGcsLocked(); 14962 return; 14963 } else { 14964 // It hasn't been long enough since we last GCed this 14965 // process... put it in the list to wait for its time. 14966 addProcessToGcListLocked(proc); 14967 break; 14968 } 14969 } 14970 } 14971 14972 scheduleAppGcsLocked(); 14973 } 14974 } 14975 14976 /** 14977 * If all looks good, perform GCs on all processes waiting for them. 14978 */ 14979 final void performAppGcsIfAppropriateLocked() { 14980 if (canGcNowLocked()) { 14981 performAppGcsLocked(); 14982 return; 14983 } 14984 // Still not idle, wait some more. 14985 scheduleAppGcsLocked(); 14986 } 14987 14988 /** 14989 * Schedule the execution of all pending app GCs. 14990 */ 14991 final void scheduleAppGcsLocked() { 14992 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 14993 14994 if (mProcessesToGc.size() > 0) { 14995 // Schedule a GC for the time to the next process. 14996 ProcessRecord proc = mProcessesToGc.get(0); 14997 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 14998 14999 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15000 long now = SystemClock.uptimeMillis(); 15001 if (when < (now+GC_TIMEOUT)) { 15002 when = now + GC_TIMEOUT; 15003 } 15004 mHandler.sendMessageAtTime(msg, when); 15005 } 15006 } 15007 15008 /** 15009 * Add a process to the array of processes waiting to be GCed. Keeps the 15010 * list in sorted order by the last GC time. The process can't already be 15011 * on the list. 15012 */ 15013 final void addProcessToGcListLocked(ProcessRecord proc) { 15014 boolean added = false; 15015 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15016 if (mProcessesToGc.get(i).lastRequestedGc < 15017 proc.lastRequestedGc) { 15018 added = true; 15019 mProcessesToGc.add(i+1, proc); 15020 break; 15021 } 15022 } 15023 if (!added) { 15024 mProcessesToGc.add(0, proc); 15025 } 15026 } 15027 15028 /** 15029 * Set up to ask a process to GC itself. This will either do it 15030 * immediately, or put it on the list of processes to gc the next 15031 * time things are idle. 15032 */ 15033 final void scheduleAppGcLocked(ProcessRecord app) { 15034 long now = SystemClock.uptimeMillis(); 15035 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15036 return; 15037 } 15038 if (!mProcessesToGc.contains(app)) { 15039 addProcessToGcListLocked(app); 15040 scheduleAppGcsLocked(); 15041 } 15042 } 15043 15044 final void checkExcessivePowerUsageLocked(boolean doKills) { 15045 updateCpuStatsNow(); 15046 15047 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15048 boolean doWakeKills = doKills; 15049 boolean doCpuKills = doKills; 15050 if (mLastPowerCheckRealtime == 0) { 15051 doWakeKills = false; 15052 } 15053 if (mLastPowerCheckUptime == 0) { 15054 doCpuKills = false; 15055 } 15056 if (stats.isScreenOn()) { 15057 doWakeKills = false; 15058 } 15059 final long curRealtime = SystemClock.elapsedRealtime(); 15060 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15061 final long curUptime = SystemClock.uptimeMillis(); 15062 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15063 mLastPowerCheckRealtime = curRealtime; 15064 mLastPowerCheckUptime = curUptime; 15065 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15066 doWakeKills = false; 15067 } 15068 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15069 doCpuKills = false; 15070 } 15071 int i = mLruProcesses.size(); 15072 while (i > 0) { 15073 i--; 15074 ProcessRecord app = mLruProcesses.get(i); 15075 if (!app.keeping) { 15076 long wtime; 15077 synchronized (stats) { 15078 wtime = stats.getProcessWakeTime(app.info.uid, 15079 app.pid, curRealtime); 15080 } 15081 long wtimeUsed = wtime - app.lastWakeTime; 15082 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15083 if (DEBUG_POWER) { 15084 StringBuilder sb = new StringBuilder(128); 15085 sb.append("Wake for "); 15086 app.toShortString(sb); 15087 sb.append(": over "); 15088 TimeUtils.formatDuration(realtimeSince, sb); 15089 sb.append(" used "); 15090 TimeUtils.formatDuration(wtimeUsed, sb); 15091 sb.append(" ("); 15092 sb.append((wtimeUsed*100)/realtimeSince); 15093 sb.append("%)"); 15094 Slog.i(TAG, sb.toString()); 15095 sb.setLength(0); 15096 sb.append("CPU for "); 15097 app.toShortString(sb); 15098 sb.append(": over "); 15099 TimeUtils.formatDuration(uptimeSince, sb); 15100 sb.append(" used "); 15101 TimeUtils.formatDuration(cputimeUsed, sb); 15102 sb.append(" ("); 15103 sb.append((cputimeUsed*100)/uptimeSince); 15104 sb.append("%)"); 15105 Slog.i(TAG, sb.toString()); 15106 } 15107 // If a process has held a wake lock for more 15108 // than 50% of the time during this period, 15109 // that sounds bad. Kill! 15110 if (doWakeKills && realtimeSince > 0 15111 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15112 synchronized (stats) { 15113 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15114 realtimeSince, wtimeUsed); 15115 } 15116 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15117 + " during " + realtimeSince); 15118 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15119 } else if (doCpuKills && uptimeSince > 0 15120 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15121 synchronized (stats) { 15122 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15123 uptimeSince, cputimeUsed); 15124 } 15125 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15126 + " during " + uptimeSince); 15127 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15128 } else { 15129 app.lastWakeTime = wtime; 15130 app.lastCpuTime = app.curCpuTime; 15131 } 15132 } 15133 } 15134 } 15135 15136 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15137 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15138 boolean success = true; 15139 15140 if (app.curRawAdj != app.setRawAdj) { 15141 if (wasKeeping && !app.keeping) { 15142 // This app is no longer something we want to keep. Note 15143 // its current wake lock time to later know to kill it if 15144 // it is not behaving well. 15145 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15146 synchronized (stats) { 15147 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15148 app.pid, SystemClock.elapsedRealtime()); 15149 } 15150 app.lastCpuTime = app.curCpuTime; 15151 } 15152 15153 app.setRawAdj = app.curRawAdj; 15154 } 15155 15156 if (app.curAdj != app.setAdj) { 15157 ProcessList.setOomAdj(app.pid, app.curAdj); 15158 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15159 TAG, "Set " + app.pid + " " + app.processName + 15160 " adj " + app.curAdj + ": " + app.adjType); 15161 app.setAdj = app.curAdj; 15162 } 15163 15164 if (app.setSchedGroup != app.curSchedGroup) { 15165 app.setSchedGroup = app.curSchedGroup; 15166 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15167 "Setting process group of " + app.processName 15168 + " to " + app.curSchedGroup); 15169 if (app.waitingToKill != null && 15170 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15171 killUnneededProcessLocked(app, app.waitingToKill); 15172 success = false; 15173 } else { 15174 if (true) { 15175 long oldId = Binder.clearCallingIdentity(); 15176 try { 15177 Process.setProcessGroup(app.pid, app.curSchedGroup); 15178 } catch (Exception e) { 15179 Slog.w(TAG, "Failed setting process group of " + app.pid 15180 + " to " + app.curSchedGroup); 15181 e.printStackTrace(); 15182 } finally { 15183 Binder.restoreCallingIdentity(oldId); 15184 } 15185 } else { 15186 if (app.thread != null) { 15187 try { 15188 app.thread.setSchedulingGroup(app.curSchedGroup); 15189 } catch (RemoteException e) { 15190 } 15191 } 15192 } 15193 Process.setSwappiness(app.pid, 15194 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15195 } 15196 } 15197 if (app.repProcState != app.curProcState) { 15198 app.repProcState = app.curProcState; 15199 if (!reportingProcessState && app.thread != null) { 15200 try { 15201 if (false) { 15202 //RuntimeException h = new RuntimeException("here"); 15203 Slog.i(TAG, "Sending new process state " + app.repProcState 15204 + " to " + app /*, h*/); 15205 } 15206 app.thread.setProcessState(app.repProcState); 15207 } catch (RemoteException e) { 15208 } 15209 } 15210 } 15211 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15212 app.setProcState)) { 15213 app.lastStateTime = now; 15214 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15215 mSleeping, now); 15216 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15217 + ProcessList.makeProcStateString(app.setProcState) + " to " 15218 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15219 + (app.nextPssTime-now) + ": " + app); 15220 } else { 15221 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15222 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15223 requestPssLocked(app, app.setProcState); 15224 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15225 mSleeping, now); 15226 } else if (false && DEBUG_PSS) { 15227 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15228 } 15229 } 15230 if (app.setProcState != app.curProcState) { 15231 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15232 "Proc state change of " + app.processName 15233 + " to " + app.curProcState); 15234 app.setProcState = app.curProcState; 15235 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15236 app.notCachedSinceIdle = false; 15237 } 15238 if (!doingAll) { 15239 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15240 } else { 15241 app.procStateChanged = true; 15242 } 15243 } 15244 return success; 15245 } 15246 15247 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15248 if (proc.thread != null && proc.baseProcessTracker != null) { 15249 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15250 } 15251 } 15252 15253 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15254 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15255 if (app.thread == null) { 15256 return false; 15257 } 15258 15259 final boolean wasKeeping = app.keeping; 15260 15261 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15262 15263 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15264 reportingProcessState, now); 15265 } 15266 15267 private final ActivityRecord resumedAppLocked() { 15268 return mStackSupervisor.resumedAppLocked(); 15269 } 15270 15271 final boolean updateOomAdjLocked(ProcessRecord app) { 15272 return updateOomAdjLocked(app, false); 15273 } 15274 15275 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15276 final ActivityRecord TOP_ACT = resumedAppLocked(); 15277 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15278 final boolean wasCached = app.cached; 15279 15280 mAdjSeq++; 15281 15282 // This is the desired cached adjusment we want to tell it to use. 15283 // If our app is currently cached, we know it, and that is it. Otherwise, 15284 // we don't know it yet, and it needs to now be cached we will then 15285 // need to do a complete oom adj. 15286 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15287 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15288 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15289 SystemClock.uptimeMillis()); 15290 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15291 // Changed to/from cached state, so apps after it in the LRU 15292 // list may also be changed. 15293 updateOomAdjLocked(); 15294 } 15295 return success; 15296 } 15297 15298 final void updateOomAdjLocked() { 15299 final ActivityRecord TOP_ACT = resumedAppLocked(); 15300 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15301 final long now = SystemClock.uptimeMillis(); 15302 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15303 final int N = mLruProcesses.size(); 15304 15305 if (false) { 15306 RuntimeException e = new RuntimeException(); 15307 e.fillInStackTrace(); 15308 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15309 } 15310 15311 mAdjSeq++; 15312 mNewNumServiceProcs = 0; 15313 mNewNumAServiceProcs = 0; 15314 15315 final int emptyProcessLimit; 15316 final int cachedProcessLimit; 15317 if (mProcessLimit <= 0) { 15318 emptyProcessLimit = cachedProcessLimit = 0; 15319 } else if (mProcessLimit == 1) { 15320 emptyProcessLimit = 1; 15321 cachedProcessLimit = 0; 15322 } else { 15323 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15324 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15325 } 15326 15327 // Let's determine how many processes we have running vs. 15328 // how many slots we have for background processes; we may want 15329 // to put multiple processes in a slot of there are enough of 15330 // them. 15331 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15332 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15333 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15334 if (numEmptyProcs > cachedProcessLimit) { 15335 // If there are more empty processes than our limit on cached 15336 // processes, then use the cached process limit for the factor. 15337 // This ensures that the really old empty processes get pushed 15338 // down to the bottom, so if we are running low on memory we will 15339 // have a better chance at keeping around more cached processes 15340 // instead of a gazillion empty processes. 15341 numEmptyProcs = cachedProcessLimit; 15342 } 15343 int emptyFactor = numEmptyProcs/numSlots; 15344 if (emptyFactor < 1) emptyFactor = 1; 15345 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15346 if (cachedFactor < 1) cachedFactor = 1; 15347 int stepCached = 0; 15348 int stepEmpty = 0; 15349 int numCached = 0; 15350 int numEmpty = 0; 15351 int numTrimming = 0; 15352 15353 mNumNonCachedProcs = 0; 15354 mNumCachedHiddenProcs = 0; 15355 15356 // First update the OOM adjustment for each of the 15357 // application processes based on their current state. 15358 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15359 int nextCachedAdj = curCachedAdj+1; 15360 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15361 int nextEmptyAdj = curEmptyAdj+2; 15362 for (int i=N-1; i>=0; i--) { 15363 ProcessRecord app = mLruProcesses.get(i); 15364 if (!app.killedByAm && app.thread != null) { 15365 app.procStateChanged = false; 15366 final boolean wasKeeping = app.keeping; 15367 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15368 15369 // If we haven't yet assigned the final cached adj 15370 // to the process, do that now. 15371 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15372 switch (app.curProcState) { 15373 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15374 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15375 // This process is a cached process holding activities... 15376 // assign it the next cached value for that type, and then 15377 // step that cached level. 15378 app.curRawAdj = curCachedAdj; 15379 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15380 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15381 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15382 + ")"); 15383 if (curCachedAdj != nextCachedAdj) { 15384 stepCached++; 15385 if (stepCached >= cachedFactor) { 15386 stepCached = 0; 15387 curCachedAdj = nextCachedAdj; 15388 nextCachedAdj += 2; 15389 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15390 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15391 } 15392 } 15393 } 15394 break; 15395 default: 15396 // For everything else, assign next empty cached process 15397 // level and bump that up. Note that this means that 15398 // long-running services that have dropped down to the 15399 // cached level will be treated as empty (since their process 15400 // state is still as a service), which is what we want. 15401 app.curRawAdj = curEmptyAdj; 15402 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15403 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15404 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15405 + ")"); 15406 if (curEmptyAdj != nextEmptyAdj) { 15407 stepEmpty++; 15408 if (stepEmpty >= emptyFactor) { 15409 stepEmpty = 0; 15410 curEmptyAdj = nextEmptyAdj; 15411 nextEmptyAdj += 2; 15412 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15413 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15414 } 15415 } 15416 } 15417 break; 15418 } 15419 } 15420 15421 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15422 15423 // Count the number of process types. 15424 switch (app.curProcState) { 15425 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15426 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15427 mNumCachedHiddenProcs++; 15428 numCached++; 15429 if (numCached > cachedProcessLimit) { 15430 killUnneededProcessLocked(app, "cached #" + numCached); 15431 } 15432 break; 15433 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15434 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15435 && app.lastActivityTime < oldTime) { 15436 killUnneededProcessLocked(app, "empty for " 15437 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15438 / 1000) + "s"); 15439 } else { 15440 numEmpty++; 15441 if (numEmpty > emptyProcessLimit) { 15442 killUnneededProcessLocked(app, "empty #" + numEmpty); 15443 } 15444 } 15445 break; 15446 default: 15447 mNumNonCachedProcs++; 15448 break; 15449 } 15450 15451 if (app.isolated && app.services.size() <= 0) { 15452 // If this is an isolated process, and there are no 15453 // services running in it, then the process is no longer 15454 // needed. We agressively kill these because we can by 15455 // definition not re-use the same process again, and it is 15456 // good to avoid having whatever code was running in them 15457 // left sitting around after no longer needed. 15458 killUnneededProcessLocked(app, "isolated not needed"); 15459 } 15460 15461 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15462 && !app.killedByAm) { 15463 numTrimming++; 15464 } 15465 } 15466 } 15467 15468 mNumServiceProcs = mNewNumServiceProcs; 15469 15470 // Now determine the memory trimming level of background processes. 15471 // Unfortunately we need to start at the back of the list to do this 15472 // properly. We only do this if the number of background apps we 15473 // are managing to keep around is less than half the maximum we desire; 15474 // if we are keeping a good number around, we'll let them use whatever 15475 // memory they want. 15476 final int numCachedAndEmpty = numCached + numEmpty; 15477 int memFactor; 15478 if (numCached <= ProcessList.TRIM_CACHED_APPS 15479 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15480 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15481 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15482 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15483 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15484 } else { 15485 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15486 } 15487 } else { 15488 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15489 } 15490 // We always allow the memory level to go up (better). We only allow it to go 15491 // down if we are in a state where that is allowed, *and* the total number of processes 15492 // has gone down since last time. 15493 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15494 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15495 + " last=" + mLastNumProcesses); 15496 if (memFactor > mLastMemoryLevel) { 15497 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15498 memFactor = mLastMemoryLevel; 15499 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15500 } 15501 } 15502 mLastMemoryLevel = memFactor; 15503 mLastNumProcesses = mLruProcesses.size(); 15504 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15505 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15506 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15507 if (mLowRamStartTime == 0) { 15508 mLowRamStartTime = now; 15509 } 15510 int step = 0; 15511 int fgTrimLevel; 15512 switch (memFactor) { 15513 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15514 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15515 break; 15516 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15517 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15518 break; 15519 default: 15520 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15521 break; 15522 } 15523 int factor = numTrimming/3; 15524 int minFactor = 2; 15525 if (mHomeProcess != null) minFactor++; 15526 if (mPreviousProcess != null) minFactor++; 15527 if (factor < minFactor) factor = minFactor; 15528 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15529 for (int i=N-1; i>=0; i--) { 15530 ProcessRecord app = mLruProcesses.get(i); 15531 if (allChanged || app.procStateChanged) { 15532 setProcessTrackerState(app, trackerMemFactor, now); 15533 app.procStateChanged = false; 15534 } 15535 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15536 && !app.killedByAm) { 15537 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15538 try { 15539 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15540 "Trimming memory of " + app.processName 15541 + " to " + curLevel); 15542 app.thread.scheduleTrimMemory(curLevel); 15543 } catch (RemoteException e) { 15544 } 15545 if (false) { 15546 // For now we won't do this; our memory trimming seems 15547 // to be good enough at this point that destroying 15548 // activities causes more harm than good. 15549 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15550 && app != mHomeProcess && app != mPreviousProcess) { 15551 // Need to do this on its own message because the stack may not 15552 // be in a consistent state at this point. 15553 // For these apps we will also finish their activities 15554 // to help them free memory. 15555 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15556 } 15557 } 15558 } 15559 app.trimMemoryLevel = curLevel; 15560 step++; 15561 if (step >= factor) { 15562 step = 0; 15563 switch (curLevel) { 15564 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15565 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15566 break; 15567 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15568 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15569 break; 15570 } 15571 } 15572 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15573 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15574 && app.thread != null) { 15575 try { 15576 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15577 "Trimming memory of heavy-weight " + app.processName 15578 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15579 app.thread.scheduleTrimMemory( 15580 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15581 } catch (RemoteException e) { 15582 } 15583 } 15584 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15585 } else { 15586 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15587 || app.systemNoUi) && app.pendingUiClean) { 15588 // If this application is now in the background and it 15589 // had done UI, then give it the special trim level to 15590 // have it free UI resources. 15591 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15592 if (app.trimMemoryLevel < level && app.thread != null) { 15593 try { 15594 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15595 "Trimming memory of bg-ui " + app.processName 15596 + " to " + level); 15597 app.thread.scheduleTrimMemory(level); 15598 } catch (RemoteException e) { 15599 } 15600 } 15601 app.pendingUiClean = false; 15602 } 15603 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15604 try { 15605 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15606 "Trimming memory of fg " + app.processName 15607 + " to " + fgTrimLevel); 15608 app.thread.scheduleTrimMemory(fgTrimLevel); 15609 } catch (RemoteException e) { 15610 } 15611 } 15612 app.trimMemoryLevel = fgTrimLevel; 15613 } 15614 } 15615 } else { 15616 if (mLowRamStartTime != 0) { 15617 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15618 mLowRamStartTime = 0; 15619 } 15620 for (int i=N-1; i>=0; i--) { 15621 ProcessRecord app = mLruProcesses.get(i); 15622 if (allChanged || app.procStateChanged) { 15623 setProcessTrackerState(app, trackerMemFactor, now); 15624 app.procStateChanged = false; 15625 } 15626 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15627 || app.systemNoUi) && app.pendingUiClean) { 15628 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15629 && app.thread != null) { 15630 try { 15631 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15632 "Trimming memory of ui hidden " + app.processName 15633 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15634 app.thread.scheduleTrimMemory( 15635 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15636 } catch (RemoteException e) { 15637 } 15638 } 15639 app.pendingUiClean = false; 15640 } 15641 app.trimMemoryLevel = 0; 15642 } 15643 } 15644 15645 if (mAlwaysFinishActivities) { 15646 // Need to do this on its own message because the stack may not 15647 // be in a consistent state at this point. 15648 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15649 } 15650 15651 if (allChanged) { 15652 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15653 } 15654 15655 if (mProcessStats.shouldWriteNowLocked(now)) { 15656 mHandler.post(new Runnable() { 15657 @Override public void run() { 15658 synchronized (ActivityManagerService.this) { 15659 mProcessStats.writeStateAsyncLocked(); 15660 } 15661 } 15662 }); 15663 } 15664 15665 if (DEBUG_OOM_ADJ) { 15666 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15667 } 15668 } 15669 15670 final void trimApplications() { 15671 synchronized (this) { 15672 int i; 15673 15674 // First remove any unused application processes whose package 15675 // has been removed. 15676 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15677 final ProcessRecord app = mRemovedProcesses.get(i); 15678 if (app.activities.size() == 0 15679 && app.curReceiver == null && app.services.size() == 0) { 15680 Slog.i( 15681 TAG, "Exiting empty application process " 15682 + app.processName + " (" 15683 + (app.thread != null ? app.thread.asBinder() : null) 15684 + ")\n"); 15685 if (app.pid > 0 && app.pid != MY_PID) { 15686 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 15687 app.processName, app.setAdj, "empty"); 15688 app.killedByAm = true; 15689 Process.killProcessQuiet(app.pid); 15690 } else { 15691 try { 15692 app.thread.scheduleExit(); 15693 } catch (Exception e) { 15694 // Ignore exceptions. 15695 } 15696 } 15697 cleanUpApplicationRecordLocked(app, false, true, -1); 15698 mRemovedProcesses.remove(i); 15699 15700 if (app.persistent) { 15701 if (app.persistent) { 15702 addAppLocked(app.info, false); 15703 } 15704 } 15705 } 15706 } 15707 15708 // Now update the oom adj for all processes. 15709 updateOomAdjLocked(); 15710 } 15711 } 15712 15713 /** This method sends the specified signal to each of the persistent apps */ 15714 public void signalPersistentProcesses(int sig) throws RemoteException { 15715 if (sig != Process.SIGNAL_USR1) { 15716 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 15717 } 15718 15719 synchronized (this) { 15720 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 15721 != PackageManager.PERMISSION_GRANTED) { 15722 throw new SecurityException("Requires permission " 15723 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 15724 } 15725 15726 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15727 ProcessRecord r = mLruProcesses.get(i); 15728 if (r.thread != null && r.persistent) { 15729 Process.sendSignal(r.pid, sig); 15730 } 15731 } 15732 } 15733 } 15734 15735 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 15736 if (proc == null || proc == mProfileProc) { 15737 proc = mProfileProc; 15738 path = mProfileFile; 15739 profileType = mProfileType; 15740 clearProfilerLocked(); 15741 } 15742 if (proc == null) { 15743 return; 15744 } 15745 try { 15746 proc.thread.profilerControl(false, path, null, profileType); 15747 } catch (RemoteException e) { 15748 throw new IllegalStateException("Process disappeared"); 15749 } 15750 } 15751 15752 private void clearProfilerLocked() { 15753 if (mProfileFd != null) { 15754 try { 15755 mProfileFd.close(); 15756 } catch (IOException e) { 15757 } 15758 } 15759 mProfileApp = null; 15760 mProfileProc = null; 15761 mProfileFile = null; 15762 mProfileType = 0; 15763 mAutoStopProfiler = false; 15764 } 15765 15766 public boolean profileControl(String process, int userId, boolean start, 15767 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 15768 15769 try { 15770 synchronized (this) { 15771 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15772 // its own permission. 15773 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15774 != PackageManager.PERMISSION_GRANTED) { 15775 throw new SecurityException("Requires permission " 15776 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15777 } 15778 15779 if (start && fd == null) { 15780 throw new IllegalArgumentException("null fd"); 15781 } 15782 15783 ProcessRecord proc = null; 15784 if (process != null) { 15785 proc = findProcessLocked(process, userId, "profileControl"); 15786 } 15787 15788 if (start && (proc == null || proc.thread == null)) { 15789 throw new IllegalArgumentException("Unknown process: " + process); 15790 } 15791 15792 if (start) { 15793 stopProfilerLocked(null, null, 0); 15794 setProfileApp(proc.info, proc.processName, path, fd, false); 15795 mProfileProc = proc; 15796 mProfileType = profileType; 15797 try { 15798 fd = fd.dup(); 15799 } catch (IOException e) { 15800 fd = null; 15801 } 15802 proc.thread.profilerControl(start, path, fd, profileType); 15803 fd = null; 15804 mProfileFd = null; 15805 } else { 15806 stopProfilerLocked(proc, path, profileType); 15807 if (fd != null) { 15808 try { 15809 fd.close(); 15810 } catch (IOException e) { 15811 } 15812 } 15813 } 15814 15815 return true; 15816 } 15817 } catch (RemoteException e) { 15818 throw new IllegalStateException("Process disappeared"); 15819 } finally { 15820 if (fd != null) { 15821 try { 15822 fd.close(); 15823 } catch (IOException e) { 15824 } 15825 } 15826 } 15827 } 15828 15829 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 15830 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15831 userId, true, true, callName, null); 15832 ProcessRecord proc = null; 15833 try { 15834 int pid = Integer.parseInt(process); 15835 synchronized (mPidsSelfLocked) { 15836 proc = mPidsSelfLocked.get(pid); 15837 } 15838 } catch (NumberFormatException e) { 15839 } 15840 15841 if (proc == null) { 15842 ArrayMap<String, SparseArray<ProcessRecord>> all 15843 = mProcessNames.getMap(); 15844 SparseArray<ProcessRecord> procs = all.get(process); 15845 if (procs != null && procs.size() > 0) { 15846 proc = procs.valueAt(0); 15847 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 15848 for (int i=1; i<procs.size(); i++) { 15849 ProcessRecord thisProc = procs.valueAt(i); 15850 if (thisProc.userId == userId) { 15851 proc = thisProc; 15852 break; 15853 } 15854 } 15855 } 15856 } 15857 } 15858 15859 return proc; 15860 } 15861 15862 public boolean dumpHeap(String process, int userId, boolean managed, 15863 String path, ParcelFileDescriptor fd) throws RemoteException { 15864 15865 try { 15866 synchronized (this) { 15867 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15868 // its own permission (same as profileControl). 15869 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15870 != PackageManager.PERMISSION_GRANTED) { 15871 throw new SecurityException("Requires permission " 15872 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15873 } 15874 15875 if (fd == null) { 15876 throw new IllegalArgumentException("null fd"); 15877 } 15878 15879 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 15880 if (proc == null || proc.thread == null) { 15881 throw new IllegalArgumentException("Unknown process: " + process); 15882 } 15883 15884 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 15885 if (!isDebuggable) { 15886 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 15887 throw new SecurityException("Process not debuggable: " + proc); 15888 } 15889 } 15890 15891 proc.thread.dumpHeap(managed, path, fd); 15892 fd = null; 15893 return true; 15894 } 15895 } catch (RemoteException e) { 15896 throw new IllegalStateException("Process disappeared"); 15897 } finally { 15898 if (fd != null) { 15899 try { 15900 fd.close(); 15901 } catch (IOException e) { 15902 } 15903 } 15904 } 15905 } 15906 15907 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 15908 public void monitor() { 15909 synchronized (this) { } 15910 } 15911 15912 void onCoreSettingsChange(Bundle settings) { 15913 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 15914 ProcessRecord processRecord = mLruProcesses.get(i); 15915 try { 15916 if (processRecord.thread != null) { 15917 processRecord.thread.setCoreSettings(settings); 15918 } 15919 } catch (RemoteException re) { 15920 /* ignore */ 15921 } 15922 } 15923 } 15924 15925 // Multi-user methods 15926 15927 @Override 15928 public boolean switchUser(final int userId) { 15929 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 15930 != PackageManager.PERMISSION_GRANTED) { 15931 String msg = "Permission Denial: switchUser() from pid=" 15932 + Binder.getCallingPid() 15933 + ", uid=" + Binder.getCallingUid() 15934 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 15935 Slog.w(TAG, msg); 15936 throw new SecurityException(msg); 15937 } 15938 15939 final long ident = Binder.clearCallingIdentity(); 15940 try { 15941 synchronized (this) { 15942 final int oldUserId = mCurrentUserId; 15943 if (oldUserId == userId) { 15944 return true; 15945 } 15946 15947 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 15948 if (userInfo == null) { 15949 Slog.w(TAG, "No user info for user #" + userId); 15950 return false; 15951 } 15952 15953 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 15954 R.anim.screen_user_enter); 15955 15956 boolean needStart = false; 15957 15958 // If the user we are switching to is not currently started, then 15959 // we need to start it now. 15960 if (mStartedUsers.get(userId) == null) { 15961 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 15962 updateStartedUserArrayLocked(); 15963 needStart = true; 15964 } 15965 15966 mCurrentUserId = userId; 15967 final Integer userIdInt = Integer.valueOf(userId); 15968 mUserLru.remove(userIdInt); 15969 mUserLru.add(userIdInt); 15970 15971 mWindowManager.setCurrentUser(userId); 15972 15973 // Once the internal notion of the active user has switched, we lock the device 15974 // with the option to show the user switcher on the keyguard. 15975 mWindowManager.lockNow(null); 15976 15977 final UserStartedState uss = mStartedUsers.get(userId); 15978 15979 // Make sure user is in the started state. If it is currently 15980 // stopping, we need to knock that off. 15981 if (uss.mState == UserStartedState.STATE_STOPPING) { 15982 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 15983 // so we can just fairly silently bring the user back from 15984 // the almost-dead. 15985 uss.mState = UserStartedState.STATE_RUNNING; 15986 updateStartedUserArrayLocked(); 15987 needStart = true; 15988 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 15989 // This means ACTION_SHUTDOWN has been sent, so we will 15990 // need to treat this as a new boot of the user. 15991 uss.mState = UserStartedState.STATE_BOOTING; 15992 updateStartedUserArrayLocked(); 15993 needStart = true; 15994 } 15995 15996 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 15997 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 15998 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 15999 oldUserId, userId, uss)); 16000 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16001 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16002 if (needStart) { 16003 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16004 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16005 | Intent.FLAG_RECEIVER_FOREGROUND); 16006 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16007 broadcastIntentLocked(null, null, intent, 16008 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16009 false, false, MY_PID, Process.SYSTEM_UID, userId); 16010 } 16011 16012 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16013 if (userId != 0) { 16014 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16015 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16016 broadcastIntentLocked(null, null, intent, null, 16017 new IIntentReceiver.Stub() { 16018 public void performReceive(Intent intent, int resultCode, 16019 String data, Bundle extras, boolean ordered, 16020 boolean sticky, int sendingUser) { 16021 userInitialized(uss, userId); 16022 } 16023 }, 0, null, null, null, AppOpsManager.OP_NONE, 16024 true, false, MY_PID, Process.SYSTEM_UID, 16025 userId); 16026 uss.initializing = true; 16027 } else { 16028 getUserManagerLocked().makeInitialized(userInfo.id); 16029 } 16030 } 16031 16032 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16033 if (homeInFront) { 16034 startHomeActivityLocked(userId); 16035 } else { 16036 mStackSupervisor.resumeTopActivitiesLocked(); 16037 } 16038 16039 EventLogTags.writeAmSwitchUser(userId); 16040 getUserManagerLocked().userForeground(userId); 16041 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16042 if (needStart) { 16043 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16044 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16045 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16046 broadcastIntentLocked(null, null, intent, 16047 null, new IIntentReceiver.Stub() { 16048 @Override 16049 public void performReceive(Intent intent, int resultCode, String data, 16050 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16051 throws RemoteException { 16052 } 16053 }, 0, null, null, 16054 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16055 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16056 } 16057 } 16058 } finally { 16059 Binder.restoreCallingIdentity(ident); 16060 } 16061 16062 return true; 16063 } 16064 16065 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16066 long ident = Binder.clearCallingIdentity(); 16067 try { 16068 Intent intent; 16069 if (oldUserId >= 0) { 16070 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16071 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16072 | Intent.FLAG_RECEIVER_FOREGROUND); 16073 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16074 broadcastIntentLocked(null, null, intent, 16075 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16076 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16077 } 16078 if (newUserId >= 0) { 16079 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16080 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16081 | Intent.FLAG_RECEIVER_FOREGROUND); 16082 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16083 broadcastIntentLocked(null, null, intent, 16084 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16085 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16086 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16087 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16088 | Intent.FLAG_RECEIVER_FOREGROUND); 16089 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16090 broadcastIntentLocked(null, null, intent, 16091 null, null, 0, null, null, 16092 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16093 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16094 } 16095 } finally { 16096 Binder.restoreCallingIdentity(ident); 16097 } 16098 } 16099 16100 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16101 final int newUserId) { 16102 final int N = mUserSwitchObservers.beginBroadcast(); 16103 if (N > 0) { 16104 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16105 int mCount = 0; 16106 @Override 16107 public void sendResult(Bundle data) throws RemoteException { 16108 synchronized (ActivityManagerService.this) { 16109 if (mCurUserSwitchCallback == this) { 16110 mCount++; 16111 if (mCount == N) { 16112 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16113 } 16114 } 16115 } 16116 } 16117 }; 16118 synchronized (this) { 16119 uss.switching = true; 16120 mCurUserSwitchCallback = callback; 16121 } 16122 for (int i=0; i<N; i++) { 16123 try { 16124 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16125 newUserId, callback); 16126 } catch (RemoteException e) { 16127 } 16128 } 16129 } else { 16130 synchronized (this) { 16131 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16132 } 16133 } 16134 mUserSwitchObservers.finishBroadcast(); 16135 } 16136 16137 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16138 synchronized (this) { 16139 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16140 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16141 } 16142 } 16143 16144 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16145 mCurUserSwitchCallback = null; 16146 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16147 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16148 oldUserId, newUserId, uss)); 16149 } 16150 16151 void userInitialized(UserStartedState uss, int newUserId) { 16152 completeSwitchAndInitalize(uss, newUserId, true, false); 16153 } 16154 16155 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16156 completeSwitchAndInitalize(uss, newUserId, false, true); 16157 } 16158 16159 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16160 boolean clearInitializing, boolean clearSwitching) { 16161 boolean unfrozen = false; 16162 synchronized (this) { 16163 if (clearInitializing) { 16164 uss.initializing = false; 16165 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16166 } 16167 if (clearSwitching) { 16168 uss.switching = false; 16169 } 16170 if (!uss.switching && !uss.initializing) { 16171 mWindowManager.stopFreezingScreen(); 16172 unfrozen = true; 16173 } 16174 } 16175 if (unfrozen) { 16176 final int N = mUserSwitchObservers.beginBroadcast(); 16177 for (int i=0; i<N; i++) { 16178 try { 16179 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16180 } catch (RemoteException e) { 16181 } 16182 } 16183 mUserSwitchObservers.finishBroadcast(); 16184 } 16185 } 16186 16187 void finishUserSwitch(UserStartedState uss) { 16188 synchronized (this) { 16189 if (uss.mState == UserStartedState.STATE_BOOTING 16190 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16191 uss.mState = UserStartedState.STATE_RUNNING; 16192 final int userId = uss.mHandle.getIdentifier(); 16193 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16194 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16195 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16196 broadcastIntentLocked(null, null, intent, 16197 null, null, 0, null, null, 16198 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16199 true, false, MY_PID, Process.SYSTEM_UID, userId); 16200 } 16201 int num = mUserLru.size(); 16202 int i = 0; 16203 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16204 Integer oldUserId = mUserLru.get(i); 16205 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16206 if (oldUss == null) { 16207 // Shouldn't happen, but be sane if it does. 16208 mUserLru.remove(i); 16209 num--; 16210 continue; 16211 } 16212 if (oldUss.mState == UserStartedState.STATE_STOPPING 16213 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16214 // This user is already stopping, doesn't count. 16215 num--; 16216 i++; 16217 continue; 16218 } 16219 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16220 // Owner and current can't be stopped, but count as running. 16221 i++; 16222 continue; 16223 } 16224 // This is a user to be stopped. 16225 stopUserLocked(oldUserId, null); 16226 num--; 16227 i++; 16228 } 16229 } 16230 } 16231 16232 @Override 16233 public int stopUser(final int userId, final IStopUserCallback callback) { 16234 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16235 != PackageManager.PERMISSION_GRANTED) { 16236 String msg = "Permission Denial: switchUser() from pid=" 16237 + Binder.getCallingPid() 16238 + ", uid=" + Binder.getCallingUid() 16239 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16240 Slog.w(TAG, msg); 16241 throw new SecurityException(msg); 16242 } 16243 if (userId <= 0) { 16244 throw new IllegalArgumentException("Can't stop primary user " + userId); 16245 } 16246 synchronized (this) { 16247 return stopUserLocked(userId, callback); 16248 } 16249 } 16250 16251 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16252 if (mCurrentUserId == userId) { 16253 return ActivityManager.USER_OP_IS_CURRENT; 16254 } 16255 16256 final UserStartedState uss = mStartedUsers.get(userId); 16257 if (uss == null) { 16258 // User is not started, nothing to do... but we do need to 16259 // callback if requested. 16260 if (callback != null) { 16261 mHandler.post(new Runnable() { 16262 @Override 16263 public void run() { 16264 try { 16265 callback.userStopped(userId); 16266 } catch (RemoteException e) { 16267 } 16268 } 16269 }); 16270 } 16271 return ActivityManager.USER_OP_SUCCESS; 16272 } 16273 16274 if (callback != null) { 16275 uss.mStopCallbacks.add(callback); 16276 } 16277 16278 if (uss.mState != UserStartedState.STATE_STOPPING 16279 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16280 uss.mState = UserStartedState.STATE_STOPPING; 16281 updateStartedUserArrayLocked(); 16282 16283 long ident = Binder.clearCallingIdentity(); 16284 try { 16285 // We are going to broadcast ACTION_USER_STOPPING and then 16286 // once that is done send a final ACTION_SHUTDOWN and then 16287 // stop the user. 16288 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16289 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16290 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16291 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16292 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16293 // This is the result receiver for the final shutdown broadcast. 16294 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16295 @Override 16296 public void performReceive(Intent intent, int resultCode, String data, 16297 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16298 finishUserStop(uss); 16299 } 16300 }; 16301 // This is the result receiver for the initial stopping broadcast. 16302 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16303 @Override 16304 public void performReceive(Intent intent, int resultCode, String data, 16305 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16306 // On to the next. 16307 synchronized (ActivityManagerService.this) { 16308 if (uss.mState != UserStartedState.STATE_STOPPING) { 16309 // Whoops, we are being started back up. Abort, abort! 16310 return; 16311 } 16312 uss.mState = UserStartedState.STATE_SHUTDOWN; 16313 } 16314 broadcastIntentLocked(null, null, shutdownIntent, 16315 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16316 true, false, MY_PID, Process.SYSTEM_UID, userId); 16317 } 16318 }; 16319 // Kick things off. 16320 broadcastIntentLocked(null, null, stoppingIntent, 16321 null, stoppingReceiver, 0, null, null, 16322 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16323 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16324 } finally { 16325 Binder.restoreCallingIdentity(ident); 16326 } 16327 } 16328 16329 return ActivityManager.USER_OP_SUCCESS; 16330 } 16331 16332 void finishUserStop(UserStartedState uss) { 16333 final int userId = uss.mHandle.getIdentifier(); 16334 boolean stopped; 16335 ArrayList<IStopUserCallback> callbacks; 16336 synchronized (this) { 16337 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16338 if (mStartedUsers.get(userId) != uss) { 16339 stopped = false; 16340 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16341 stopped = false; 16342 } else { 16343 stopped = true; 16344 // User can no longer run. 16345 mStartedUsers.remove(userId); 16346 mUserLru.remove(Integer.valueOf(userId)); 16347 updateStartedUserArrayLocked(); 16348 16349 // Clean up all state and processes associated with the user. 16350 // Kill all the processes for the user. 16351 forceStopUserLocked(userId, "finish user"); 16352 } 16353 } 16354 16355 for (int i=0; i<callbacks.size(); i++) { 16356 try { 16357 if (stopped) callbacks.get(i).userStopped(userId); 16358 else callbacks.get(i).userStopAborted(userId); 16359 } catch (RemoteException e) { 16360 } 16361 } 16362 16363 mStackSupervisor.removeUserLocked(userId); 16364 } 16365 16366 @Override 16367 public UserInfo getCurrentUser() { 16368 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16369 != PackageManager.PERMISSION_GRANTED) && ( 16370 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16371 != PackageManager.PERMISSION_GRANTED)) { 16372 String msg = "Permission Denial: getCurrentUser() from pid=" 16373 + Binder.getCallingPid() 16374 + ", uid=" + Binder.getCallingUid() 16375 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16376 Slog.w(TAG, msg); 16377 throw new SecurityException(msg); 16378 } 16379 synchronized (this) { 16380 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16381 } 16382 } 16383 16384 int getCurrentUserIdLocked() { 16385 return mCurrentUserId; 16386 } 16387 16388 @Override 16389 public boolean isUserRunning(int userId, boolean orStopped) { 16390 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16391 != PackageManager.PERMISSION_GRANTED) { 16392 String msg = "Permission Denial: isUserRunning() from pid=" 16393 + Binder.getCallingPid() 16394 + ", uid=" + Binder.getCallingUid() 16395 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16396 Slog.w(TAG, msg); 16397 throw new SecurityException(msg); 16398 } 16399 synchronized (this) { 16400 return isUserRunningLocked(userId, orStopped); 16401 } 16402 } 16403 16404 boolean isUserRunningLocked(int userId, boolean orStopped) { 16405 UserStartedState state = mStartedUsers.get(userId); 16406 if (state == null) { 16407 return false; 16408 } 16409 if (orStopped) { 16410 return true; 16411 } 16412 return state.mState != UserStartedState.STATE_STOPPING 16413 && state.mState != UserStartedState.STATE_SHUTDOWN; 16414 } 16415 16416 @Override 16417 public int[] getRunningUserIds() { 16418 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16419 != PackageManager.PERMISSION_GRANTED) { 16420 String msg = "Permission Denial: isUserRunning() from pid=" 16421 + Binder.getCallingPid() 16422 + ", uid=" + Binder.getCallingUid() 16423 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16424 Slog.w(TAG, msg); 16425 throw new SecurityException(msg); 16426 } 16427 synchronized (this) { 16428 return mStartedUserArray; 16429 } 16430 } 16431 16432 private void updateStartedUserArrayLocked() { 16433 int num = 0; 16434 for (int i=0; i<mStartedUsers.size(); i++) { 16435 UserStartedState uss = mStartedUsers.valueAt(i); 16436 // This list does not include stopping users. 16437 if (uss.mState != UserStartedState.STATE_STOPPING 16438 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16439 num++; 16440 } 16441 } 16442 mStartedUserArray = new int[num]; 16443 num = 0; 16444 for (int i=0; i<mStartedUsers.size(); i++) { 16445 UserStartedState uss = mStartedUsers.valueAt(i); 16446 if (uss.mState != UserStartedState.STATE_STOPPING 16447 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16448 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16449 num++; 16450 } 16451 } 16452 } 16453 16454 @Override 16455 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16456 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16457 != PackageManager.PERMISSION_GRANTED) { 16458 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16459 + Binder.getCallingPid() 16460 + ", uid=" + Binder.getCallingUid() 16461 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16462 Slog.w(TAG, msg); 16463 throw new SecurityException(msg); 16464 } 16465 16466 mUserSwitchObservers.register(observer); 16467 } 16468 16469 @Override 16470 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16471 mUserSwitchObservers.unregister(observer); 16472 } 16473 16474 private boolean userExists(int userId) { 16475 if (userId == 0) { 16476 return true; 16477 } 16478 UserManagerService ums = getUserManagerLocked(); 16479 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16480 } 16481 16482 int[] getUsersLocked() { 16483 UserManagerService ums = getUserManagerLocked(); 16484 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16485 } 16486 16487 UserManagerService getUserManagerLocked() { 16488 if (mUserManager == null) { 16489 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16490 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16491 } 16492 return mUserManager; 16493 } 16494 16495 private int applyUserId(int uid, int userId) { 16496 return UserHandle.getUid(userId, uid); 16497 } 16498 16499 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16500 if (info == null) return null; 16501 ApplicationInfo newInfo = new ApplicationInfo(info); 16502 newInfo.uid = applyUserId(info.uid, userId); 16503 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16504 + info.packageName; 16505 return newInfo; 16506 } 16507 16508 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16509 if (aInfo == null 16510 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16511 return aInfo; 16512 } 16513 16514 ActivityInfo info = new ActivityInfo(aInfo); 16515 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16516 return info; 16517 } 16518} 16519