ActivityManagerService.java revision 9358dcca6f3d33d1e3f976a4c3a5f61e103930dc
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.os.BatteryStats; 36import android.util.ArrayMap; 37import com.android.internal.R; 38import com.android.internal.annotations.GuardedBy; 39import com.android.internal.app.IAppOpsService; 40import com.android.internal.app.ProcessMap; 41import com.android.internal.app.ProcessStats; 42import com.android.internal.os.BackgroundThread; 43import com.android.internal.os.BatteryStatsImpl; 44import com.android.internal.os.ProcessCpuTracker; 45import com.android.internal.os.TransferPipe; 46import com.android.internal.util.FastPrintWriter; 47import com.android.internal.util.FastXmlSerializer; 48import com.android.internal.util.MemInfoReader; 49import com.android.internal.util.Preconditions; 50import com.android.server.AppOpsService; 51import com.android.server.AttributeCache; 52import com.android.server.IntentResolver; 53import com.android.server.ServiceThread; 54import com.android.server.SystemService; 55import com.android.server.Watchdog; 56import com.android.server.am.ActivityStack.ActivityState; 57import com.android.server.firewall.IntentFirewall; 58import com.android.server.pm.UserManagerService; 59import com.android.server.wm.AppTransition; 60import com.android.server.wm.WindowManagerService; 61import com.google.android.collect.Lists; 62import com.google.android.collect.Maps; 63 64import dalvik.system.Zygote; 65 66import libcore.io.IoUtils; 67 68import org.xmlpull.v1.XmlPullParser; 69import org.xmlpull.v1.XmlPullParserException; 70import org.xmlpull.v1.XmlSerializer; 71 72import android.app.Activity; 73import android.app.ActivityManager; 74import android.app.ActivityManager.RunningTaskInfo; 75import android.app.ActivityManager.StackInfo; 76import android.app.ActivityManagerNative; 77import android.app.ActivityOptions; 78import android.app.ActivityThread; 79import android.app.AlertDialog; 80import android.app.AppGlobals; 81import android.app.ApplicationErrorReport; 82import android.app.Dialog; 83import android.app.IActivityController; 84import android.app.IApplicationThread; 85import android.app.IInstrumentationWatcher; 86import android.app.INotificationManager; 87import android.app.IProcessObserver; 88import android.app.IServiceConnection; 89import android.app.IStopUserCallback; 90import android.app.IThumbnailReceiver; 91import android.app.IUiAutomationConnection; 92import android.app.IUserSwitchObserver; 93import android.app.Instrumentation; 94import android.app.Notification; 95import android.app.NotificationManager; 96import android.app.PendingIntent; 97import android.app.backup.IBackupManager; 98import android.content.ActivityNotFoundException; 99import android.content.BroadcastReceiver; 100import android.content.ClipData; 101import android.content.ComponentCallbacks2; 102import android.content.ComponentName; 103import android.content.ContentProvider; 104import android.content.ContentResolver; 105import android.content.Context; 106import android.content.DialogInterface; 107import android.content.IContentProvider; 108import android.content.IIntentReceiver; 109import android.content.IIntentSender; 110import android.content.Intent; 111import android.content.IntentFilter; 112import android.content.IntentSender; 113import android.content.pm.ActivityInfo; 114import android.content.pm.ApplicationInfo; 115import android.content.pm.ConfigurationInfo; 116import android.content.pm.IPackageDataObserver; 117import android.content.pm.IPackageManager; 118import android.content.pm.InstrumentationInfo; 119import android.content.pm.PackageInfo; 120import android.content.pm.PackageManager; 121import android.content.pm.ParceledListSlice; 122import android.content.pm.UserInfo; 123import android.content.pm.PackageManager.NameNotFoundException; 124import android.content.pm.PathPermission; 125import android.content.pm.ProviderInfo; 126import android.content.pm.ResolveInfo; 127import android.content.pm.ServiceInfo; 128import android.content.res.CompatibilityInfo; 129import android.content.res.Configuration; 130import android.graphics.Bitmap; 131import android.net.Proxy; 132import android.net.ProxyProperties; 133import android.net.Uri; 134import android.os.Binder; 135import android.os.Build; 136import android.os.Bundle; 137import android.os.Debug; 138import android.os.DropBoxManager; 139import android.os.Environment; 140import android.os.FactoryTest; 141import android.os.FileObserver; 142import android.os.FileUtils; 143import android.os.Handler; 144import android.os.IBinder; 145import android.os.IPermissionController; 146import android.os.IRemoteCallback; 147import android.os.IUserManager; 148import android.os.Looper; 149import android.os.Message; 150import android.os.Parcel; 151import android.os.ParcelFileDescriptor; 152import android.os.Process; 153import android.os.RemoteCallbackList; 154import android.os.RemoteException; 155import android.os.SELinux; 156import android.os.ServiceManager; 157import android.os.StrictMode; 158import android.os.SystemClock; 159import android.os.SystemProperties; 160import android.os.UpdateLock; 161import android.os.UserHandle; 162import android.provider.Settings; 163import android.text.format.DateUtils; 164import android.text.format.Time; 165import android.util.AtomicFile; 166import android.util.EventLog; 167import android.util.Log; 168import android.util.Pair; 169import android.util.PrintWriterPrinter; 170import android.util.Slog; 171import android.util.SparseArray; 172import android.util.TimeUtils; 173import android.util.Xml; 174import android.view.Gravity; 175import android.view.LayoutInflater; 176import android.view.View; 177import android.view.WindowManager; 178 179import java.io.BufferedInputStream; 180import java.io.BufferedOutputStream; 181import java.io.DataInputStream; 182import java.io.DataOutputStream; 183import java.io.File; 184import java.io.FileDescriptor; 185import java.io.FileInputStream; 186import java.io.FileNotFoundException; 187import java.io.FileOutputStream; 188import java.io.IOException; 189import java.io.InputStreamReader; 190import java.io.PrintWriter; 191import java.io.StringWriter; 192import java.lang.ref.WeakReference; 193import java.util.ArrayList; 194import java.util.Arrays; 195import java.util.Collections; 196import java.util.Comparator; 197import java.util.HashMap; 198import java.util.HashSet; 199import java.util.Iterator; 200import java.util.List; 201import java.util.Locale; 202import java.util.Map; 203import java.util.Set; 204import java.util.concurrent.atomic.AtomicBoolean; 205import java.util.concurrent.atomic.AtomicLong; 206 207public final class ActivityManagerService extends ActivityManagerNative 208 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 209 private static final String USER_DATA_DIR = "/data/user/"; 210 static final String TAG = "ActivityManager"; 211 static final String TAG_MU = "ActivityManagerServiceMU"; 212 static final boolean DEBUG = false; 213 static final boolean localLOGV = DEBUG; 214 static final boolean DEBUG_BACKUP = localLOGV || false; 215 static final boolean DEBUG_BROADCAST = localLOGV || false; 216 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 217 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 218 static final boolean DEBUG_CLEANUP = localLOGV || false; 219 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 220 static final boolean DEBUG_FOCUS = false; 221 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 222 static final boolean DEBUG_MU = localLOGV || false; 223 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 224 static final boolean DEBUG_LRU = localLOGV || false; 225 static final boolean DEBUG_PAUSE = localLOGV || false; 226 static final boolean DEBUG_POWER = localLOGV || false; 227 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 228 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 229 static final boolean DEBUG_PROCESSES = localLOGV || false; 230 static final boolean DEBUG_PROVIDER = localLOGV || false; 231 static final boolean DEBUG_RESULTS = localLOGV || false; 232 static final boolean DEBUG_SERVICE = localLOGV || false; 233 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 234 static final boolean DEBUG_STACK = localLOGV || false; 235 static final boolean DEBUG_SWITCH = localLOGV || false; 236 static final boolean DEBUG_TASKS = localLOGV || false; 237 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 238 static final boolean DEBUG_TRANSITION = localLOGV || false; 239 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 240 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 241 static final boolean DEBUG_VISBILITY = localLOGV || false; 242 static final boolean DEBUG_PSS = localLOGV || false; 243 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 244 static final boolean VALIDATE_TOKENS = false; 245 static final boolean SHOW_ACTIVITY_START_TIME = true; 246 247 // Control over CPU and battery monitoring. 248 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 249 static final boolean MONITOR_CPU_USAGE = true; 250 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 251 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 252 static final boolean MONITOR_THREAD_CPU_USAGE = false; 253 254 // The flags that are set for all calls we make to the package manager. 255 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 256 257 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 258 259 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 260 261 // Maximum number of recent tasks that we can remember. 262 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 263 264 // Amount of time after a call to stopAppSwitches() during which we will 265 // prevent further untrusted switches from happening. 266 static final long APP_SWITCH_DELAY_TIME = 5*1000; 267 268 // How long we wait for a launched process to attach to the activity manager 269 // before we decide it's never going to come up for real. 270 static final int PROC_START_TIMEOUT = 10*1000; 271 272 // How long we wait for a launched process to attach to the activity manager 273 // before we decide it's never going to come up for real, when the process was 274 // started with a wrapper for instrumentation (such as Valgrind) because it 275 // could take much longer than usual. 276 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 277 278 // How long to wait after going idle before forcing apps to GC. 279 static final int GC_TIMEOUT = 5*1000; 280 281 // The minimum amount of time between successive GC requests for a process. 282 static final int GC_MIN_INTERVAL = 60*1000; 283 284 // The minimum amount of time between successive PSS requests for a process. 285 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 286 287 // The minimum amount of time between successive PSS requests for a process 288 // when the request is due to the memory state being lowered. 289 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 290 291 // The rate at which we check for apps using excessive power -- 15 mins. 292 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 293 294 // The minimum sample duration we will allow before deciding we have 295 // enough data on wake locks to start killing things. 296 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 297 298 // The minimum sample duration we will allow before deciding we have 299 // enough data on CPU usage to start killing things. 300 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 301 302 // How long we allow a receiver to run before giving up on it. 303 static final int BROADCAST_FG_TIMEOUT = 10*1000; 304 static final int BROADCAST_BG_TIMEOUT = 60*1000; 305 306 // How long we wait until we timeout on key dispatching. 307 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 308 309 // How long we wait until we timeout on key dispatching during instrumentation. 310 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 311 312 // Amount of time we wait for observers to handle a user switch before 313 // giving up on them and unfreezing the screen. 314 static final int USER_SWITCH_TIMEOUT = 2*1000; 315 316 // Maximum number of users we allow to be running at a time. 317 static final int MAX_RUNNING_USERS = 3; 318 319 // How long to wait in getAssistContextExtras for the activity and foreground services 320 // to respond with the result. 321 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 322 323 // Maximum number of persisted Uri grants a package is allowed 324 static final int MAX_PERSISTED_URI_GRANTS = 128; 325 326 static final int MY_PID = Process.myPid(); 327 328 static final String[] EMPTY_STRING_ARRAY = new String[0]; 329 330 // How many bytes to write into the dropbox log before truncating 331 static final int DROPBOX_MAX_SIZE = 256 * 1024; 332 333 /** Run all ActivityStacks through this */ 334 ActivityStackSupervisor mStackSupervisor; 335 336 public IntentFirewall mIntentFirewall; 337 338 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 339 // default actuion automatically. Important for devices without direct input 340 // devices. 341 private boolean mShowDialogs = true; 342 343 /** 344 * Description of a request to start a new activity, which has been held 345 * due to app switches being disabled. 346 */ 347 static class PendingActivityLaunch { 348 final ActivityRecord r; 349 final ActivityRecord sourceRecord; 350 final int startFlags; 351 final ActivityStack stack; 352 353 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 354 int _startFlags, ActivityStack _stack) { 355 r = _r; 356 sourceRecord = _sourceRecord; 357 startFlags = _startFlags; 358 stack = _stack; 359 } 360 } 361 362 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 363 = new ArrayList<PendingActivityLaunch>(); 364 365 BroadcastQueue mFgBroadcastQueue; 366 BroadcastQueue mBgBroadcastQueue; 367 // Convenient for easy iteration over the queues. Foreground is first 368 // so that dispatch of foreground broadcasts gets precedence. 369 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 370 371 BroadcastQueue broadcastQueueForIntent(Intent intent) { 372 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 373 if (DEBUG_BACKGROUND_BROADCAST) { 374 Slog.i(TAG, "Broadcast intent " + intent + " on " 375 + (isFg ? "foreground" : "background") 376 + " queue"); 377 } 378 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 379 } 380 381 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 382 for (BroadcastQueue queue : mBroadcastQueues) { 383 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 384 if (r != null) { 385 return r; 386 } 387 } 388 return null; 389 } 390 391 /** 392 * Activity we have told the window manager to have key focus. 393 */ 394 ActivityRecord mFocusedActivity = null; 395 396 /** 397 * List of intents that were used to start the most recent tasks. 398 */ 399 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 400 401 public class PendingAssistExtras extends Binder implements Runnable { 402 public final ActivityRecord activity; 403 public boolean haveResult = false; 404 public Bundle result = null; 405 public PendingAssistExtras(ActivityRecord _activity) { 406 activity = _activity; 407 } 408 @Override 409 public void run() { 410 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 411 synchronized (this) { 412 haveResult = true; 413 notifyAll(); 414 } 415 } 416 } 417 418 final ArrayList<PendingAssistExtras> mPendingAssistExtras 419 = new ArrayList<PendingAssistExtras>(); 420 421 /** 422 * Process management. 423 */ 424 final ProcessList mProcessList = new ProcessList(); 425 426 /** 427 * All of the applications we currently have running organized by name. 428 * The keys are strings of the application package name (as 429 * returned by the package manager), and the keys are ApplicationRecord 430 * objects. 431 */ 432 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 433 434 /** 435 * Tracking long-term execution of processes to look for abuse and other 436 * bad app behavior. 437 */ 438 final ProcessStatsService mProcessStats; 439 440 /** 441 * The currently running isolated processes. 442 */ 443 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 444 445 /** 446 * Counter for assigning isolated process uids, to avoid frequently reusing the 447 * same ones. 448 */ 449 int mNextIsolatedProcessUid = 0; 450 451 /** 452 * The currently running heavy-weight process, if any. 453 */ 454 ProcessRecord mHeavyWeightProcess = null; 455 456 /** 457 * The last time that various processes have crashed. 458 */ 459 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 460 461 /** 462 * Information about a process that is currently marked as bad. 463 */ 464 static final class BadProcessInfo { 465 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 466 this.time = time; 467 this.shortMsg = shortMsg; 468 this.longMsg = longMsg; 469 this.stack = stack; 470 } 471 472 final long time; 473 final String shortMsg; 474 final String longMsg; 475 final String stack; 476 } 477 478 /** 479 * Set of applications that we consider to be bad, and will reject 480 * incoming broadcasts from (which the user has no control over). 481 * Processes are added to this set when they have crashed twice within 482 * a minimum amount of time; they are removed from it when they are 483 * later restarted (hopefully due to some user action). The value is the 484 * time it was added to the list. 485 */ 486 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 487 488 /** 489 * All of the processes we currently have running organized by pid. 490 * The keys are the pid running the application. 491 * 492 * <p>NOTE: This object is protected by its own lock, NOT the global 493 * activity manager lock! 494 */ 495 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 496 497 /** 498 * All of the processes that have been forced to be foreground. The key 499 * is the pid of the caller who requested it (we hold a death 500 * link on it). 501 */ 502 abstract class ForegroundToken implements IBinder.DeathRecipient { 503 int pid; 504 IBinder token; 505 } 506 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 507 508 /** 509 * List of records for processes that someone had tried to start before the 510 * system was ready. We don't start them at that point, but ensure they 511 * are started by the time booting is complete. 512 */ 513 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 514 515 /** 516 * List of persistent applications that are in the process 517 * of being started. 518 */ 519 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 520 521 /** 522 * Processes that are being forcibly torn down. 523 */ 524 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 525 526 /** 527 * List of running applications, sorted by recent usage. 528 * The first entry in the list is the least recently used. 529 */ 530 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 531 532 /** 533 * Where in mLruProcesses that the processes hosting activities start. 534 */ 535 int mLruProcessActivityStart = 0; 536 537 /** 538 * Where in mLruProcesses that the processes hosting services start. 539 * This is after (lower index) than mLruProcessesActivityStart. 540 */ 541 int mLruProcessServiceStart = 0; 542 543 /** 544 * List of processes that should gc as soon as things are idle. 545 */ 546 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 547 548 /** 549 * Processes we want to collect PSS data from. 550 */ 551 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 552 553 /** 554 * Last time we requested PSS data of all processes. 555 */ 556 long mLastFullPssTime = SystemClock.uptimeMillis(); 557 558 /** 559 * This is the process holding what we currently consider to be 560 * the "home" activity. 561 */ 562 ProcessRecord mHomeProcess; 563 564 /** 565 * This is the process holding the activity the user last visited that 566 * is in a different process from the one they are currently in. 567 */ 568 ProcessRecord mPreviousProcess; 569 570 /** 571 * The time at which the previous process was last visible. 572 */ 573 long mPreviousProcessVisibleTime; 574 575 /** 576 * Which uses have been started, so are allowed to run code. 577 */ 578 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 579 580 /** 581 * LRU list of history of current users. Most recently current is at the end. 582 */ 583 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 584 585 /** 586 * Constant array of the users that are currently started. 587 */ 588 int[] mStartedUserArray = new int[] { 0 }; 589 590 /** 591 * Registered observers of the user switching mechanics. 592 */ 593 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 594 = new RemoteCallbackList<IUserSwitchObserver>(); 595 596 /** 597 * Currently active user switch. 598 */ 599 Object mCurUserSwitchCallback; 600 601 /** 602 * Packages that the user has asked to have run in screen size 603 * compatibility mode instead of filling the screen. 604 */ 605 final CompatModePackages mCompatModePackages; 606 607 /** 608 * Set of IntentSenderRecord objects that are currently active. 609 */ 610 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 611 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 612 613 /** 614 * Fingerprints (hashCode()) of stack traces that we've 615 * already logged DropBox entries for. Guarded by itself. If 616 * something (rogue user app) forces this over 617 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 618 */ 619 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 620 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 621 622 /** 623 * Strict Mode background batched logging state. 624 * 625 * The string buffer is guarded by itself, and its lock is also 626 * used to determine if another batched write is already 627 * in-flight. 628 */ 629 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 630 631 /** 632 * Keeps track of all IIntentReceivers that have been registered for 633 * broadcasts. Hash keys are the receiver IBinder, hash value is 634 * a ReceiverList. 635 */ 636 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 637 new HashMap<IBinder, ReceiverList>(); 638 639 /** 640 * Resolver for broadcast intents to registered receivers. 641 * Holds BroadcastFilter (subclass of IntentFilter). 642 */ 643 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 644 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 645 @Override 646 protected boolean allowFilterResult( 647 BroadcastFilter filter, List<BroadcastFilter> dest) { 648 IBinder target = filter.receiverList.receiver.asBinder(); 649 for (int i=dest.size()-1; i>=0; i--) { 650 if (dest.get(i).receiverList.receiver.asBinder() == target) { 651 return false; 652 } 653 } 654 return true; 655 } 656 657 @Override 658 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 659 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 660 || userId == filter.owningUserId) { 661 return super.newResult(filter, match, userId); 662 } 663 return null; 664 } 665 666 @Override 667 protected BroadcastFilter[] newArray(int size) { 668 return new BroadcastFilter[size]; 669 } 670 671 @Override 672 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 673 return packageName.equals(filter.packageName); 674 } 675 }; 676 677 /** 678 * State of all active sticky broadcasts per user. Keys are the action of the 679 * sticky Intent, values are an ArrayList of all broadcasted intents with 680 * that action (which should usually be one). The SparseArray is keyed 681 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 682 * for stickies that are sent to all users. 683 */ 684 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 685 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 686 687 final ActiveServices mServices; 688 689 /** 690 * Backup/restore process management 691 */ 692 String mBackupAppName = null; 693 BackupRecord mBackupTarget = null; 694 695 /** 696 * List of PendingThumbnailsRecord objects of clients who are still 697 * waiting to receive all of the thumbnails for a task. 698 */ 699 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 700 new ArrayList<PendingThumbnailsRecord>(); 701 702 final ProviderMap mProviderMap; 703 704 /** 705 * List of content providers who have clients waiting for them. The 706 * application is currently being launched and the provider will be 707 * removed from this list once it is published. 708 */ 709 final ArrayList<ContentProviderRecord> mLaunchingProviders 710 = new ArrayList<ContentProviderRecord>(); 711 712 /** 713 * File storing persisted {@link #mGrantedUriPermissions}. 714 */ 715 private final AtomicFile mGrantFile; 716 717 /** XML constants used in {@link #mGrantFile} */ 718 private static final String TAG_URI_GRANTS = "uri-grants"; 719 private static final String TAG_URI_GRANT = "uri-grant"; 720 private static final String ATTR_USER_HANDLE = "userHandle"; 721 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 722 private static final String ATTR_TARGET_PKG = "targetPkg"; 723 private static final String ATTR_URI = "uri"; 724 private static final String ATTR_MODE_FLAGS = "modeFlags"; 725 private static final String ATTR_CREATED_TIME = "createdTime"; 726 727 /** 728 * Global set of specific {@link Uri} permissions that have been granted. 729 * This optimized lookup structure maps from {@link UriPermission#targetUid} 730 * to {@link UriPermission#uri} to {@link UriPermission}. 731 */ 732 @GuardedBy("this") 733 private final SparseArray<ArrayMap<Uri, UriPermission>> 734 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 735 736 CoreSettingsObserver mCoreSettingsObserver; 737 738 /** 739 * Thread-local storage used to carry caller permissions over through 740 * indirect content-provider access. 741 */ 742 private class Identity { 743 public int pid; 744 public int uid; 745 746 Identity(int _pid, int _uid) { 747 pid = _pid; 748 uid = _uid; 749 } 750 } 751 752 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 753 754 /** 755 * All information we have collected about the runtime performance of 756 * any user id that can impact battery performance. 757 */ 758 final BatteryStatsService mBatteryStatsService; 759 760 /** 761 * Information about component usage 762 */ 763 final UsageStatsService mUsageStatsService; 764 765 /** 766 * Information about and control over application operations 767 */ 768 final AppOpsService mAppOpsService; 769 770 /** 771 * Current configuration information. HistoryRecord objects are given 772 * a reference to this object to indicate which configuration they are 773 * currently running in, so this object must be kept immutable. 774 */ 775 Configuration mConfiguration = new Configuration(); 776 777 /** 778 * Current sequencing integer of the configuration, for skipping old 779 * configurations. 780 */ 781 int mConfigurationSeq = 0; 782 783 /** 784 * Hardware-reported OpenGLES version. 785 */ 786 final int GL_ES_VERSION; 787 788 /** 789 * List of initialization arguments to pass to all processes when binding applications to them. 790 * For example, references to the commonly used services. 791 */ 792 HashMap<String, IBinder> mAppBindArgs; 793 794 /** 795 * Temporary to avoid allocations. Protected by main lock. 796 */ 797 final StringBuilder mStringBuilder = new StringBuilder(256); 798 799 /** 800 * Used to control how we initialize the service. 801 */ 802 boolean mStartRunning = false; 803 ComponentName mTopComponent; 804 String mTopAction; 805 String mTopData; 806 boolean mProcessesReady = false; 807 boolean mSystemReady = false; 808 boolean mBooting = false; 809 boolean mWaitingUpdate = false; 810 boolean mDidUpdate = false; 811 boolean mOnBattery = false; 812 boolean mLaunchWarningShown = false; 813 814 Context mContext; 815 816 int mFactoryTest; 817 818 boolean mCheckedForSetup; 819 820 /** 821 * The time at which we will allow normal application switches again, 822 * after a call to {@link #stopAppSwitches()}. 823 */ 824 long mAppSwitchesAllowedTime; 825 826 /** 827 * This is set to true after the first switch after mAppSwitchesAllowedTime 828 * is set; any switches after that will clear the time. 829 */ 830 boolean mDidAppSwitch; 831 832 /** 833 * Last time (in realtime) at which we checked for power usage. 834 */ 835 long mLastPowerCheckRealtime; 836 837 /** 838 * Last time (in uptime) at which we checked for power usage. 839 */ 840 long mLastPowerCheckUptime; 841 842 /** 843 * Set while we are wanting to sleep, to prevent any 844 * activities from being started/resumed. 845 */ 846 boolean mSleeping = false; 847 848 /** 849 * State of external calls telling us if the device is asleep. 850 */ 851 boolean mWentToSleep = false; 852 853 /** 854 * State of external call telling us if the lock screen is shown. 855 */ 856 boolean mLockScreenShown = false; 857 858 /** 859 * Set if we are shutting down the system, similar to sleeping. 860 */ 861 boolean mShuttingDown = false; 862 863 /** 864 * Current sequence id for oom_adj computation traversal. 865 */ 866 int mAdjSeq = 0; 867 868 /** 869 * Current sequence id for process LRU updating. 870 */ 871 int mLruSeq = 0; 872 873 /** 874 * Keep track of the non-cached/empty process we last found, to help 875 * determine how to distribute cached/empty processes next time. 876 */ 877 int mNumNonCachedProcs = 0; 878 879 /** 880 * Keep track of the number of cached hidden procs, to balance oom adj 881 * distribution between those and empty procs. 882 */ 883 int mNumCachedHiddenProcs = 0; 884 885 /** 886 * Keep track of the number of service processes we last found, to 887 * determine on the next iteration which should be B services. 888 */ 889 int mNumServiceProcs = 0; 890 int mNewNumAServiceProcs = 0; 891 int mNewNumServiceProcs = 0; 892 893 /** 894 * Allow the current computed overall memory level of the system to go down? 895 * This is set to false when we are killing processes for reasons other than 896 * memory management, so that the now smaller process list will not be taken as 897 * an indication that memory is tighter. 898 */ 899 boolean mAllowLowerMemLevel = false; 900 901 /** 902 * The last computed memory level, for holding when we are in a state that 903 * processes are going away for other reasons. 904 */ 905 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 906 907 /** 908 * The last total number of process we have, to determine if changes actually look 909 * like a shrinking number of process due to lower RAM. 910 */ 911 int mLastNumProcesses; 912 913 /** 914 * The uptime of the last time we performed idle maintenance. 915 */ 916 long mLastIdleTime = SystemClock.uptimeMillis(); 917 918 /** 919 * Total time spent with RAM that has been added in the past since the last idle time. 920 */ 921 long mLowRamTimeSinceLastIdle = 0; 922 923 /** 924 * If RAM is currently low, when that horrible situation started. 925 */ 926 long mLowRamStartTime = 0; 927 928 /** 929 * For reporting to battery stats the current top application. 930 */ 931 private String mCurResumedPackage = null; 932 private int mCurResumedUid = -1; 933 934 /** 935 * For reporting to battery stats the apps currently running foreground 936 * service. The ProcessMap is package/uid tuples; each of these contain 937 * an array of the currently foreground processes. 938 */ 939 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 940 = new ProcessMap<ArrayList<ProcessRecord>>(); 941 942 /** 943 * This is set if we had to do a delayed dexopt of an app before launching 944 * it, to increasing the ANR timeouts in that case. 945 */ 946 boolean mDidDexOpt; 947 948 String mDebugApp = null; 949 boolean mWaitForDebugger = false; 950 boolean mDebugTransient = false; 951 String mOrigDebugApp = null; 952 boolean mOrigWaitForDebugger = false; 953 boolean mAlwaysFinishActivities = false; 954 IActivityController mController = null; 955 String mProfileApp = null; 956 ProcessRecord mProfileProc = null; 957 String mProfileFile; 958 ParcelFileDescriptor mProfileFd; 959 int mProfileType = 0; 960 boolean mAutoStopProfiler = false; 961 String mOpenGlTraceApp = null; 962 963 static class ProcessChangeItem { 964 static final int CHANGE_ACTIVITIES = 1<<0; 965 static final int CHANGE_IMPORTANCE= 1<<1; 966 int changes; 967 int uid; 968 int pid; 969 int importance; 970 boolean foregroundActivities; 971 } 972 973 final RemoteCallbackList<IProcessObserver> mProcessObservers 974 = new RemoteCallbackList<IProcessObserver>(); 975 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 976 977 final ArrayList<ProcessChangeItem> mPendingProcessChanges 978 = new ArrayList<ProcessChangeItem>(); 979 final ArrayList<ProcessChangeItem> mAvailProcessChanges 980 = new ArrayList<ProcessChangeItem>(); 981 982 /** 983 * Runtime CPU use collection thread. This object's lock is used to 984 * protect all related state. 985 */ 986 final Thread mProcessCpuThread; 987 988 /** 989 * Used to collect process stats when showing not responding dialog. 990 * Protected by mProcessCpuThread. 991 */ 992 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 993 MONITOR_THREAD_CPU_USAGE); 994 final AtomicLong mLastCpuTime = new AtomicLong(0); 995 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 996 997 long mLastWriteTime = 0; 998 999 /** 1000 * Used to retain an update lock when the foreground activity is in 1001 * immersive mode. 1002 */ 1003 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1004 1005 /** 1006 * Set to true after the system has finished booting. 1007 */ 1008 boolean mBooted = false; 1009 1010 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1011 int mProcessLimitOverride = -1; 1012 1013 WindowManagerService mWindowManager; 1014 1015 final ActivityThread mSystemThread; 1016 1017 int mCurrentUserId = 0; 1018 private UserManagerService mUserManager; 1019 1020 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1021 final ProcessRecord mApp; 1022 final int mPid; 1023 final IApplicationThread mAppThread; 1024 1025 AppDeathRecipient(ProcessRecord app, int pid, 1026 IApplicationThread thread) { 1027 if (localLOGV) Slog.v( 1028 TAG, "New death recipient " + this 1029 + " for thread " + thread.asBinder()); 1030 mApp = app; 1031 mPid = pid; 1032 mAppThread = thread; 1033 } 1034 1035 @Override 1036 public void binderDied() { 1037 if (localLOGV) Slog.v( 1038 TAG, "Death received in " + this 1039 + " for thread " + mAppThread.asBinder()); 1040 synchronized(ActivityManagerService.this) { 1041 appDiedLocked(mApp, mPid, mAppThread); 1042 } 1043 } 1044 } 1045 1046 static final int SHOW_ERROR_MSG = 1; 1047 static final int SHOW_NOT_RESPONDING_MSG = 2; 1048 static final int SHOW_FACTORY_ERROR_MSG = 3; 1049 static final int UPDATE_CONFIGURATION_MSG = 4; 1050 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1051 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1052 static final int SERVICE_TIMEOUT_MSG = 12; 1053 static final int UPDATE_TIME_ZONE = 13; 1054 static final int SHOW_UID_ERROR_MSG = 14; 1055 static final int IM_FEELING_LUCKY_MSG = 15; 1056 static final int PROC_START_TIMEOUT_MSG = 20; 1057 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1058 static final int KILL_APPLICATION_MSG = 22; 1059 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1060 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1061 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1062 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1063 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1064 static final int CLEAR_DNS_CACHE_MSG = 28; 1065 static final int UPDATE_HTTP_PROXY_MSG = 29; 1066 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1067 static final int DISPATCH_PROCESSES_CHANGED = 31; 1068 static final int DISPATCH_PROCESS_DIED = 32; 1069 static final int REPORT_MEM_USAGE_MSG = 33; 1070 static final int REPORT_USER_SWITCH_MSG = 34; 1071 static final int CONTINUE_USER_SWITCH_MSG = 35; 1072 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1073 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1074 static final int PERSIST_URI_GRANTS_MSG = 38; 1075 static final int REQUEST_ALL_PSS_MSG = 39; 1076 1077 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1078 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1079 static final int FIRST_COMPAT_MODE_MSG = 300; 1080 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1081 1082 AlertDialog mUidAlert; 1083 CompatModeDialog mCompatModeDialog; 1084 long mLastMemUsageReportTime = 0; 1085 1086 /** 1087 * Flag whether the current user is a "monkey", i.e. whether 1088 * the UI is driven by a UI automation tool. 1089 */ 1090 private boolean mUserIsMonkey; 1091 1092 final ServiceThread mHandlerThread; 1093 final MainHandler mHandler; 1094 1095 final class MainHandler extends Handler { 1096 public MainHandler(Looper looper) { 1097 super(looper, null, true); 1098 } 1099 1100 @Override 1101 public void handleMessage(Message msg) { 1102 switch (msg.what) { 1103 case SHOW_ERROR_MSG: { 1104 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1105 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1106 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1107 synchronized (ActivityManagerService.this) { 1108 ProcessRecord proc = (ProcessRecord)data.get("app"); 1109 AppErrorResult res = (AppErrorResult) data.get("result"); 1110 if (proc != null && proc.crashDialog != null) { 1111 Slog.e(TAG, "App already has crash dialog: " + proc); 1112 if (res != null) { 1113 res.set(0); 1114 } 1115 return; 1116 } 1117 if (!showBackground && UserHandle.getAppId(proc.uid) 1118 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1119 && proc.pid != MY_PID) { 1120 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1121 if (res != null) { 1122 res.set(0); 1123 } 1124 return; 1125 } 1126 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1127 Dialog d = new AppErrorDialog(mContext, 1128 ActivityManagerService.this, res, proc); 1129 d.show(); 1130 proc.crashDialog = d; 1131 } else { 1132 // The device is asleep, so just pretend that the user 1133 // saw a crash dialog and hit "force quit". 1134 if (res != null) { 1135 res.set(0); 1136 } 1137 } 1138 } 1139 1140 ensureBootCompleted(); 1141 } break; 1142 case SHOW_NOT_RESPONDING_MSG: { 1143 synchronized (ActivityManagerService.this) { 1144 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1145 ProcessRecord proc = (ProcessRecord)data.get("app"); 1146 if (proc != null && proc.anrDialog != null) { 1147 Slog.e(TAG, "App already has anr dialog: " + proc); 1148 return; 1149 } 1150 1151 Intent intent = new Intent("android.intent.action.ANR"); 1152 if (!mProcessesReady) { 1153 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1154 | Intent.FLAG_RECEIVER_FOREGROUND); 1155 } 1156 broadcastIntentLocked(null, null, intent, 1157 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1158 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1159 1160 if (mShowDialogs) { 1161 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1162 mContext, proc, (ActivityRecord)data.get("activity"), 1163 msg.arg1 != 0); 1164 d.show(); 1165 proc.anrDialog = d; 1166 } else { 1167 // Just kill the app if there is no dialog to be shown. 1168 killAppAtUsersRequest(proc, null); 1169 } 1170 } 1171 1172 ensureBootCompleted(); 1173 } break; 1174 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1175 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1176 synchronized (ActivityManagerService.this) { 1177 ProcessRecord proc = (ProcessRecord) data.get("app"); 1178 if (proc == null) { 1179 Slog.e(TAG, "App not found when showing strict mode dialog."); 1180 break; 1181 } 1182 if (proc.crashDialog != null) { 1183 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1184 return; 1185 } 1186 AppErrorResult res = (AppErrorResult) data.get("result"); 1187 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1188 Dialog d = new StrictModeViolationDialog(mContext, 1189 ActivityManagerService.this, res, proc); 1190 d.show(); 1191 proc.crashDialog = d; 1192 } else { 1193 // The device is asleep, so just pretend that the user 1194 // saw a crash dialog and hit "force quit". 1195 res.set(0); 1196 } 1197 } 1198 ensureBootCompleted(); 1199 } break; 1200 case SHOW_FACTORY_ERROR_MSG: { 1201 Dialog d = new FactoryErrorDialog( 1202 mContext, msg.getData().getCharSequence("msg")); 1203 d.show(); 1204 ensureBootCompleted(); 1205 } break; 1206 case UPDATE_CONFIGURATION_MSG: { 1207 final ContentResolver resolver = mContext.getContentResolver(); 1208 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1209 } break; 1210 case GC_BACKGROUND_PROCESSES_MSG: { 1211 synchronized (ActivityManagerService.this) { 1212 performAppGcsIfAppropriateLocked(); 1213 } 1214 } break; 1215 case WAIT_FOR_DEBUGGER_MSG: { 1216 synchronized (ActivityManagerService.this) { 1217 ProcessRecord app = (ProcessRecord)msg.obj; 1218 if (msg.arg1 != 0) { 1219 if (!app.waitedForDebugger) { 1220 Dialog d = new AppWaitingForDebuggerDialog( 1221 ActivityManagerService.this, 1222 mContext, app); 1223 app.waitDialog = d; 1224 app.waitedForDebugger = true; 1225 d.show(); 1226 } 1227 } else { 1228 if (app.waitDialog != null) { 1229 app.waitDialog.dismiss(); 1230 app.waitDialog = null; 1231 } 1232 } 1233 } 1234 } break; 1235 case SERVICE_TIMEOUT_MSG: { 1236 if (mDidDexOpt) { 1237 mDidDexOpt = false; 1238 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1239 nmsg.obj = msg.obj; 1240 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1241 return; 1242 } 1243 mServices.serviceTimeout((ProcessRecord)msg.obj); 1244 } break; 1245 case UPDATE_TIME_ZONE: { 1246 synchronized (ActivityManagerService.this) { 1247 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1248 ProcessRecord r = mLruProcesses.get(i); 1249 if (r.thread != null) { 1250 try { 1251 r.thread.updateTimeZone(); 1252 } catch (RemoteException ex) { 1253 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1254 } 1255 } 1256 } 1257 } 1258 } break; 1259 case CLEAR_DNS_CACHE_MSG: { 1260 synchronized (ActivityManagerService.this) { 1261 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1262 ProcessRecord r = mLruProcesses.get(i); 1263 if (r.thread != null) { 1264 try { 1265 r.thread.clearDnsCache(); 1266 } catch (RemoteException ex) { 1267 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1268 } 1269 } 1270 } 1271 } 1272 } break; 1273 case UPDATE_HTTP_PROXY_MSG: { 1274 ProxyProperties proxy = (ProxyProperties)msg.obj; 1275 String host = ""; 1276 String port = ""; 1277 String exclList = ""; 1278 String pacFileUrl = null; 1279 if (proxy != null) { 1280 host = proxy.getHost(); 1281 port = Integer.toString(proxy.getPort()); 1282 exclList = proxy.getExclusionList(); 1283 pacFileUrl = proxy.getPacFileUrl(); 1284 } 1285 synchronized (ActivityManagerService.this) { 1286 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1287 ProcessRecord r = mLruProcesses.get(i); 1288 if (r.thread != null) { 1289 try { 1290 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1291 } catch (RemoteException ex) { 1292 Slog.w(TAG, "Failed to update http proxy for: " + 1293 r.info.processName); 1294 } 1295 } 1296 } 1297 } 1298 } break; 1299 case SHOW_UID_ERROR_MSG: { 1300 String title = "System UIDs Inconsistent"; 1301 String text = "UIDs on the system are inconsistent, you need to wipe your" 1302 + " data partition or your device will be unstable."; 1303 Log.e(TAG, title + ": " + text); 1304 if (mShowDialogs) { 1305 // XXX This is a temporary dialog, no need to localize. 1306 AlertDialog d = new BaseErrorDialog(mContext); 1307 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1308 d.setCancelable(false); 1309 d.setTitle(title); 1310 d.setMessage(text); 1311 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1312 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1313 mUidAlert = d; 1314 d.show(); 1315 } 1316 } break; 1317 case IM_FEELING_LUCKY_MSG: { 1318 if (mUidAlert != null) { 1319 mUidAlert.dismiss(); 1320 mUidAlert = null; 1321 } 1322 } break; 1323 case PROC_START_TIMEOUT_MSG: { 1324 if (mDidDexOpt) { 1325 mDidDexOpt = false; 1326 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1327 nmsg.obj = msg.obj; 1328 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1329 return; 1330 } 1331 ProcessRecord app = (ProcessRecord)msg.obj; 1332 synchronized (ActivityManagerService.this) { 1333 processStartTimedOutLocked(app); 1334 } 1335 } break; 1336 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1337 synchronized (ActivityManagerService.this) { 1338 doPendingActivityLaunchesLocked(true); 1339 } 1340 } break; 1341 case KILL_APPLICATION_MSG: { 1342 synchronized (ActivityManagerService.this) { 1343 int appid = msg.arg1; 1344 boolean restart = (msg.arg2 == 1); 1345 Bundle bundle = (Bundle)msg.obj; 1346 String pkg = bundle.getString("pkg"); 1347 String reason = bundle.getString("reason"); 1348 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1349 false, UserHandle.USER_ALL, reason); 1350 } 1351 } break; 1352 case FINALIZE_PENDING_INTENT_MSG: { 1353 ((PendingIntentRecord)msg.obj).completeFinalize(); 1354 } break; 1355 case POST_HEAVY_NOTIFICATION_MSG: { 1356 INotificationManager inm = NotificationManager.getService(); 1357 if (inm == null) { 1358 return; 1359 } 1360 1361 ActivityRecord root = (ActivityRecord)msg.obj; 1362 ProcessRecord process = root.app; 1363 if (process == null) { 1364 return; 1365 } 1366 1367 try { 1368 Context context = mContext.createPackageContext(process.info.packageName, 0); 1369 String text = mContext.getString(R.string.heavy_weight_notification, 1370 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1371 Notification notification = new Notification(); 1372 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1373 notification.when = 0; 1374 notification.flags = Notification.FLAG_ONGOING_EVENT; 1375 notification.tickerText = text; 1376 notification.defaults = 0; // please be quiet 1377 notification.sound = null; 1378 notification.vibrate = null; 1379 notification.setLatestEventInfo(context, text, 1380 mContext.getText(R.string.heavy_weight_notification_detail), 1381 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1382 PendingIntent.FLAG_CANCEL_CURRENT, null, 1383 new UserHandle(root.userId))); 1384 1385 try { 1386 int[] outId = new int[1]; 1387 inm.enqueueNotificationWithTag("android", "android", null, 1388 R.string.heavy_weight_notification, 1389 notification, outId, root.userId); 1390 } catch (RuntimeException e) { 1391 Slog.w(ActivityManagerService.TAG, 1392 "Error showing notification for heavy-weight app", e); 1393 } catch (RemoteException e) { 1394 } 1395 } catch (NameNotFoundException e) { 1396 Slog.w(TAG, "Unable to create context for heavy notification", e); 1397 } 1398 } break; 1399 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1400 INotificationManager inm = NotificationManager.getService(); 1401 if (inm == null) { 1402 return; 1403 } 1404 try { 1405 inm.cancelNotificationWithTag("android", null, 1406 R.string.heavy_weight_notification, msg.arg1); 1407 } catch (RuntimeException e) { 1408 Slog.w(ActivityManagerService.TAG, 1409 "Error canceling notification for service", e); 1410 } catch (RemoteException e) { 1411 } 1412 } break; 1413 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1414 synchronized (ActivityManagerService.this) { 1415 checkExcessivePowerUsageLocked(true); 1416 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1417 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1418 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1419 } 1420 } break; 1421 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1422 synchronized (ActivityManagerService.this) { 1423 ActivityRecord ar = (ActivityRecord)msg.obj; 1424 if (mCompatModeDialog != null) { 1425 if (mCompatModeDialog.mAppInfo.packageName.equals( 1426 ar.info.applicationInfo.packageName)) { 1427 return; 1428 } 1429 mCompatModeDialog.dismiss(); 1430 mCompatModeDialog = null; 1431 } 1432 if (ar != null && false) { 1433 if (mCompatModePackages.getPackageAskCompatModeLocked( 1434 ar.packageName)) { 1435 int mode = mCompatModePackages.computeCompatModeLocked( 1436 ar.info.applicationInfo); 1437 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1438 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1439 mCompatModeDialog = new CompatModeDialog( 1440 ActivityManagerService.this, mContext, 1441 ar.info.applicationInfo); 1442 mCompatModeDialog.show(); 1443 } 1444 } 1445 } 1446 } 1447 break; 1448 } 1449 case DISPATCH_PROCESSES_CHANGED: { 1450 dispatchProcessesChanged(); 1451 break; 1452 } 1453 case DISPATCH_PROCESS_DIED: { 1454 final int pid = msg.arg1; 1455 final int uid = msg.arg2; 1456 dispatchProcessDied(pid, uid); 1457 break; 1458 } 1459 case REPORT_MEM_USAGE_MSG: { 1460 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1461 Thread thread = new Thread() { 1462 @Override public void run() { 1463 final SparseArray<ProcessMemInfo> infoMap 1464 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1465 for (int i=0, N=memInfos.size(); i<N; i++) { 1466 ProcessMemInfo mi = memInfos.get(i); 1467 infoMap.put(mi.pid, mi); 1468 } 1469 updateCpuStatsNow(); 1470 synchronized (mProcessCpuThread) { 1471 final int N = mProcessCpuTracker.countStats(); 1472 for (int i=0; i<N; i++) { 1473 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1474 if (st.vsize > 0) { 1475 long pss = Debug.getPss(st.pid, null); 1476 if (pss > 0) { 1477 if (infoMap.indexOfKey(st.pid) < 0) { 1478 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1479 ProcessList.NATIVE_ADJ, -1, "native", null); 1480 mi.pss = pss; 1481 memInfos.add(mi); 1482 } 1483 } 1484 } 1485 } 1486 } 1487 1488 long totalPss = 0; 1489 for (int i=0, N=memInfos.size(); i<N; i++) { 1490 ProcessMemInfo mi = memInfos.get(i); 1491 if (mi.pss == 0) { 1492 mi.pss = Debug.getPss(mi.pid, null); 1493 } 1494 totalPss += mi.pss; 1495 } 1496 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1497 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1498 if (lhs.oomAdj != rhs.oomAdj) { 1499 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1500 } 1501 if (lhs.pss != rhs.pss) { 1502 return lhs.pss < rhs.pss ? 1 : -1; 1503 } 1504 return 0; 1505 } 1506 }); 1507 1508 StringBuilder tag = new StringBuilder(128); 1509 StringBuilder stack = new StringBuilder(128); 1510 tag.append("Low on memory -- "); 1511 appendMemBucket(tag, totalPss, "total", false); 1512 appendMemBucket(stack, totalPss, "total", true); 1513 1514 StringBuilder logBuilder = new StringBuilder(1024); 1515 logBuilder.append("Low on memory:\n"); 1516 1517 boolean firstLine = true; 1518 int lastOomAdj = Integer.MIN_VALUE; 1519 for (int i=0, N=memInfos.size(); i<N; i++) { 1520 ProcessMemInfo mi = memInfos.get(i); 1521 1522 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1523 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1524 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1525 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1526 if (lastOomAdj != mi.oomAdj) { 1527 lastOomAdj = mi.oomAdj; 1528 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1529 tag.append(" / "); 1530 } 1531 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1532 if (firstLine) { 1533 stack.append(":"); 1534 firstLine = false; 1535 } 1536 stack.append("\n\t at "); 1537 } else { 1538 stack.append("$"); 1539 } 1540 } else { 1541 tag.append(" "); 1542 stack.append("$"); 1543 } 1544 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1545 appendMemBucket(tag, mi.pss, mi.name, false); 1546 } 1547 appendMemBucket(stack, mi.pss, mi.name, true); 1548 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1549 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1550 stack.append("("); 1551 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1552 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1553 stack.append(DUMP_MEM_OOM_LABEL[k]); 1554 stack.append(":"); 1555 stack.append(DUMP_MEM_OOM_ADJ[k]); 1556 } 1557 } 1558 stack.append(")"); 1559 } 1560 } 1561 1562 logBuilder.append(" "); 1563 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1564 logBuilder.append(' '); 1565 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1566 logBuilder.append(' '); 1567 ProcessList.appendRamKb(logBuilder, mi.pss); 1568 logBuilder.append(" kB: "); 1569 logBuilder.append(mi.name); 1570 logBuilder.append(" ("); 1571 logBuilder.append(mi.pid); 1572 logBuilder.append(") "); 1573 logBuilder.append(mi.adjType); 1574 logBuilder.append('\n'); 1575 if (mi.adjReason != null) { 1576 logBuilder.append(" "); 1577 logBuilder.append(mi.adjReason); 1578 logBuilder.append('\n'); 1579 } 1580 } 1581 1582 logBuilder.append(" "); 1583 ProcessList.appendRamKb(logBuilder, totalPss); 1584 logBuilder.append(" kB: TOTAL\n"); 1585 1586 long[] infos = new long[Debug.MEMINFO_COUNT]; 1587 Debug.getMemInfo(infos); 1588 logBuilder.append(" MemInfo: "); 1589 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1590 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1591 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1592 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1593 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1594 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1595 logBuilder.append(" ZRAM: "); 1596 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1597 logBuilder.append(" kB RAM, "); 1598 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1599 logBuilder.append(" kB swap total, "); 1600 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1601 logBuilder.append(" kB swap free\n"); 1602 } 1603 Slog.i(TAG, logBuilder.toString()); 1604 1605 StringBuilder dropBuilder = new StringBuilder(1024); 1606 /* 1607 StringWriter oomSw = new StringWriter(); 1608 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1609 StringWriter catSw = new StringWriter(); 1610 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1611 String[] emptyArgs = new String[] { }; 1612 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1613 oomPw.flush(); 1614 String oomString = oomSw.toString(); 1615 */ 1616 dropBuilder.append(stack); 1617 dropBuilder.append('\n'); 1618 dropBuilder.append('\n'); 1619 dropBuilder.append(logBuilder); 1620 dropBuilder.append('\n'); 1621 /* 1622 dropBuilder.append(oomString); 1623 dropBuilder.append('\n'); 1624 */ 1625 StringWriter catSw = new StringWriter(); 1626 synchronized (ActivityManagerService.this) { 1627 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1628 String[] emptyArgs = new String[] { }; 1629 catPw.println(); 1630 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1631 catPw.println(); 1632 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1633 false, false, null); 1634 catPw.println(); 1635 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1636 catPw.flush(); 1637 } 1638 dropBuilder.append(catSw.toString()); 1639 addErrorToDropBox("lowmem", null, "system_server", null, 1640 null, tag.toString(), dropBuilder.toString(), null, null); 1641 //Slog.i(TAG, "Sent to dropbox:"); 1642 //Slog.i(TAG, dropBuilder.toString()); 1643 synchronized (ActivityManagerService.this) { 1644 long now = SystemClock.uptimeMillis(); 1645 if (mLastMemUsageReportTime < now) { 1646 mLastMemUsageReportTime = now; 1647 } 1648 } 1649 } 1650 }; 1651 thread.start(); 1652 break; 1653 } 1654 case REPORT_USER_SWITCH_MSG: { 1655 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1656 break; 1657 } 1658 case CONTINUE_USER_SWITCH_MSG: { 1659 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1660 break; 1661 } 1662 case USER_SWITCH_TIMEOUT_MSG: { 1663 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1664 break; 1665 } 1666 case IMMERSIVE_MODE_LOCK_MSG: { 1667 final boolean nextState = (msg.arg1 != 0); 1668 if (mUpdateLock.isHeld() != nextState) { 1669 if (DEBUG_IMMERSIVE) { 1670 final ActivityRecord r = (ActivityRecord) msg.obj; 1671 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1672 } 1673 if (nextState) { 1674 mUpdateLock.acquire(); 1675 } else { 1676 mUpdateLock.release(); 1677 } 1678 } 1679 break; 1680 } 1681 case PERSIST_URI_GRANTS_MSG: { 1682 writeGrantedUriPermissions(); 1683 break; 1684 } 1685 case REQUEST_ALL_PSS_MSG: { 1686 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1687 break; 1688 } 1689 } 1690 } 1691 }; 1692 1693 static final int COLLECT_PSS_BG_MSG = 1; 1694 1695 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1696 @Override 1697 public void handleMessage(Message msg) { 1698 switch (msg.what) { 1699 case COLLECT_PSS_BG_MSG: { 1700 int i=0, num=0; 1701 long start = SystemClock.uptimeMillis(); 1702 long[] tmp = new long[1]; 1703 do { 1704 ProcessRecord proc; 1705 int procState; 1706 int pid; 1707 synchronized (ActivityManagerService.this) { 1708 if (i >= mPendingPssProcesses.size()) { 1709 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1710 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1711 mPendingPssProcesses.clear(); 1712 return; 1713 } 1714 proc = mPendingPssProcesses.get(i); 1715 procState = proc.pssProcState; 1716 if (proc.thread != null && procState == proc.setProcState) { 1717 pid = proc.pid; 1718 } else { 1719 proc = null; 1720 pid = 0; 1721 } 1722 i++; 1723 } 1724 if (proc != null) { 1725 long pss = Debug.getPss(pid, tmp); 1726 synchronized (ActivityManagerService.this) { 1727 if (proc.thread != null && proc.setProcState == procState 1728 && proc.pid == pid) { 1729 num++; 1730 proc.lastPssTime = SystemClock.uptimeMillis(); 1731 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1732 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1733 + ": " + pss + " lastPss=" + proc.lastPss 1734 + " state=" + ProcessList.makeProcStateString(procState)); 1735 if (proc.initialIdlePss == 0) { 1736 proc.initialIdlePss = pss; 1737 } 1738 proc.lastPss = pss; 1739 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1740 proc.lastCachedPss = pss; 1741 } 1742 } 1743 } 1744 } 1745 } while (true); 1746 } 1747 } 1748 } 1749 }; 1750 1751 public void setSystemProcess() { 1752 try { 1753 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1754 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1755 ServiceManager.addService("meminfo", new MemBinder(this)); 1756 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1757 ServiceManager.addService("dbinfo", new DbBinder(this)); 1758 if (MONITOR_CPU_USAGE) { 1759 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1760 } 1761 ServiceManager.addService("permission", new PermissionController(this)); 1762 1763 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1764 "android", STOCK_PM_FLAGS); 1765 mSystemThread.installSystemApplicationInfo(info); 1766 1767 synchronized (this) { 1768 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1769 app.persistent = true; 1770 app.pid = MY_PID; 1771 app.maxAdj = ProcessList.SYSTEM_ADJ; 1772 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1773 mProcessNames.put(app.processName, app.uid, app); 1774 synchronized (mPidsSelfLocked) { 1775 mPidsSelfLocked.put(app.pid, app); 1776 } 1777 updateLruProcessLocked(app, false, null); 1778 updateOomAdjLocked(); 1779 } 1780 } catch (PackageManager.NameNotFoundException e) { 1781 throw new RuntimeException( 1782 "Unable to find android system package", e); 1783 } 1784 } 1785 1786 public void setWindowManager(WindowManagerService wm) { 1787 mWindowManager = wm; 1788 mStackSupervisor.setWindowManager(wm); 1789 } 1790 1791 public void startObservingNativeCrashes() { 1792 final NativeCrashListener ncl = new NativeCrashListener(this); 1793 ncl.start(); 1794 } 1795 1796 public IAppOpsService getAppOpsService() { 1797 return mAppOpsService; 1798 } 1799 1800 static class MemBinder extends Binder { 1801 ActivityManagerService mActivityManagerService; 1802 MemBinder(ActivityManagerService activityManagerService) { 1803 mActivityManagerService = activityManagerService; 1804 } 1805 1806 @Override 1807 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1808 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1809 != PackageManager.PERMISSION_GRANTED) { 1810 pw.println("Permission Denial: can't dump meminfo from from pid=" 1811 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1812 + " without permission " + android.Manifest.permission.DUMP); 1813 return; 1814 } 1815 1816 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1817 } 1818 } 1819 1820 static class GraphicsBinder extends Binder { 1821 ActivityManagerService mActivityManagerService; 1822 GraphicsBinder(ActivityManagerService activityManagerService) { 1823 mActivityManagerService = activityManagerService; 1824 } 1825 1826 @Override 1827 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1828 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1829 != PackageManager.PERMISSION_GRANTED) { 1830 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1831 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1832 + " without permission " + android.Manifest.permission.DUMP); 1833 return; 1834 } 1835 1836 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1837 } 1838 } 1839 1840 static class DbBinder extends Binder { 1841 ActivityManagerService mActivityManagerService; 1842 DbBinder(ActivityManagerService activityManagerService) { 1843 mActivityManagerService = activityManagerService; 1844 } 1845 1846 @Override 1847 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1848 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1849 != PackageManager.PERMISSION_GRANTED) { 1850 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1851 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1852 + " without permission " + android.Manifest.permission.DUMP); 1853 return; 1854 } 1855 1856 mActivityManagerService.dumpDbInfo(fd, pw, args); 1857 } 1858 } 1859 1860 static class CpuBinder extends Binder { 1861 ActivityManagerService mActivityManagerService; 1862 CpuBinder(ActivityManagerService activityManagerService) { 1863 mActivityManagerService = activityManagerService; 1864 } 1865 1866 @Override 1867 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1868 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1869 != PackageManager.PERMISSION_GRANTED) { 1870 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1871 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1872 + " without permission " + android.Manifest.permission.DUMP); 1873 return; 1874 } 1875 1876 synchronized (mActivityManagerService.mProcessCpuThread) { 1877 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1878 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1879 SystemClock.uptimeMillis())); 1880 } 1881 } 1882 } 1883 1884 public static class Lifecycle extends SystemService { 1885 private ActivityManagerService mService; 1886 1887 @Override 1888 public void onCreate(Context context) { 1889 mService = new ActivityManagerService(context); 1890 } 1891 1892 @Override 1893 public void onStart() { 1894 mService.start(); 1895 } 1896 1897 public ActivityManagerService getService() { 1898 return mService; 1899 } 1900 } 1901 1902 // Note: This method is invoked on the main thread but may need to attach various 1903 // handlers to other threads. So take care to be explicit about the looper. 1904 public ActivityManagerService(Context systemContext) { 1905 mContext = systemContext; 1906 mFactoryTest = FactoryTest.getMode(); 1907 mSystemThread = ActivityThread.currentActivityThread(); 1908 1909 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1910 1911 mHandlerThread = new ServiceThread(TAG, 1912 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1913 mHandlerThread.start(); 1914 mHandler = new MainHandler(mHandlerThread.getLooper()); 1915 1916 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1917 "foreground", BROADCAST_FG_TIMEOUT, false); 1918 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1919 "background", BROADCAST_BG_TIMEOUT, true); 1920 mBroadcastQueues[0] = mFgBroadcastQueue; 1921 mBroadcastQueues[1] = mBgBroadcastQueue; 1922 1923 mServices = new ActiveServices(this); 1924 mProviderMap = new ProviderMap(this); 1925 1926 // TODO: Move creation of battery stats service outside of activity manager service. 1927 File dataDir = Environment.getDataDirectory(); 1928 File systemDir = new File(dataDir, "system"); 1929 systemDir.mkdirs(); 1930 mBatteryStatsService = new BatteryStatsService(new File( 1931 systemDir, "batterystats.bin").toString(), mHandler); 1932 mBatteryStatsService.getActiveStatistics().readLocked(); 1933 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1934 mOnBattery = DEBUG_POWER ? true 1935 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1936 mBatteryStatsService.getActiveStatistics().setCallback(this); 1937 1938 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1939 1940 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1941 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1942 1943 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1944 1945 // User 0 is the first and only user that runs at boot. 1946 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1947 mUserLru.add(Integer.valueOf(0)); 1948 updateStartedUserArrayLocked(); 1949 1950 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1951 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1952 1953 mConfiguration.setToDefaults(); 1954 mConfiguration.setLocale(Locale.getDefault()); 1955 1956 mConfigurationSeq = mConfiguration.seq = 1; 1957 mProcessCpuTracker.init(); 1958 1959 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1960 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1961 mStackSupervisor = new ActivityStackSupervisor(this); 1962 1963 mProcessCpuThread = new Thread("CpuTracker") { 1964 @Override 1965 public void run() { 1966 while (true) { 1967 try { 1968 try { 1969 synchronized(this) { 1970 final long now = SystemClock.uptimeMillis(); 1971 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1972 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1973 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1974 // + ", write delay=" + nextWriteDelay); 1975 if (nextWriteDelay < nextCpuDelay) { 1976 nextCpuDelay = nextWriteDelay; 1977 } 1978 if (nextCpuDelay > 0) { 1979 mProcessCpuMutexFree.set(true); 1980 this.wait(nextCpuDelay); 1981 } 1982 } 1983 } catch (InterruptedException e) { 1984 } 1985 updateCpuStatsNow(); 1986 } catch (Exception e) { 1987 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1988 } 1989 } 1990 } 1991 }; 1992 1993 Watchdog.getInstance().addMonitor(this); 1994 Watchdog.getInstance().addThread(mHandler); 1995 } 1996 1997 private void start() { 1998 mProcessCpuThread.start(); 1999 2000 mBatteryStatsService.publish(mContext); 2001 mUsageStatsService.publish(mContext); 2002 mAppOpsService.publish(mContext); 2003 startRunning(null, null, null, null); 2004 } 2005 2006 @Override 2007 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2008 throws RemoteException { 2009 if (code == SYSPROPS_TRANSACTION) { 2010 // We need to tell all apps about the system property change. 2011 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2012 synchronized(this) { 2013 final int NP = mProcessNames.getMap().size(); 2014 for (int ip=0; ip<NP; ip++) { 2015 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2016 final int NA = apps.size(); 2017 for (int ia=0; ia<NA; ia++) { 2018 ProcessRecord app = apps.valueAt(ia); 2019 if (app.thread != null) { 2020 procs.add(app.thread.asBinder()); 2021 } 2022 } 2023 } 2024 } 2025 2026 int N = procs.size(); 2027 for (int i=0; i<N; i++) { 2028 Parcel data2 = Parcel.obtain(); 2029 try { 2030 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2031 } catch (RemoteException e) { 2032 } 2033 data2.recycle(); 2034 } 2035 } 2036 try { 2037 return super.onTransact(code, data, reply, flags); 2038 } catch (RuntimeException e) { 2039 // The activity manager only throws security exceptions, so let's 2040 // log all others. 2041 if (!(e instanceof SecurityException)) { 2042 Slog.wtf(TAG, "Activity Manager Crash", e); 2043 } 2044 throw e; 2045 } 2046 } 2047 2048 void updateCpuStats() { 2049 final long now = SystemClock.uptimeMillis(); 2050 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2051 return; 2052 } 2053 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2054 synchronized (mProcessCpuThread) { 2055 mProcessCpuThread.notify(); 2056 } 2057 } 2058 } 2059 2060 void updateCpuStatsNow() { 2061 synchronized (mProcessCpuThread) { 2062 mProcessCpuMutexFree.set(false); 2063 final long now = SystemClock.uptimeMillis(); 2064 boolean haveNewCpuStats = false; 2065 2066 if (MONITOR_CPU_USAGE && 2067 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2068 mLastCpuTime.set(now); 2069 haveNewCpuStats = true; 2070 mProcessCpuTracker.update(); 2071 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2072 //Slog.i(TAG, "Total CPU usage: " 2073 // + mProcessCpu.getTotalCpuPercent() + "%"); 2074 2075 // Slog the cpu usage if the property is set. 2076 if ("true".equals(SystemProperties.get("events.cpu"))) { 2077 int user = mProcessCpuTracker.getLastUserTime(); 2078 int system = mProcessCpuTracker.getLastSystemTime(); 2079 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2080 int irq = mProcessCpuTracker.getLastIrqTime(); 2081 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2082 int idle = mProcessCpuTracker.getLastIdleTime(); 2083 2084 int total = user + system + iowait + irq + softIrq + idle; 2085 if (total == 0) total = 1; 2086 2087 EventLog.writeEvent(EventLogTags.CPU, 2088 ((user+system+iowait+irq+softIrq) * 100) / total, 2089 (user * 100) / total, 2090 (system * 100) / total, 2091 (iowait * 100) / total, 2092 (irq * 100) / total, 2093 (softIrq * 100) / total); 2094 } 2095 } 2096 2097 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2098 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2099 synchronized(bstats) { 2100 synchronized(mPidsSelfLocked) { 2101 if (haveNewCpuStats) { 2102 if (mOnBattery) { 2103 int perc = bstats.startAddingCpuLocked(); 2104 int totalUTime = 0; 2105 int totalSTime = 0; 2106 final int N = mProcessCpuTracker.countStats(); 2107 for (int i=0; i<N; i++) { 2108 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2109 if (!st.working) { 2110 continue; 2111 } 2112 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2113 int otherUTime = (st.rel_utime*perc)/100; 2114 int otherSTime = (st.rel_stime*perc)/100; 2115 totalUTime += otherUTime; 2116 totalSTime += otherSTime; 2117 if (pr != null) { 2118 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2119 if (ps == null || !ps.isActive()) { 2120 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2121 pr.info.uid, pr.processName); 2122 } 2123 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2124 st.rel_stime-otherSTime); 2125 ps.addSpeedStepTimes(cpuSpeedTimes); 2126 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2127 } else { 2128 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2129 if (ps == null || !ps.isActive()) { 2130 st.batteryStats = ps = bstats.getProcessStatsLocked( 2131 bstats.mapUid(st.uid), st.name); 2132 } 2133 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2134 st.rel_stime-otherSTime); 2135 ps.addSpeedStepTimes(cpuSpeedTimes); 2136 } 2137 } 2138 bstats.finishAddingCpuLocked(perc, totalUTime, 2139 totalSTime, cpuSpeedTimes); 2140 } 2141 } 2142 } 2143 2144 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2145 mLastWriteTime = now; 2146 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2147 } 2148 } 2149 } 2150 } 2151 2152 @Override 2153 public void batteryNeedsCpuUpdate() { 2154 updateCpuStatsNow(); 2155 } 2156 2157 @Override 2158 public void batteryPowerChanged(boolean onBattery) { 2159 // When plugging in, update the CPU stats first before changing 2160 // the plug state. 2161 updateCpuStatsNow(); 2162 synchronized (this) { 2163 synchronized(mPidsSelfLocked) { 2164 mOnBattery = DEBUG_POWER ? true : onBattery; 2165 } 2166 } 2167 } 2168 2169 /** 2170 * Initialize the application bind args. These are passed to each 2171 * process when the bindApplication() IPC is sent to the process. They're 2172 * lazily setup to make sure the services are running when they're asked for. 2173 */ 2174 private HashMap<String, IBinder> getCommonServicesLocked() { 2175 if (mAppBindArgs == null) { 2176 mAppBindArgs = new HashMap<String, IBinder>(); 2177 2178 // Setup the application init args 2179 mAppBindArgs.put("package", ServiceManager.getService("package")); 2180 mAppBindArgs.put("window", ServiceManager.getService("window")); 2181 mAppBindArgs.put(Context.ALARM_SERVICE, 2182 ServiceManager.getService(Context.ALARM_SERVICE)); 2183 } 2184 return mAppBindArgs; 2185 } 2186 2187 final void setFocusedActivityLocked(ActivityRecord r) { 2188 if (mFocusedActivity != r) { 2189 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2190 mFocusedActivity = r; 2191 mStackSupervisor.setFocusedStack(r); 2192 if (r != null) { 2193 mWindowManager.setFocusedApp(r.appToken, true); 2194 } 2195 applyUpdateLockStateLocked(r); 2196 } 2197 } 2198 2199 @Override 2200 public void setFocusedStack(int stackId) { 2201 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2202 synchronized (ActivityManagerService.this) { 2203 ActivityStack stack = mStackSupervisor.getStack(stackId); 2204 if (stack != null) { 2205 ActivityRecord r = stack.topRunningActivityLocked(null); 2206 if (r != null) { 2207 setFocusedActivityLocked(r); 2208 } 2209 } 2210 } 2211 } 2212 2213 @Override 2214 public void notifyActivityDrawn(IBinder token) { 2215 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2216 synchronized (this) { 2217 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2218 if (r != null) { 2219 r.task.stack.notifyActivityDrawnLocked(r); 2220 } 2221 } 2222 } 2223 2224 final void applyUpdateLockStateLocked(ActivityRecord r) { 2225 // Modifications to the UpdateLock state are done on our handler, outside 2226 // the activity manager's locks. The new state is determined based on the 2227 // state *now* of the relevant activity record. The object is passed to 2228 // the handler solely for logging detail, not to be consulted/modified. 2229 final boolean nextState = r != null && r.immersive; 2230 mHandler.sendMessage( 2231 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2232 } 2233 2234 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2235 Message msg = Message.obtain(); 2236 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2237 msg.obj = r.task.askedCompatMode ? null : r; 2238 mHandler.sendMessage(msg); 2239 } 2240 2241 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2242 String what, Object obj, ProcessRecord srcApp) { 2243 app.lastActivityTime = now; 2244 2245 if (app.activities.size() > 0) { 2246 // Don't want to touch dependent processes that are hosting activities. 2247 return index; 2248 } 2249 2250 int lrui = mLruProcesses.lastIndexOf(app); 2251 if (lrui < 0) { 2252 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2253 + what + " " + obj + " from " + srcApp); 2254 return index; 2255 } 2256 2257 if (lrui >= index) { 2258 // Don't want to cause this to move dependent processes *back* in the 2259 // list as if they were less frequently used. 2260 return index; 2261 } 2262 2263 if (lrui >= mLruProcessActivityStart) { 2264 // Don't want to touch dependent processes that are hosting activities. 2265 return index; 2266 } 2267 2268 mLruProcesses.remove(lrui); 2269 if (index > 0) { 2270 index--; 2271 } 2272 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2273 + " in LRU list: " + app); 2274 mLruProcesses.add(index, app); 2275 return index; 2276 } 2277 2278 final void removeLruProcessLocked(ProcessRecord app) { 2279 int lrui = mLruProcesses.lastIndexOf(app); 2280 if (lrui >= 0) { 2281 if (lrui <= mLruProcessActivityStart) { 2282 mLruProcessActivityStart--; 2283 } 2284 if (lrui <= mLruProcessServiceStart) { 2285 mLruProcessServiceStart--; 2286 } 2287 mLruProcesses.remove(lrui); 2288 } 2289 } 2290 2291 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2292 ProcessRecord client) { 2293 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities; 2294 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2295 if (!activityChange && hasActivity) { 2296 // The process has activties, so we are only going to allow activity-based 2297 // adjustments move it. It should be kept in the front of the list with other 2298 // processes that have activities, and we don't want those to change their 2299 // order except due to activity operations. 2300 return; 2301 } 2302 2303 mLruSeq++; 2304 final long now = SystemClock.uptimeMillis(); 2305 app.lastActivityTime = now; 2306 2307 // First a quick reject: if the app is already at the position we will 2308 // put it, then there is nothing to do. 2309 if (hasActivity) { 2310 final int N = mLruProcesses.size(); 2311 if (N > 0 && mLruProcesses.get(N-1) == app) { 2312 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2313 return; 2314 } 2315 } else { 2316 if (mLruProcessServiceStart > 0 2317 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2318 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2319 return; 2320 } 2321 } 2322 2323 int lrui = mLruProcesses.lastIndexOf(app); 2324 2325 if (app.persistent && lrui >= 0) { 2326 // We don't care about the position of persistent processes, as long as 2327 // they are in the list. 2328 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2329 return; 2330 } 2331 2332 /* In progress: compute new position first, so we can avoid doing work 2333 if the process is not actually going to move. Not yet working. 2334 int addIndex; 2335 int nextIndex; 2336 boolean inActivity = false, inService = false; 2337 if (hasActivity) { 2338 // Process has activities, put it at the very tipsy-top. 2339 addIndex = mLruProcesses.size(); 2340 nextIndex = mLruProcessServiceStart; 2341 inActivity = true; 2342 } else if (hasService) { 2343 // Process has services, put it at the top of the service list. 2344 addIndex = mLruProcessActivityStart; 2345 nextIndex = mLruProcessServiceStart; 2346 inActivity = true; 2347 inService = true; 2348 } else { 2349 // Process not otherwise of interest, it goes to the top of the non-service area. 2350 addIndex = mLruProcessServiceStart; 2351 if (client != null) { 2352 int clientIndex = mLruProcesses.lastIndexOf(client); 2353 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2354 + app); 2355 if (clientIndex >= 0 && addIndex > clientIndex) { 2356 addIndex = clientIndex; 2357 } 2358 } 2359 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2360 } 2361 2362 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2363 + mLruProcessActivityStart + "): " + app); 2364 */ 2365 2366 if (lrui >= 0) { 2367 if (lrui < mLruProcessActivityStart) { 2368 mLruProcessActivityStart--; 2369 } 2370 if (lrui < mLruProcessServiceStart) { 2371 mLruProcessServiceStart--; 2372 } 2373 /* 2374 if (addIndex > lrui) { 2375 addIndex--; 2376 } 2377 if (nextIndex > lrui) { 2378 nextIndex--; 2379 } 2380 */ 2381 mLruProcesses.remove(lrui); 2382 } 2383 2384 /* 2385 mLruProcesses.add(addIndex, app); 2386 if (inActivity) { 2387 mLruProcessActivityStart++; 2388 } 2389 if (inService) { 2390 mLruProcessActivityStart++; 2391 } 2392 */ 2393 2394 int nextIndex; 2395 if (hasActivity) { 2396 final int N = mLruProcesses.size(); 2397 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2398 // Process doesn't have activities, but has clients with 2399 // activities... move it up, but one below the top (the top 2400 // should always have a real activity). 2401 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2402 mLruProcesses.add(N-1, app); 2403 // To keep it from spamming the LRU list (by making a bunch of clients), 2404 // we will push down any other entries owned by the app. 2405 final int uid = app.info.uid; 2406 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2407 ProcessRecord subProc = mLruProcesses.get(i); 2408 if (subProc.info.uid == uid) { 2409 // We want to push this one down the list. If the process after 2410 // it is for the same uid, however, don't do so, because we don't 2411 // want them internally to be re-ordered. 2412 if (mLruProcesses.get(i-1).info.uid != uid) { 2413 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2414 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2415 ProcessRecord tmp = mLruProcesses.get(i); 2416 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2417 mLruProcesses.set(i-1, tmp); 2418 i--; 2419 } 2420 } else { 2421 // A gap, we can stop here. 2422 break; 2423 } 2424 } 2425 } else { 2426 // Process has activities, put it at the very tipsy-top. 2427 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2428 mLruProcesses.add(app); 2429 } 2430 nextIndex = mLruProcessServiceStart; 2431 } else if (hasService) { 2432 // Process has services, put it at the top of the service list. 2433 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2434 mLruProcesses.add(mLruProcessActivityStart, app); 2435 nextIndex = mLruProcessServiceStart; 2436 mLruProcessActivityStart++; 2437 } else { 2438 // Process not otherwise of interest, it goes to the top of the non-service area. 2439 int index = mLruProcessServiceStart; 2440 if (client != null) { 2441 // If there is a client, don't allow the process to be moved up higher 2442 // in the list than that client. 2443 int clientIndex = mLruProcesses.lastIndexOf(client); 2444 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2445 + " when updating " + app); 2446 if (clientIndex <= lrui) { 2447 // Don't allow the client index restriction to push it down farther in the 2448 // list than it already is. 2449 clientIndex = lrui; 2450 } 2451 if (clientIndex >= 0 && index > clientIndex) { 2452 index = clientIndex; 2453 } 2454 } 2455 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2456 mLruProcesses.add(index, app); 2457 nextIndex = index-1; 2458 mLruProcessActivityStart++; 2459 mLruProcessServiceStart++; 2460 } 2461 2462 // If the app is currently using a content provider or service, 2463 // bump those processes as well. 2464 for (int j=app.connections.size()-1; j>=0; j--) { 2465 ConnectionRecord cr = app.connections.valueAt(j); 2466 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2467 && cr.binding.service.app != null 2468 && cr.binding.service.app.lruSeq != mLruSeq 2469 && !cr.binding.service.app.persistent) { 2470 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2471 "service connection", cr, app); 2472 } 2473 } 2474 for (int j=app.conProviders.size()-1; j>=0; j--) { 2475 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2476 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2477 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2478 "provider reference", cpr, app); 2479 } 2480 } 2481 } 2482 2483 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2484 if (uid == Process.SYSTEM_UID) { 2485 // The system gets to run in any process. If there are multiple 2486 // processes with the same uid, just pick the first (this 2487 // should never happen). 2488 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2489 if (procs == null) return null; 2490 final int N = procs.size(); 2491 for (int i = 0; i < N; i++) { 2492 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2493 } 2494 } 2495 ProcessRecord proc = mProcessNames.get(processName, uid); 2496 if (false && proc != null && !keepIfLarge 2497 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2498 && proc.lastCachedPss >= 4000) { 2499 // Turn this condition on to cause killing to happen regularly, for testing. 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 } else if (proc != null && !keepIfLarge 2506 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2507 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2508 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2509 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2510 if (proc.baseProcessTracker != null) { 2511 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2512 } 2513 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2514 + "k from cached"); 2515 } 2516 } 2517 return proc; 2518 } 2519 2520 void ensurePackageDexOpt(String packageName) { 2521 IPackageManager pm = AppGlobals.getPackageManager(); 2522 try { 2523 if (pm.performDexOpt(packageName)) { 2524 mDidDexOpt = true; 2525 } 2526 } catch (RemoteException e) { 2527 } 2528 } 2529 2530 boolean isNextTransitionForward() { 2531 int transit = mWindowManager.getPendingAppTransition(); 2532 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2533 || transit == AppTransition.TRANSIT_TASK_OPEN 2534 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2535 } 2536 2537 final ProcessRecord startProcessLocked(String processName, 2538 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2539 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2540 boolean isolated, boolean keepIfLarge) { 2541 ProcessRecord app; 2542 if (!isolated) { 2543 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2544 } else { 2545 // If this is an isolated process, it can't re-use an existing process. 2546 app = null; 2547 } 2548 // We don't have to do anything more if: 2549 // (1) There is an existing application record; and 2550 // (2) The caller doesn't think it is dead, OR there is no thread 2551 // object attached to it so we know it couldn't have crashed; and 2552 // (3) There is a pid assigned to it, so it is either starting or 2553 // already running. 2554 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2555 + " app=" + app + " knownToBeDead=" + knownToBeDead 2556 + " thread=" + (app != null ? app.thread : null) 2557 + " pid=" + (app != null ? app.pid : -1)); 2558 if (app != null && app.pid > 0) { 2559 if (!knownToBeDead || app.thread == null) { 2560 // We already have the app running, or are waiting for it to 2561 // come up (we have a pid but not yet its thread), so keep it. 2562 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2563 // If this is a new package in the process, add the package to the list 2564 app.addPackage(info.packageName, mProcessStats); 2565 return app; 2566 } 2567 2568 // An application record is attached to a previous process, 2569 // clean it up now. 2570 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2571 handleAppDiedLocked(app, true, true); 2572 } 2573 2574 String hostingNameStr = hostingName != null 2575 ? hostingName.flattenToShortString() : null; 2576 2577 if (!isolated) { 2578 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2579 // If we are in the background, then check to see if this process 2580 // is bad. If so, we will just silently fail. 2581 if (mBadProcesses.get(info.processName, info.uid) != null) { 2582 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2583 + "/" + info.processName); 2584 return null; 2585 } 2586 } else { 2587 // When the user is explicitly starting a process, then clear its 2588 // crash count so that we won't make it bad until they see at 2589 // least one crash dialog again, and make the process good again 2590 // if it had been bad. 2591 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2592 + "/" + info.processName); 2593 mProcessCrashTimes.remove(info.processName, info.uid); 2594 if (mBadProcesses.get(info.processName, info.uid) != null) { 2595 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2596 UserHandle.getUserId(info.uid), info.uid, 2597 info.processName); 2598 mBadProcesses.remove(info.processName, info.uid); 2599 if (app != null) { 2600 app.bad = false; 2601 } 2602 } 2603 } 2604 } 2605 2606 if (app == null) { 2607 app = newProcessRecordLocked(info, processName, isolated); 2608 if (app == null) { 2609 Slog.w(TAG, "Failed making new process record for " 2610 + processName + "/" + info.uid + " isolated=" + isolated); 2611 return null; 2612 } 2613 mProcessNames.put(processName, app.uid, app); 2614 if (isolated) { 2615 mIsolatedProcesses.put(app.uid, app); 2616 } 2617 } else { 2618 // If this is a new package in the process, add the package to the list 2619 app.addPackage(info.packageName, mProcessStats); 2620 } 2621 2622 // If the system is not ready yet, then hold off on starting this 2623 // process until it is. 2624 if (!mProcessesReady 2625 && !isAllowedWhileBooting(info) 2626 && !allowWhileBooting) { 2627 if (!mProcessesOnHold.contains(app)) { 2628 mProcessesOnHold.add(app); 2629 } 2630 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2631 return app; 2632 } 2633 2634 startProcessLocked(app, hostingType, hostingNameStr); 2635 return (app.pid != 0) ? app : null; 2636 } 2637 2638 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2639 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2640 } 2641 2642 private final void startProcessLocked(ProcessRecord app, 2643 String hostingType, String hostingNameStr) { 2644 if (app.pid > 0 && app.pid != MY_PID) { 2645 synchronized (mPidsSelfLocked) { 2646 mPidsSelfLocked.remove(app.pid); 2647 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2648 } 2649 app.setPid(0); 2650 } 2651 2652 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2653 "startProcessLocked removing on hold: " + app); 2654 mProcessesOnHold.remove(app); 2655 2656 updateCpuStats(); 2657 2658 try { 2659 int uid = app.uid; 2660 2661 int[] gids = null; 2662 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2663 if (!app.isolated) { 2664 int[] permGids = null; 2665 try { 2666 final PackageManager pm = mContext.getPackageManager(); 2667 permGids = pm.getPackageGids(app.info.packageName); 2668 2669 if (Environment.isExternalStorageEmulated()) { 2670 if (pm.checkPermission( 2671 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2672 app.info.packageName) == PERMISSION_GRANTED) { 2673 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2674 } else { 2675 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2676 } 2677 } 2678 } catch (PackageManager.NameNotFoundException e) { 2679 Slog.w(TAG, "Unable to retrieve gids", e); 2680 } 2681 2682 /* 2683 * Add shared application GID so applications can share some 2684 * resources like shared libraries 2685 */ 2686 if (permGids == null) { 2687 gids = new int[1]; 2688 } else { 2689 gids = new int[permGids.length + 1]; 2690 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2691 } 2692 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2693 } 2694 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2695 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2696 && mTopComponent != null 2697 && app.processName.equals(mTopComponent.getPackageName())) { 2698 uid = 0; 2699 } 2700 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2701 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2702 uid = 0; 2703 } 2704 } 2705 int debugFlags = 0; 2706 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2707 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2708 // Also turn on CheckJNI for debuggable apps. It's quite 2709 // awkward to turn on otherwise. 2710 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2711 } 2712 // Run the app in safe mode if its manifest requests so or the 2713 // system is booted in safe mode. 2714 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2715 Zygote.systemInSafeMode == true) { 2716 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2717 } 2718 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2719 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2720 } 2721 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2722 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2723 } 2724 if ("1".equals(SystemProperties.get("debug.assert"))) { 2725 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2726 } 2727 2728 // Start the process. It will either succeed and return a result containing 2729 // the PID of the new process, or else throw a RuntimeException. 2730 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2731 app.processName, uid, uid, gids, debugFlags, mountExternal, 2732 app.info.targetSdkVersion, app.info.seinfo, null); 2733 2734 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2735 synchronized (bs) { 2736 if (bs.isOnBattery()) { 2737 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2738 } 2739 } 2740 2741 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2742 UserHandle.getUserId(uid), startResult.pid, uid, 2743 app.processName, hostingType, 2744 hostingNameStr != null ? hostingNameStr : ""); 2745 2746 if (app.persistent) { 2747 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2748 } 2749 2750 StringBuilder buf = mStringBuilder; 2751 buf.setLength(0); 2752 buf.append("Start proc "); 2753 buf.append(app.processName); 2754 buf.append(" for "); 2755 buf.append(hostingType); 2756 if (hostingNameStr != null) { 2757 buf.append(" "); 2758 buf.append(hostingNameStr); 2759 } 2760 buf.append(": pid="); 2761 buf.append(startResult.pid); 2762 buf.append(" uid="); 2763 buf.append(uid); 2764 buf.append(" gids={"); 2765 if (gids != null) { 2766 for (int gi=0; gi<gids.length; gi++) { 2767 if (gi != 0) buf.append(", "); 2768 buf.append(gids[gi]); 2769 2770 } 2771 } 2772 buf.append("}"); 2773 Slog.i(TAG, buf.toString()); 2774 app.setPid(startResult.pid); 2775 app.usingWrapper = startResult.usingWrapper; 2776 app.removed = false; 2777 synchronized (mPidsSelfLocked) { 2778 this.mPidsSelfLocked.put(startResult.pid, app); 2779 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2780 msg.obj = app; 2781 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2782 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2783 } 2784 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2785 app.processName, app.info.uid); 2786 if (app.isolated) { 2787 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2788 } 2789 } catch (RuntimeException e) { 2790 // XXX do better error recovery. 2791 app.setPid(0); 2792 Slog.e(TAG, "Failure starting process " + app.processName, e); 2793 } 2794 } 2795 2796 void updateUsageStats(ActivityRecord component, boolean resumed) { 2797 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2798 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2799 if (resumed) { 2800 mUsageStatsService.noteResumeComponent(component.realActivity); 2801 synchronized (stats) { 2802 stats.noteActivityResumedLocked(component.app.uid); 2803 } 2804 } else { 2805 mUsageStatsService.notePauseComponent(component.realActivity); 2806 synchronized (stats) { 2807 stats.noteActivityPausedLocked(component.app.uid); 2808 } 2809 } 2810 } 2811 2812 Intent getHomeIntent() { 2813 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2814 intent.setComponent(mTopComponent); 2815 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2816 intent.addCategory(Intent.CATEGORY_HOME); 2817 } 2818 return intent; 2819 } 2820 2821 boolean startHomeActivityLocked(int userId) { 2822 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2823 && mTopAction == null) { 2824 // We are running in factory test mode, but unable to find 2825 // the factory test app, so just sit around displaying the 2826 // error message and don't try to start anything. 2827 return false; 2828 } 2829 Intent intent = getHomeIntent(); 2830 ActivityInfo aInfo = 2831 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2832 if (aInfo != null) { 2833 intent.setComponent(new ComponentName( 2834 aInfo.applicationInfo.packageName, aInfo.name)); 2835 // Don't do this if the home app is currently being 2836 // instrumented. 2837 aInfo = new ActivityInfo(aInfo); 2838 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2839 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2840 aInfo.applicationInfo.uid, true); 2841 if (app == null || app.instrumentationClass == null) { 2842 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2843 mStackSupervisor.startHomeActivity(intent, aInfo); 2844 } 2845 } 2846 2847 return true; 2848 } 2849 2850 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2851 ActivityInfo ai = null; 2852 ComponentName comp = intent.getComponent(); 2853 try { 2854 if (comp != null) { 2855 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2856 } else { 2857 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2858 intent, 2859 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2860 flags, userId); 2861 2862 if (info != null) { 2863 ai = info.activityInfo; 2864 } 2865 } 2866 } catch (RemoteException e) { 2867 // ignore 2868 } 2869 2870 return ai; 2871 } 2872 2873 /** 2874 * Starts the "new version setup screen" if appropriate. 2875 */ 2876 void startSetupActivityLocked() { 2877 // Only do this once per boot. 2878 if (mCheckedForSetup) { 2879 return; 2880 } 2881 2882 // We will show this screen if the current one is a different 2883 // version than the last one shown, and we are not running in 2884 // low-level factory test mode. 2885 final ContentResolver resolver = mContext.getContentResolver(); 2886 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2887 Settings.Global.getInt(resolver, 2888 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2889 mCheckedForSetup = true; 2890 2891 // See if we should be showing the platform update setup UI. 2892 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2893 List<ResolveInfo> ris = mContext.getPackageManager() 2894 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2895 2896 // We don't allow third party apps to replace this. 2897 ResolveInfo ri = null; 2898 for (int i=0; ris != null && i<ris.size(); i++) { 2899 if ((ris.get(i).activityInfo.applicationInfo.flags 2900 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2901 ri = ris.get(i); 2902 break; 2903 } 2904 } 2905 2906 if (ri != null) { 2907 String vers = ri.activityInfo.metaData != null 2908 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2909 : null; 2910 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2911 vers = ri.activityInfo.applicationInfo.metaData.getString( 2912 Intent.METADATA_SETUP_VERSION); 2913 } 2914 String lastVers = Settings.Secure.getString( 2915 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2916 if (vers != null && !vers.equals(lastVers)) { 2917 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2918 intent.setComponent(new ComponentName( 2919 ri.activityInfo.packageName, ri.activityInfo.name)); 2920 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2921 null, null, 0, 0, 0, null, 0, null, false, null, null); 2922 } 2923 } 2924 } 2925 } 2926 2927 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2928 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2929 } 2930 2931 void enforceNotIsolatedCaller(String caller) { 2932 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2933 throw new SecurityException("Isolated process not allowed to call " + caller); 2934 } 2935 } 2936 2937 @Override 2938 public int getFrontActivityScreenCompatMode() { 2939 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2940 synchronized (this) { 2941 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2942 } 2943 } 2944 2945 @Override 2946 public void setFrontActivityScreenCompatMode(int mode) { 2947 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2948 "setFrontActivityScreenCompatMode"); 2949 synchronized (this) { 2950 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2951 } 2952 } 2953 2954 @Override 2955 public int getPackageScreenCompatMode(String packageName) { 2956 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2957 synchronized (this) { 2958 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2959 } 2960 } 2961 2962 @Override 2963 public void setPackageScreenCompatMode(String packageName, int mode) { 2964 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2965 "setPackageScreenCompatMode"); 2966 synchronized (this) { 2967 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2968 } 2969 } 2970 2971 @Override 2972 public boolean getPackageAskScreenCompat(String packageName) { 2973 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2974 synchronized (this) { 2975 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2976 } 2977 } 2978 2979 @Override 2980 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2981 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2982 "setPackageAskScreenCompat"); 2983 synchronized (this) { 2984 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2985 } 2986 } 2987 2988 private void dispatchProcessesChanged() { 2989 int N; 2990 synchronized (this) { 2991 N = mPendingProcessChanges.size(); 2992 if (mActiveProcessChanges.length < N) { 2993 mActiveProcessChanges = new ProcessChangeItem[N]; 2994 } 2995 mPendingProcessChanges.toArray(mActiveProcessChanges); 2996 mAvailProcessChanges.addAll(mPendingProcessChanges); 2997 mPendingProcessChanges.clear(); 2998 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2999 } 3000 3001 int i = mProcessObservers.beginBroadcast(); 3002 while (i > 0) { 3003 i--; 3004 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3005 if (observer != null) { 3006 try { 3007 for (int j=0; j<N; j++) { 3008 ProcessChangeItem item = mActiveProcessChanges[j]; 3009 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3010 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3011 + item.pid + " uid=" + item.uid + ": " 3012 + item.foregroundActivities); 3013 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3014 item.foregroundActivities); 3015 } 3016 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3017 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3018 + item.pid + " uid=" + item.uid + ": " + item.importance); 3019 observer.onImportanceChanged(item.pid, item.uid, 3020 item.importance); 3021 } 3022 } 3023 } catch (RemoteException e) { 3024 } 3025 } 3026 } 3027 mProcessObservers.finishBroadcast(); 3028 } 3029 3030 private void dispatchProcessDied(int pid, int uid) { 3031 int i = mProcessObservers.beginBroadcast(); 3032 while (i > 0) { 3033 i--; 3034 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3035 if (observer != null) { 3036 try { 3037 observer.onProcessDied(pid, uid); 3038 } catch (RemoteException e) { 3039 } 3040 } 3041 } 3042 mProcessObservers.finishBroadcast(); 3043 } 3044 3045 final void doPendingActivityLaunchesLocked(boolean doResume) { 3046 final int N = mPendingActivityLaunches.size(); 3047 if (N <= 0) { 3048 return; 3049 } 3050 for (int i=0; i<N; i++) { 3051 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3052 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3053 doResume && i == (N-1), null); 3054 } 3055 mPendingActivityLaunches.clear(); 3056 } 3057 3058 @Override 3059 public final int startActivity(IApplicationThread caller, String callingPackage, 3060 Intent intent, String resolvedType, IBinder resultTo, 3061 String resultWho, int requestCode, int startFlags, 3062 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3063 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3064 resultWho, requestCode, 3065 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3066 } 3067 3068 @Override 3069 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3070 Intent intent, String resolvedType, IBinder resultTo, 3071 String resultWho, int requestCode, int startFlags, 3072 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3073 enforceNotIsolatedCaller("startActivity"); 3074 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3075 false, true, "startActivity", null); 3076 // TODO: Switch to user app stacks here. 3077 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3078 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3079 null, null, options, userId, null); 3080 } 3081 3082 @Override 3083 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3084 Intent intent, String resolvedType, IBinder resultTo, 3085 String resultWho, int requestCode, int startFlags, String profileFile, 3086 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3087 enforceNotIsolatedCaller("startActivityAndWait"); 3088 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3089 false, true, "startActivityAndWait", null); 3090 WaitResult res = new WaitResult(); 3091 // TODO: Switch to user app stacks here. 3092 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3093 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3094 res, null, options, UserHandle.getCallingUserId(), null); 3095 return res; 3096 } 3097 3098 @Override 3099 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3100 Intent intent, String resolvedType, IBinder resultTo, 3101 String resultWho, int requestCode, int startFlags, Configuration config, 3102 Bundle options, int userId) { 3103 enforceNotIsolatedCaller("startActivityWithConfig"); 3104 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3105 false, true, "startActivityWithConfig", null); 3106 // TODO: Switch to user app stacks here. 3107 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3108 resolvedType, resultTo, resultWho, requestCode, startFlags, 3109 null, null, null, config, options, userId, null); 3110 return ret; 3111 } 3112 3113 @Override 3114 public int startActivityIntentSender(IApplicationThread caller, 3115 IntentSender intent, Intent fillInIntent, String resolvedType, 3116 IBinder resultTo, String resultWho, int requestCode, 3117 int flagsMask, int flagsValues, Bundle options) { 3118 enforceNotIsolatedCaller("startActivityIntentSender"); 3119 // Refuse possible leaked file descriptors 3120 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3121 throw new IllegalArgumentException("File descriptors passed in Intent"); 3122 } 3123 3124 IIntentSender sender = intent.getTarget(); 3125 if (!(sender instanceof PendingIntentRecord)) { 3126 throw new IllegalArgumentException("Bad PendingIntent object"); 3127 } 3128 3129 PendingIntentRecord pir = (PendingIntentRecord)sender; 3130 3131 synchronized (this) { 3132 // If this is coming from the currently resumed activity, it is 3133 // effectively saying that app switches are allowed at this point. 3134 final ActivityStack stack = getFocusedStack(); 3135 if (stack.mResumedActivity != null && 3136 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3137 mAppSwitchesAllowedTime = 0; 3138 } 3139 } 3140 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3141 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3142 return ret; 3143 } 3144 3145 @Override 3146 public boolean startNextMatchingActivity(IBinder callingActivity, 3147 Intent intent, Bundle options) { 3148 // Refuse possible leaked file descriptors 3149 if (intent != null && intent.hasFileDescriptors() == true) { 3150 throw new IllegalArgumentException("File descriptors passed in Intent"); 3151 } 3152 3153 synchronized (this) { 3154 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3155 if (r == null) { 3156 ActivityOptions.abort(options); 3157 return false; 3158 } 3159 if (r.app == null || r.app.thread == null) { 3160 // The caller is not running... d'oh! 3161 ActivityOptions.abort(options); 3162 return false; 3163 } 3164 intent = new Intent(intent); 3165 // The caller is not allowed to change the data. 3166 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3167 // And we are resetting to find the next component... 3168 intent.setComponent(null); 3169 3170 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3171 3172 ActivityInfo aInfo = null; 3173 try { 3174 List<ResolveInfo> resolves = 3175 AppGlobals.getPackageManager().queryIntentActivities( 3176 intent, r.resolvedType, 3177 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3178 UserHandle.getCallingUserId()); 3179 3180 // Look for the original activity in the list... 3181 final int N = resolves != null ? resolves.size() : 0; 3182 for (int i=0; i<N; i++) { 3183 ResolveInfo rInfo = resolves.get(i); 3184 if (rInfo.activityInfo.packageName.equals(r.packageName) 3185 && rInfo.activityInfo.name.equals(r.info.name)) { 3186 // We found the current one... the next matching is 3187 // after it. 3188 i++; 3189 if (i<N) { 3190 aInfo = resolves.get(i).activityInfo; 3191 } 3192 if (debug) { 3193 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3194 + "/" + r.info.name); 3195 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3196 + "/" + aInfo.name); 3197 } 3198 break; 3199 } 3200 } 3201 } catch (RemoteException e) { 3202 } 3203 3204 if (aInfo == null) { 3205 // Nobody who is next! 3206 ActivityOptions.abort(options); 3207 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3208 return false; 3209 } 3210 3211 intent.setComponent(new ComponentName( 3212 aInfo.applicationInfo.packageName, aInfo.name)); 3213 intent.setFlags(intent.getFlags()&~( 3214 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3215 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3216 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3217 Intent.FLAG_ACTIVITY_NEW_TASK)); 3218 3219 // Okay now we need to start the new activity, replacing the 3220 // currently running activity. This is a little tricky because 3221 // we want to start the new one as if the current one is finished, 3222 // but not finish the current one first so that there is no flicker. 3223 // And thus... 3224 final boolean wasFinishing = r.finishing; 3225 r.finishing = true; 3226 3227 // Propagate reply information over to the new activity. 3228 final ActivityRecord resultTo = r.resultTo; 3229 final String resultWho = r.resultWho; 3230 final int requestCode = r.requestCode; 3231 r.resultTo = null; 3232 if (resultTo != null) { 3233 resultTo.removeResultsLocked(r, resultWho, requestCode); 3234 } 3235 3236 final long origId = Binder.clearCallingIdentity(); 3237 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3238 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3239 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3240 options, false, null, null); 3241 Binder.restoreCallingIdentity(origId); 3242 3243 r.finishing = wasFinishing; 3244 if (res != ActivityManager.START_SUCCESS) { 3245 return false; 3246 } 3247 return true; 3248 } 3249 } 3250 3251 final int startActivityInPackage(int uid, String callingPackage, 3252 Intent intent, String resolvedType, IBinder resultTo, 3253 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3254 IActivityContainer container) { 3255 3256 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3257 false, true, "startActivityInPackage", null); 3258 3259 // TODO: Switch to user app stacks here. 3260 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3261 resultTo, resultWho, requestCode, startFlags, 3262 null, null, null, null, options, userId, container); 3263 return ret; 3264 } 3265 3266 @Override 3267 public final int startActivities(IApplicationThread caller, String callingPackage, 3268 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3269 int userId) { 3270 enforceNotIsolatedCaller("startActivities"); 3271 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3272 false, true, "startActivity", null); 3273 // TODO: Switch to user app stacks here. 3274 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3275 resolvedTypes, resultTo, options, userId); 3276 return ret; 3277 } 3278 3279 final int startActivitiesInPackage(int uid, String callingPackage, 3280 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3281 Bundle options, int userId) { 3282 3283 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3284 false, true, "startActivityInPackage", null); 3285 // TODO: Switch to user app stacks here. 3286 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3287 resultTo, options, userId); 3288 return ret; 3289 } 3290 3291 final void addRecentTaskLocked(TaskRecord task) { 3292 int N = mRecentTasks.size(); 3293 // Quick case: check if the top-most recent task is the same. 3294 if (N > 0 && mRecentTasks.get(0) == task) { 3295 return; 3296 } 3297 // Remove any existing entries that are the same kind of task. 3298 for (int i=0; i<N; i++) { 3299 TaskRecord tr = mRecentTasks.get(i); 3300 if (task.userId == tr.userId 3301 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 3302 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 3303 tr.disposeThumbnail(); 3304 mRecentTasks.remove(i); 3305 i--; 3306 N--; 3307 if (task.intent == null) { 3308 // If the new recent task we are adding is not fully 3309 // specified, then replace it with the existing recent task. 3310 task = tr; 3311 } 3312 } 3313 } 3314 if (N >= MAX_RECENT_TASKS) { 3315 mRecentTasks.remove(N-1).disposeThumbnail(); 3316 } 3317 mRecentTasks.add(0, task); 3318 } 3319 3320 @Override 3321 public void reportActivityFullyDrawn(IBinder token) { 3322 synchronized (this) { 3323 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3324 if (r == null) { 3325 return; 3326 } 3327 r.reportFullyDrawnLocked(); 3328 } 3329 } 3330 3331 @Override 3332 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3333 synchronized (this) { 3334 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3335 if (r == null) { 3336 return; 3337 } 3338 final long origId = Binder.clearCallingIdentity(); 3339 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3340 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3341 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3342 if (config != null) { 3343 r.frozenBeforeDestroy = true; 3344 if (!updateConfigurationLocked(config, r, false, false)) { 3345 mStackSupervisor.resumeTopActivitiesLocked(); 3346 } 3347 } 3348 Binder.restoreCallingIdentity(origId); 3349 } 3350 } 3351 3352 @Override 3353 public int getRequestedOrientation(IBinder token) { 3354 synchronized (this) { 3355 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3356 if (r == null) { 3357 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3358 } 3359 return mWindowManager.getAppOrientation(r.appToken); 3360 } 3361 } 3362 3363 /** 3364 * This is the internal entry point for handling Activity.finish(). 3365 * 3366 * @param token The Binder token referencing the Activity we want to finish. 3367 * @param resultCode Result code, if any, from this Activity. 3368 * @param resultData Result data (Intent), if any, from this Activity. 3369 * 3370 * @return Returns true if the activity successfully finished, or false if it is still running. 3371 */ 3372 @Override 3373 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3374 // Refuse possible leaked file descriptors 3375 if (resultData != null && resultData.hasFileDescriptors() == true) { 3376 throw new IllegalArgumentException("File descriptors passed in Intent"); 3377 } 3378 3379 synchronized(this) { 3380 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3381 if (r == null) { 3382 return true; 3383 } 3384 if (mController != null) { 3385 // Find the first activity that is not finishing. 3386 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3387 if (next != null) { 3388 // ask watcher if this is allowed 3389 boolean resumeOK = true; 3390 try { 3391 resumeOK = mController.activityResuming(next.packageName); 3392 } catch (RemoteException e) { 3393 mController = null; 3394 Watchdog.getInstance().setActivityController(null); 3395 } 3396 3397 if (!resumeOK) { 3398 return false; 3399 } 3400 } 3401 } 3402 final long origId = Binder.clearCallingIdentity(); 3403 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3404 resultData, "app-request", true); 3405 Binder.restoreCallingIdentity(origId); 3406 return res; 3407 } 3408 } 3409 3410 @Override 3411 public final void finishHeavyWeightApp() { 3412 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3413 != PackageManager.PERMISSION_GRANTED) { 3414 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3415 + Binder.getCallingPid() 3416 + ", uid=" + Binder.getCallingUid() 3417 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3418 Slog.w(TAG, msg); 3419 throw new SecurityException(msg); 3420 } 3421 3422 synchronized(this) { 3423 if (mHeavyWeightProcess == null) { 3424 return; 3425 } 3426 3427 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3428 mHeavyWeightProcess.activities); 3429 for (int i=0; i<activities.size(); i++) { 3430 ActivityRecord r = activities.get(i); 3431 if (!r.finishing) { 3432 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3433 null, "finish-heavy", true); 3434 } 3435 } 3436 3437 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3438 mHeavyWeightProcess.userId, 0)); 3439 mHeavyWeightProcess = null; 3440 } 3441 } 3442 3443 @Override 3444 public void crashApplication(int uid, int initialPid, String packageName, 3445 String message) { 3446 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3447 != PackageManager.PERMISSION_GRANTED) { 3448 String msg = "Permission Denial: crashApplication() from pid=" 3449 + Binder.getCallingPid() 3450 + ", uid=" + Binder.getCallingUid() 3451 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3452 Slog.w(TAG, msg); 3453 throw new SecurityException(msg); 3454 } 3455 3456 synchronized(this) { 3457 ProcessRecord proc = null; 3458 3459 // Figure out which process to kill. We don't trust that initialPid 3460 // still has any relation to current pids, so must scan through the 3461 // list. 3462 synchronized (mPidsSelfLocked) { 3463 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3464 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3465 if (p.uid != uid) { 3466 continue; 3467 } 3468 if (p.pid == initialPid) { 3469 proc = p; 3470 break; 3471 } 3472 if (p.pkgList.containsKey(packageName)) { 3473 proc = p; 3474 } 3475 } 3476 } 3477 3478 if (proc == null) { 3479 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3480 + " initialPid=" + initialPid 3481 + " packageName=" + packageName); 3482 return; 3483 } 3484 3485 if (proc.thread != null) { 3486 if (proc.pid == Process.myPid()) { 3487 Log.w(TAG, "crashApplication: trying to crash self!"); 3488 return; 3489 } 3490 long ident = Binder.clearCallingIdentity(); 3491 try { 3492 proc.thread.scheduleCrash(message); 3493 } catch (RemoteException e) { 3494 } 3495 Binder.restoreCallingIdentity(ident); 3496 } 3497 } 3498 } 3499 3500 @Override 3501 public final void finishSubActivity(IBinder token, String resultWho, 3502 int requestCode) { 3503 synchronized(this) { 3504 final long origId = Binder.clearCallingIdentity(); 3505 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3506 if (r != null) { 3507 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3508 } 3509 Binder.restoreCallingIdentity(origId); 3510 } 3511 } 3512 3513 @Override 3514 public boolean finishActivityAffinity(IBinder token) { 3515 synchronized(this) { 3516 final long origId = Binder.clearCallingIdentity(); 3517 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3518 boolean res = false; 3519 if (r != null) { 3520 res = r.task.stack.finishActivityAffinityLocked(r); 3521 } 3522 Binder.restoreCallingIdentity(origId); 3523 return res; 3524 } 3525 } 3526 3527 @Override 3528 public boolean willActivityBeVisible(IBinder token) { 3529 synchronized(this) { 3530 ActivityStack stack = ActivityRecord.getStackLocked(token); 3531 if (stack != null) { 3532 return stack.willActivityBeVisibleLocked(token); 3533 } 3534 return false; 3535 } 3536 } 3537 3538 @Override 3539 public void overridePendingTransition(IBinder token, String packageName, 3540 int enterAnim, int exitAnim) { 3541 synchronized(this) { 3542 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3543 if (self == null) { 3544 return; 3545 } 3546 3547 final long origId = Binder.clearCallingIdentity(); 3548 3549 if (self.state == ActivityState.RESUMED 3550 || self.state == ActivityState.PAUSING) { 3551 mWindowManager.overridePendingAppTransition(packageName, 3552 enterAnim, exitAnim, null); 3553 } 3554 3555 Binder.restoreCallingIdentity(origId); 3556 } 3557 } 3558 3559 /** 3560 * Main function for removing an existing process from the activity manager 3561 * as a result of that process going away. Clears out all connections 3562 * to the process. 3563 */ 3564 private final void handleAppDiedLocked(ProcessRecord app, 3565 boolean restarting, boolean allowRestart) { 3566 int pid = app.pid; 3567 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3568 if (!restarting) { 3569 removeLruProcessLocked(app); 3570 if (pid > 0) { 3571 ProcessList.remove(pid); 3572 } 3573 } 3574 3575 if (mProfileProc == app) { 3576 clearProfilerLocked(); 3577 } 3578 3579 // Remove this application's activities from active lists. 3580 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3581 3582 app.activities.clear(); 3583 3584 if (app.instrumentationClass != null) { 3585 Slog.w(TAG, "Crash of app " + app.processName 3586 + " running instrumentation " + app.instrumentationClass); 3587 Bundle info = new Bundle(); 3588 info.putString("shortMsg", "Process crashed."); 3589 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3590 } 3591 3592 if (!restarting) { 3593 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3594 // If there was nothing to resume, and we are not already 3595 // restarting this process, but there is a visible activity that 3596 // is hosted by the process... then make sure all visible 3597 // activities are running, taking care of restarting this 3598 // process. 3599 if (hasVisibleActivities) { 3600 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3601 } 3602 } 3603 } 3604 } 3605 3606 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3607 IBinder threadBinder = thread.asBinder(); 3608 // Find the application record. 3609 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3610 ProcessRecord rec = mLruProcesses.get(i); 3611 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3612 return i; 3613 } 3614 } 3615 return -1; 3616 } 3617 3618 final ProcessRecord getRecordForAppLocked( 3619 IApplicationThread thread) { 3620 if (thread == null) { 3621 return null; 3622 } 3623 3624 int appIndex = getLRURecordIndexForAppLocked(thread); 3625 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3626 } 3627 3628 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3629 // If there are no longer any background processes running, 3630 // and the app that died was not running instrumentation, 3631 // then tell everyone we are now low on memory. 3632 boolean haveBg = false; 3633 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3634 ProcessRecord rec = mLruProcesses.get(i); 3635 if (rec.thread != null 3636 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3637 haveBg = true; 3638 break; 3639 } 3640 } 3641 3642 if (!haveBg) { 3643 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3644 if (doReport) { 3645 long now = SystemClock.uptimeMillis(); 3646 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3647 doReport = false; 3648 } else { 3649 mLastMemUsageReportTime = now; 3650 } 3651 } 3652 final ArrayList<ProcessMemInfo> memInfos 3653 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3654 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3655 long now = SystemClock.uptimeMillis(); 3656 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3657 ProcessRecord rec = mLruProcesses.get(i); 3658 if (rec == dyingProc || rec.thread == null) { 3659 continue; 3660 } 3661 if (doReport) { 3662 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3663 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3664 } 3665 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3666 // The low memory report is overriding any current 3667 // state for a GC request. Make sure to do 3668 // heavy/important/visible/foreground processes first. 3669 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3670 rec.lastRequestedGc = 0; 3671 } else { 3672 rec.lastRequestedGc = rec.lastLowMemory; 3673 } 3674 rec.reportLowMemory = true; 3675 rec.lastLowMemory = now; 3676 mProcessesToGc.remove(rec); 3677 addProcessToGcListLocked(rec); 3678 } 3679 } 3680 if (doReport) { 3681 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3682 mHandler.sendMessage(msg); 3683 } 3684 scheduleAppGcsLocked(); 3685 } 3686 } 3687 3688 final void appDiedLocked(ProcessRecord app, int pid, 3689 IApplicationThread thread) { 3690 3691 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3692 synchronized (stats) { 3693 stats.noteProcessDiedLocked(app.info.uid, pid); 3694 } 3695 3696 // Clean up already done if the process has been re-started. 3697 if (app.pid == pid && app.thread != null && 3698 app.thread.asBinder() == thread.asBinder()) { 3699 boolean doLowMem = app.instrumentationClass == null; 3700 boolean doOomAdj = doLowMem; 3701 if (!app.killedByAm) { 3702 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3703 + ") has died."); 3704 mAllowLowerMemLevel = true; 3705 } else { 3706 // Note that we always want to do oom adj to update our state with the 3707 // new number of procs. 3708 mAllowLowerMemLevel = false; 3709 doLowMem = false; 3710 } 3711 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3712 if (DEBUG_CLEANUP) Slog.v( 3713 TAG, "Dying app: " + app + ", pid: " + pid 3714 + ", thread: " + thread.asBinder()); 3715 handleAppDiedLocked(app, false, true); 3716 3717 if (doOomAdj) { 3718 updateOomAdjLocked(); 3719 } 3720 if (doLowMem) { 3721 doLowMemReportIfNeededLocked(app); 3722 } 3723 } else if (app.pid != pid) { 3724 // A new process has already been started. 3725 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3726 + ") has died and restarted (pid " + app.pid + ")."); 3727 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3728 } else if (DEBUG_PROCESSES) { 3729 Slog.d(TAG, "Received spurious death notification for thread " 3730 + thread.asBinder()); 3731 } 3732 } 3733 3734 /** 3735 * If a stack trace dump file is configured, dump process stack traces. 3736 * @param clearTraces causes the dump file to be erased prior to the new 3737 * traces being written, if true; when false, the new traces will be 3738 * appended to any existing file content. 3739 * @param firstPids of dalvik VM processes to dump stack traces for first 3740 * @param lastPids of dalvik VM processes to dump stack traces for last 3741 * @param nativeProcs optional list of native process names to dump stack crawls 3742 * @return file containing stack traces, or null if no dump file is configured 3743 */ 3744 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3745 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3746 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3747 if (tracesPath == null || tracesPath.length() == 0) { 3748 return null; 3749 } 3750 3751 File tracesFile = new File(tracesPath); 3752 try { 3753 File tracesDir = tracesFile.getParentFile(); 3754 if (!tracesDir.exists()) { 3755 tracesFile.mkdirs(); 3756 if (!SELinux.restorecon(tracesDir)) { 3757 return null; 3758 } 3759 } 3760 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3761 3762 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3763 tracesFile.createNewFile(); 3764 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3765 } catch (IOException e) { 3766 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3767 return null; 3768 } 3769 3770 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3771 return tracesFile; 3772 } 3773 3774 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3775 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3776 // Use a FileObserver to detect when traces finish writing. 3777 // The order of traces is considered important to maintain for legibility. 3778 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3779 @Override 3780 public synchronized void onEvent(int event, String path) { notify(); } 3781 }; 3782 3783 try { 3784 observer.startWatching(); 3785 3786 // First collect all of the stacks of the most important pids. 3787 if (firstPids != null) { 3788 try { 3789 int num = firstPids.size(); 3790 for (int i = 0; i < num; i++) { 3791 synchronized (observer) { 3792 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3793 observer.wait(200); // Wait for write-close, give up after 200msec 3794 } 3795 } 3796 } catch (InterruptedException e) { 3797 Log.wtf(TAG, e); 3798 } 3799 } 3800 3801 // Next collect the stacks of the native pids 3802 if (nativeProcs != null) { 3803 int[] pids = Process.getPidsForCommands(nativeProcs); 3804 if (pids != null) { 3805 for (int pid : pids) { 3806 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3807 } 3808 } 3809 } 3810 3811 // Lastly, measure CPU usage. 3812 if (processCpuTracker != null) { 3813 processCpuTracker.init(); 3814 System.gc(); 3815 processCpuTracker.update(); 3816 try { 3817 synchronized (processCpuTracker) { 3818 processCpuTracker.wait(500); // measure over 1/2 second. 3819 } 3820 } catch (InterruptedException e) { 3821 } 3822 processCpuTracker.update(); 3823 3824 // We'll take the stack crawls of just the top apps using CPU. 3825 final int N = processCpuTracker.countWorkingStats(); 3826 int numProcs = 0; 3827 for (int i=0; i<N && numProcs<5; i++) { 3828 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3829 if (lastPids.indexOfKey(stats.pid) >= 0) { 3830 numProcs++; 3831 try { 3832 synchronized (observer) { 3833 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3834 observer.wait(200); // Wait for write-close, give up after 200msec 3835 } 3836 } catch (InterruptedException e) { 3837 Log.wtf(TAG, e); 3838 } 3839 3840 } 3841 } 3842 } 3843 } finally { 3844 observer.stopWatching(); 3845 } 3846 } 3847 3848 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3849 if (true || IS_USER_BUILD) { 3850 return; 3851 } 3852 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3853 if (tracesPath == null || tracesPath.length() == 0) { 3854 return; 3855 } 3856 3857 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3858 StrictMode.allowThreadDiskWrites(); 3859 try { 3860 final File tracesFile = new File(tracesPath); 3861 final File tracesDir = tracesFile.getParentFile(); 3862 final File tracesTmp = new File(tracesDir, "__tmp__"); 3863 try { 3864 if (!tracesDir.exists()) { 3865 tracesFile.mkdirs(); 3866 if (!SELinux.restorecon(tracesDir.getPath())) { 3867 return; 3868 } 3869 } 3870 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3871 3872 if (tracesFile.exists()) { 3873 tracesTmp.delete(); 3874 tracesFile.renameTo(tracesTmp); 3875 } 3876 StringBuilder sb = new StringBuilder(); 3877 Time tobj = new Time(); 3878 tobj.set(System.currentTimeMillis()); 3879 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3880 sb.append(": "); 3881 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3882 sb.append(" since "); 3883 sb.append(msg); 3884 FileOutputStream fos = new FileOutputStream(tracesFile); 3885 fos.write(sb.toString().getBytes()); 3886 if (app == null) { 3887 fos.write("\n*** No application process!".getBytes()); 3888 } 3889 fos.close(); 3890 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3891 } catch (IOException e) { 3892 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3893 return; 3894 } 3895 3896 if (app != null) { 3897 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3898 firstPids.add(app.pid); 3899 dumpStackTraces(tracesPath, firstPids, null, null, null); 3900 } 3901 3902 File lastTracesFile = null; 3903 File curTracesFile = null; 3904 for (int i=9; i>=0; i--) { 3905 String name = String.format(Locale.US, "slow%02d.txt", i); 3906 curTracesFile = new File(tracesDir, name); 3907 if (curTracesFile.exists()) { 3908 if (lastTracesFile != null) { 3909 curTracesFile.renameTo(lastTracesFile); 3910 } else { 3911 curTracesFile.delete(); 3912 } 3913 } 3914 lastTracesFile = curTracesFile; 3915 } 3916 tracesFile.renameTo(curTracesFile); 3917 if (tracesTmp.exists()) { 3918 tracesTmp.renameTo(tracesFile); 3919 } 3920 } finally { 3921 StrictMode.setThreadPolicy(oldPolicy); 3922 } 3923 } 3924 3925 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3926 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3927 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3928 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3929 3930 if (mController != null) { 3931 try { 3932 // 0 == continue, -1 = kill process immediately 3933 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3934 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3935 } catch (RemoteException e) { 3936 mController = null; 3937 Watchdog.getInstance().setActivityController(null); 3938 } 3939 } 3940 3941 long anrTime = SystemClock.uptimeMillis(); 3942 if (MONITOR_CPU_USAGE) { 3943 updateCpuStatsNow(); 3944 } 3945 3946 synchronized (this) { 3947 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3948 if (mShuttingDown) { 3949 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3950 return; 3951 } else if (app.notResponding) { 3952 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3953 return; 3954 } else if (app.crashing) { 3955 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3956 return; 3957 } 3958 3959 // In case we come through here for the same app before completing 3960 // this one, mark as anring now so we will bail out. 3961 app.notResponding = true; 3962 3963 // Log the ANR to the event log. 3964 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3965 app.processName, app.info.flags, annotation); 3966 3967 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3968 firstPids.add(app.pid); 3969 3970 int parentPid = app.pid; 3971 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3972 if (parentPid != app.pid) firstPids.add(parentPid); 3973 3974 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3975 3976 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3977 ProcessRecord r = mLruProcesses.get(i); 3978 if (r != null && r.thread != null) { 3979 int pid = r.pid; 3980 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3981 if (r.persistent) { 3982 firstPids.add(pid); 3983 } else { 3984 lastPids.put(pid, Boolean.TRUE); 3985 } 3986 } 3987 } 3988 } 3989 } 3990 3991 // Log the ANR to the main log. 3992 StringBuilder info = new StringBuilder(); 3993 info.setLength(0); 3994 info.append("ANR in ").append(app.processName); 3995 if (activity != null && activity.shortComponentName != null) { 3996 info.append(" (").append(activity.shortComponentName).append(")"); 3997 } 3998 info.append("\n"); 3999 info.append("PID: ").append(app.pid).append("\n"); 4000 if (annotation != null) { 4001 info.append("Reason: ").append(annotation).append("\n"); 4002 } 4003 if (parent != null && parent != activity) { 4004 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4005 } 4006 4007 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4008 4009 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4010 NATIVE_STACKS_OF_INTEREST); 4011 4012 String cpuInfo = null; 4013 if (MONITOR_CPU_USAGE) { 4014 updateCpuStatsNow(); 4015 synchronized (mProcessCpuThread) { 4016 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4017 } 4018 info.append(processCpuTracker.printCurrentLoad()); 4019 info.append(cpuInfo); 4020 } 4021 4022 info.append(processCpuTracker.printCurrentState(anrTime)); 4023 4024 Slog.e(TAG, info.toString()); 4025 if (tracesFile == null) { 4026 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4027 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4028 } 4029 4030 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4031 cpuInfo, tracesFile, null); 4032 4033 if (mController != null) { 4034 try { 4035 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4036 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4037 if (res != 0) { 4038 if (res < 0 && app.pid != MY_PID) { 4039 Process.killProcess(app.pid); 4040 } else { 4041 synchronized (this) { 4042 mServices.scheduleServiceTimeoutLocked(app); 4043 } 4044 } 4045 return; 4046 } 4047 } catch (RemoteException e) { 4048 mController = null; 4049 Watchdog.getInstance().setActivityController(null); 4050 } 4051 } 4052 4053 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4054 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4055 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4056 4057 synchronized (this) { 4058 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4059 killUnneededProcessLocked(app, "background ANR"); 4060 return; 4061 } 4062 4063 // Set the app's notResponding state, and look up the errorReportReceiver 4064 makeAppNotRespondingLocked(app, 4065 activity != null ? activity.shortComponentName : null, 4066 annotation != null ? "ANR " + annotation : "ANR", 4067 info.toString()); 4068 4069 // Bring up the infamous App Not Responding dialog 4070 Message msg = Message.obtain(); 4071 HashMap<String, Object> map = new HashMap<String, Object>(); 4072 msg.what = SHOW_NOT_RESPONDING_MSG; 4073 msg.obj = map; 4074 msg.arg1 = aboveSystem ? 1 : 0; 4075 map.put("app", app); 4076 if (activity != null) { 4077 map.put("activity", activity); 4078 } 4079 4080 mHandler.sendMessage(msg); 4081 } 4082 } 4083 4084 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4085 if (!mLaunchWarningShown) { 4086 mLaunchWarningShown = true; 4087 mHandler.post(new Runnable() { 4088 @Override 4089 public void run() { 4090 synchronized (ActivityManagerService.this) { 4091 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4092 d.show(); 4093 mHandler.postDelayed(new Runnable() { 4094 @Override 4095 public void run() { 4096 synchronized (ActivityManagerService.this) { 4097 d.dismiss(); 4098 mLaunchWarningShown = false; 4099 } 4100 } 4101 }, 4000); 4102 } 4103 } 4104 }); 4105 } 4106 } 4107 4108 @Override 4109 public boolean clearApplicationUserData(final String packageName, 4110 final IPackageDataObserver observer, int userId) { 4111 enforceNotIsolatedCaller("clearApplicationUserData"); 4112 int uid = Binder.getCallingUid(); 4113 int pid = Binder.getCallingPid(); 4114 userId = handleIncomingUser(pid, uid, 4115 userId, false, true, "clearApplicationUserData", null); 4116 long callingId = Binder.clearCallingIdentity(); 4117 try { 4118 IPackageManager pm = AppGlobals.getPackageManager(); 4119 int pkgUid = -1; 4120 synchronized(this) { 4121 try { 4122 pkgUid = pm.getPackageUid(packageName, userId); 4123 } catch (RemoteException e) { 4124 } 4125 if (pkgUid == -1) { 4126 Slog.w(TAG, "Invalid packageName: " + packageName); 4127 if (observer != null) { 4128 try { 4129 observer.onRemoveCompleted(packageName, false); 4130 } catch (RemoteException e) { 4131 Slog.i(TAG, "Observer no longer exists."); 4132 } 4133 } 4134 return false; 4135 } 4136 if (uid == pkgUid || checkComponentPermission( 4137 android.Manifest.permission.CLEAR_APP_USER_DATA, 4138 pid, uid, -1, true) 4139 == PackageManager.PERMISSION_GRANTED) { 4140 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4141 } else { 4142 throw new SecurityException("PID " + pid + " does not have permission " 4143 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4144 + " of package " + packageName); 4145 } 4146 } 4147 4148 try { 4149 // Clear application user data 4150 pm.clearApplicationUserData(packageName, observer, userId); 4151 4152 // Remove all permissions granted from/to this package 4153 removeUriPermissionsForPackageLocked(packageName, userId, true); 4154 4155 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4156 Uri.fromParts("package", packageName, null)); 4157 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4158 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4159 null, null, 0, null, null, null, false, false, userId); 4160 } catch (RemoteException e) { 4161 } 4162 } finally { 4163 Binder.restoreCallingIdentity(callingId); 4164 } 4165 return true; 4166 } 4167 4168 @Override 4169 public void killBackgroundProcesses(final String packageName, int userId) { 4170 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4171 != PackageManager.PERMISSION_GRANTED && 4172 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4173 != PackageManager.PERMISSION_GRANTED) { 4174 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4175 + Binder.getCallingPid() 4176 + ", uid=" + Binder.getCallingUid() 4177 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4178 Slog.w(TAG, msg); 4179 throw new SecurityException(msg); 4180 } 4181 4182 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4183 userId, true, true, "killBackgroundProcesses", null); 4184 long callingId = Binder.clearCallingIdentity(); 4185 try { 4186 IPackageManager pm = AppGlobals.getPackageManager(); 4187 synchronized(this) { 4188 int appId = -1; 4189 try { 4190 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4191 } catch (RemoteException e) { 4192 } 4193 if (appId == -1) { 4194 Slog.w(TAG, "Invalid packageName: " + packageName); 4195 return; 4196 } 4197 killPackageProcessesLocked(packageName, appId, userId, 4198 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4199 } 4200 } finally { 4201 Binder.restoreCallingIdentity(callingId); 4202 } 4203 } 4204 4205 @Override 4206 public void killAllBackgroundProcesses() { 4207 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4208 != PackageManager.PERMISSION_GRANTED) { 4209 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4210 + Binder.getCallingPid() 4211 + ", uid=" + Binder.getCallingUid() 4212 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4213 Slog.w(TAG, msg); 4214 throw new SecurityException(msg); 4215 } 4216 4217 long callingId = Binder.clearCallingIdentity(); 4218 try { 4219 synchronized(this) { 4220 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4221 final int NP = mProcessNames.getMap().size(); 4222 for (int ip=0; ip<NP; ip++) { 4223 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4224 final int NA = apps.size(); 4225 for (int ia=0; ia<NA; ia++) { 4226 ProcessRecord app = apps.valueAt(ia); 4227 if (app.persistent) { 4228 // we don't kill persistent processes 4229 continue; 4230 } 4231 if (app.removed) { 4232 procs.add(app); 4233 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4234 app.removed = true; 4235 procs.add(app); 4236 } 4237 } 4238 } 4239 4240 int N = procs.size(); 4241 for (int i=0; i<N; i++) { 4242 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4243 } 4244 mAllowLowerMemLevel = true; 4245 updateOomAdjLocked(); 4246 doLowMemReportIfNeededLocked(null); 4247 } 4248 } finally { 4249 Binder.restoreCallingIdentity(callingId); 4250 } 4251 } 4252 4253 @Override 4254 public void forceStopPackage(final String packageName, int userId) { 4255 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4256 != PackageManager.PERMISSION_GRANTED) { 4257 String msg = "Permission Denial: forceStopPackage() from pid=" 4258 + Binder.getCallingPid() 4259 + ", uid=" + Binder.getCallingUid() 4260 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4261 Slog.w(TAG, msg); 4262 throw new SecurityException(msg); 4263 } 4264 final int callingPid = Binder.getCallingPid(); 4265 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4266 userId, true, true, "forceStopPackage", null); 4267 long callingId = Binder.clearCallingIdentity(); 4268 try { 4269 IPackageManager pm = AppGlobals.getPackageManager(); 4270 synchronized(this) { 4271 int[] users = userId == UserHandle.USER_ALL 4272 ? getUsersLocked() : new int[] { userId }; 4273 for (int user : users) { 4274 int pkgUid = -1; 4275 try { 4276 pkgUid = pm.getPackageUid(packageName, user); 4277 } catch (RemoteException e) { 4278 } 4279 if (pkgUid == -1) { 4280 Slog.w(TAG, "Invalid packageName: " + packageName); 4281 continue; 4282 } 4283 try { 4284 pm.setPackageStoppedState(packageName, true, user); 4285 } catch (RemoteException e) { 4286 } catch (IllegalArgumentException e) { 4287 Slog.w(TAG, "Failed trying to unstop package " 4288 + packageName + ": " + e); 4289 } 4290 if (isUserRunningLocked(user, false)) { 4291 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4292 } 4293 } 4294 } 4295 } finally { 4296 Binder.restoreCallingIdentity(callingId); 4297 } 4298 } 4299 4300 /* 4301 * The pkg name and app id have to be specified. 4302 */ 4303 @Override 4304 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4305 if (pkg == null) { 4306 return; 4307 } 4308 // Make sure the uid is valid. 4309 if (appid < 0) { 4310 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4311 return; 4312 } 4313 int callerUid = Binder.getCallingUid(); 4314 // Only the system server can kill an application 4315 if (callerUid == Process.SYSTEM_UID) { 4316 // Post an aysnc message to kill the application 4317 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4318 msg.arg1 = appid; 4319 msg.arg2 = 0; 4320 Bundle bundle = new Bundle(); 4321 bundle.putString("pkg", pkg); 4322 bundle.putString("reason", reason); 4323 msg.obj = bundle; 4324 mHandler.sendMessage(msg); 4325 } else { 4326 throw new SecurityException(callerUid + " cannot kill pkg: " + 4327 pkg); 4328 } 4329 } 4330 4331 @Override 4332 public void closeSystemDialogs(String reason) { 4333 enforceNotIsolatedCaller("closeSystemDialogs"); 4334 4335 final int pid = Binder.getCallingPid(); 4336 final int uid = Binder.getCallingUid(); 4337 final long origId = Binder.clearCallingIdentity(); 4338 try { 4339 synchronized (this) { 4340 // Only allow this from foreground processes, so that background 4341 // applications can't abuse it to prevent system UI from being shown. 4342 if (uid >= Process.FIRST_APPLICATION_UID) { 4343 ProcessRecord proc; 4344 synchronized (mPidsSelfLocked) { 4345 proc = mPidsSelfLocked.get(pid); 4346 } 4347 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4348 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4349 + " from background process " + proc); 4350 return; 4351 } 4352 } 4353 closeSystemDialogsLocked(reason); 4354 } 4355 } finally { 4356 Binder.restoreCallingIdentity(origId); 4357 } 4358 } 4359 4360 void closeSystemDialogsLocked(String reason) { 4361 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4362 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4363 | Intent.FLAG_RECEIVER_FOREGROUND); 4364 if (reason != null) { 4365 intent.putExtra("reason", reason); 4366 } 4367 mWindowManager.closeSystemDialogs(reason); 4368 4369 mStackSupervisor.closeSystemDialogsLocked(); 4370 4371 broadcastIntentLocked(null, null, intent, null, 4372 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4373 Process.SYSTEM_UID, UserHandle.USER_ALL); 4374 } 4375 4376 @Override 4377 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4378 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4379 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4380 for (int i=pids.length-1; i>=0; i--) { 4381 ProcessRecord proc; 4382 int oomAdj; 4383 synchronized (this) { 4384 synchronized (mPidsSelfLocked) { 4385 proc = mPidsSelfLocked.get(pids[i]); 4386 oomAdj = proc != null ? proc.setAdj : 0; 4387 } 4388 } 4389 infos[i] = new Debug.MemoryInfo(); 4390 Debug.getMemoryInfo(pids[i], infos[i]); 4391 if (proc != null) { 4392 synchronized (this) { 4393 if (proc.thread != null && proc.setAdj == oomAdj) { 4394 // Record this for posterity if the process has been stable. 4395 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4396 infos[i].getTotalUss(), false, proc.pkgList); 4397 } 4398 } 4399 } 4400 } 4401 return infos; 4402 } 4403 4404 @Override 4405 public long[] getProcessPss(int[] pids) { 4406 enforceNotIsolatedCaller("getProcessPss"); 4407 long[] pss = new long[pids.length]; 4408 for (int i=pids.length-1; i>=0; i--) { 4409 ProcessRecord proc; 4410 int oomAdj; 4411 synchronized (this) { 4412 synchronized (mPidsSelfLocked) { 4413 proc = mPidsSelfLocked.get(pids[i]); 4414 oomAdj = proc != null ? proc.setAdj : 0; 4415 } 4416 } 4417 long[] tmpUss = new long[1]; 4418 pss[i] = Debug.getPss(pids[i], tmpUss); 4419 if (proc != null) { 4420 synchronized (this) { 4421 if (proc.thread != null && proc.setAdj == oomAdj) { 4422 // Record this for posterity if the process has been stable. 4423 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4424 } 4425 } 4426 } 4427 } 4428 return pss; 4429 } 4430 4431 @Override 4432 public void killApplicationProcess(String processName, int uid) { 4433 if (processName == null) { 4434 return; 4435 } 4436 4437 int callerUid = Binder.getCallingUid(); 4438 // Only the system server can kill an application 4439 if (callerUid == Process.SYSTEM_UID) { 4440 synchronized (this) { 4441 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4442 if (app != null && app.thread != null) { 4443 try { 4444 app.thread.scheduleSuicide(); 4445 } catch (RemoteException e) { 4446 // If the other end already died, then our work here is done. 4447 } 4448 } else { 4449 Slog.w(TAG, "Process/uid not found attempting kill of " 4450 + processName + " / " + uid); 4451 } 4452 } 4453 } else { 4454 throw new SecurityException(callerUid + " cannot kill app process: " + 4455 processName); 4456 } 4457 } 4458 4459 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4460 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4461 false, true, false, false, UserHandle.getUserId(uid), reason); 4462 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4463 Uri.fromParts("package", packageName, null)); 4464 if (!mProcessesReady) { 4465 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4466 | Intent.FLAG_RECEIVER_FOREGROUND); 4467 } 4468 intent.putExtra(Intent.EXTRA_UID, uid); 4469 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4470 broadcastIntentLocked(null, null, intent, 4471 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4472 false, false, 4473 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4474 } 4475 4476 private void forceStopUserLocked(int userId, String reason) { 4477 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4478 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4479 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4480 | Intent.FLAG_RECEIVER_FOREGROUND); 4481 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4482 broadcastIntentLocked(null, null, intent, 4483 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4484 false, false, 4485 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4486 } 4487 4488 private final boolean killPackageProcessesLocked(String packageName, int appId, 4489 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4490 boolean doit, boolean evenPersistent, String reason) { 4491 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4492 4493 // Remove all processes this package may have touched: all with the 4494 // same UID (except for the system or root user), and all whose name 4495 // matches the package name. 4496 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4497 final int NP = mProcessNames.getMap().size(); 4498 for (int ip=0; ip<NP; ip++) { 4499 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4500 final int NA = apps.size(); 4501 for (int ia=0; ia<NA; ia++) { 4502 ProcessRecord app = apps.valueAt(ia); 4503 if (app.persistent && !evenPersistent) { 4504 // we don't kill persistent processes 4505 continue; 4506 } 4507 if (app.removed) { 4508 if (doit) { 4509 procs.add(app); 4510 } 4511 continue; 4512 } 4513 4514 // Skip process if it doesn't meet our oom adj requirement. 4515 if (app.setAdj < minOomAdj) { 4516 continue; 4517 } 4518 4519 // If no package is specified, we call all processes under the 4520 // give user id. 4521 if (packageName == null) { 4522 if (app.userId != userId) { 4523 continue; 4524 } 4525 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4526 continue; 4527 } 4528 // Package has been specified, we want to hit all processes 4529 // that match it. We need to qualify this by the processes 4530 // that are running under the specified app and user ID. 4531 } else { 4532 if (UserHandle.getAppId(app.uid) != appId) { 4533 continue; 4534 } 4535 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4536 continue; 4537 } 4538 if (!app.pkgList.containsKey(packageName)) { 4539 continue; 4540 } 4541 } 4542 4543 // Process has passed all conditions, kill it! 4544 if (!doit) { 4545 return true; 4546 } 4547 app.removed = true; 4548 procs.add(app); 4549 } 4550 } 4551 4552 int N = procs.size(); 4553 for (int i=0; i<N; i++) { 4554 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4555 } 4556 updateOomAdjLocked(); 4557 return N > 0; 4558 } 4559 4560 private final boolean forceStopPackageLocked(String name, int appId, 4561 boolean callerWillRestart, boolean purgeCache, boolean doit, 4562 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4563 int i; 4564 int N; 4565 4566 if (userId == UserHandle.USER_ALL && name == null) { 4567 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4568 } 4569 4570 if (appId < 0 && name != null) { 4571 try { 4572 appId = UserHandle.getAppId( 4573 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4574 } catch (RemoteException e) { 4575 } 4576 } 4577 4578 if (doit) { 4579 if (name != null) { 4580 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4581 + " user=" + userId + ": " + reason); 4582 } else { 4583 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4584 } 4585 4586 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4587 for (int ip=pmap.size()-1; ip>=0; ip--) { 4588 SparseArray<Long> ba = pmap.valueAt(ip); 4589 for (i=ba.size()-1; i>=0; i--) { 4590 boolean remove = false; 4591 final int entUid = ba.keyAt(i); 4592 if (name != null) { 4593 if (userId == UserHandle.USER_ALL) { 4594 if (UserHandle.getAppId(entUid) == appId) { 4595 remove = true; 4596 } 4597 } else { 4598 if (entUid == UserHandle.getUid(userId, appId)) { 4599 remove = true; 4600 } 4601 } 4602 } else if (UserHandle.getUserId(entUid) == userId) { 4603 remove = true; 4604 } 4605 if (remove) { 4606 ba.removeAt(i); 4607 } 4608 } 4609 if (ba.size() == 0) { 4610 pmap.removeAt(ip); 4611 } 4612 } 4613 } 4614 4615 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4616 -100, callerWillRestart, true, doit, evenPersistent, 4617 name == null ? ("stop user " + userId) : ("stop " + name)); 4618 4619 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4620 if (!doit) { 4621 return true; 4622 } 4623 didSomething = true; 4624 } 4625 4626 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4627 if (!doit) { 4628 return true; 4629 } 4630 didSomething = true; 4631 } 4632 4633 if (name == null) { 4634 // Remove all sticky broadcasts from this user. 4635 mStickyBroadcasts.remove(userId); 4636 } 4637 4638 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4639 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4640 userId, providers)) { 4641 if (!doit) { 4642 return true; 4643 } 4644 didSomething = true; 4645 } 4646 N = providers.size(); 4647 for (i=0; i<N; i++) { 4648 removeDyingProviderLocked(null, providers.get(i), true); 4649 } 4650 4651 // Remove transient permissions granted from/to this package/user 4652 removeUriPermissionsForPackageLocked(name, userId, false); 4653 4654 if (name == null || uninstalling) { 4655 // Remove pending intents. For now we only do this when force 4656 // stopping users, because we have some problems when doing this 4657 // for packages -- app widgets are not currently cleaned up for 4658 // such packages, so they can be left with bad pending intents. 4659 if (mIntentSenderRecords.size() > 0) { 4660 Iterator<WeakReference<PendingIntentRecord>> it 4661 = mIntentSenderRecords.values().iterator(); 4662 while (it.hasNext()) { 4663 WeakReference<PendingIntentRecord> wpir = it.next(); 4664 if (wpir == null) { 4665 it.remove(); 4666 continue; 4667 } 4668 PendingIntentRecord pir = wpir.get(); 4669 if (pir == null) { 4670 it.remove(); 4671 continue; 4672 } 4673 if (name == null) { 4674 // Stopping user, remove all objects for the user. 4675 if (pir.key.userId != userId) { 4676 // Not the same user, skip it. 4677 continue; 4678 } 4679 } else { 4680 if (UserHandle.getAppId(pir.uid) != appId) { 4681 // Different app id, skip it. 4682 continue; 4683 } 4684 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4685 // Different user, skip it. 4686 continue; 4687 } 4688 if (!pir.key.packageName.equals(name)) { 4689 // Different package, skip it. 4690 continue; 4691 } 4692 } 4693 if (!doit) { 4694 return true; 4695 } 4696 didSomething = true; 4697 it.remove(); 4698 pir.canceled = true; 4699 if (pir.key.activity != null) { 4700 pir.key.activity.pendingResults.remove(pir.ref); 4701 } 4702 } 4703 } 4704 } 4705 4706 if (doit) { 4707 if (purgeCache && name != null) { 4708 AttributeCache ac = AttributeCache.instance(); 4709 if (ac != null) { 4710 ac.removePackage(name); 4711 } 4712 } 4713 if (mBooted) { 4714 mStackSupervisor.resumeTopActivitiesLocked(); 4715 mStackSupervisor.scheduleIdleLocked(); 4716 } 4717 } 4718 4719 return didSomething; 4720 } 4721 4722 private final boolean removeProcessLocked(ProcessRecord app, 4723 boolean callerWillRestart, boolean allowRestart, String reason) { 4724 final String name = app.processName; 4725 final int uid = app.uid; 4726 if (DEBUG_PROCESSES) Slog.d( 4727 TAG, "Force removing proc " + app.toShortString() + " (" + name 4728 + "/" + uid + ")"); 4729 4730 mProcessNames.remove(name, uid); 4731 mIsolatedProcesses.remove(app.uid); 4732 if (mHeavyWeightProcess == app) { 4733 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4734 mHeavyWeightProcess.userId, 0)); 4735 mHeavyWeightProcess = null; 4736 } 4737 boolean needRestart = false; 4738 if (app.pid > 0 && app.pid != MY_PID) { 4739 int pid = app.pid; 4740 synchronized (mPidsSelfLocked) { 4741 mPidsSelfLocked.remove(pid); 4742 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4743 } 4744 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4745 app.processName, app.info.uid); 4746 if (app.isolated) { 4747 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4748 } 4749 killUnneededProcessLocked(app, reason); 4750 handleAppDiedLocked(app, true, allowRestart); 4751 removeLruProcessLocked(app); 4752 4753 if (app.persistent && !app.isolated) { 4754 if (!callerWillRestart) { 4755 addAppLocked(app.info, false); 4756 } else { 4757 needRestart = true; 4758 } 4759 } 4760 } else { 4761 mRemovedProcesses.add(app); 4762 } 4763 4764 return needRestart; 4765 } 4766 4767 private final void processStartTimedOutLocked(ProcessRecord app) { 4768 final int pid = app.pid; 4769 boolean gone = false; 4770 synchronized (mPidsSelfLocked) { 4771 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4772 if (knownApp != null && knownApp.thread == null) { 4773 mPidsSelfLocked.remove(pid); 4774 gone = true; 4775 } 4776 } 4777 4778 if (gone) { 4779 Slog.w(TAG, "Process " + app + " failed to attach"); 4780 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4781 pid, app.uid, app.processName); 4782 mProcessNames.remove(app.processName, app.uid); 4783 mIsolatedProcesses.remove(app.uid); 4784 if (mHeavyWeightProcess == app) { 4785 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4786 mHeavyWeightProcess.userId, 0)); 4787 mHeavyWeightProcess = null; 4788 } 4789 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4790 app.processName, app.info.uid); 4791 if (app.isolated) { 4792 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4793 } 4794 // Take care of any launching providers waiting for this process. 4795 checkAppInLaunchingProvidersLocked(app, true); 4796 // Take care of any services that are waiting for the process. 4797 mServices.processStartTimedOutLocked(app); 4798 killUnneededProcessLocked(app, "start timeout"); 4799 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4800 Slog.w(TAG, "Unattached app died before backup, skipping"); 4801 try { 4802 IBackupManager bm = IBackupManager.Stub.asInterface( 4803 ServiceManager.getService(Context.BACKUP_SERVICE)); 4804 bm.agentDisconnected(app.info.packageName); 4805 } catch (RemoteException e) { 4806 // Can't happen; the backup manager is local 4807 } 4808 } 4809 if (isPendingBroadcastProcessLocked(pid)) { 4810 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4811 skipPendingBroadcastLocked(pid); 4812 } 4813 } else { 4814 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4815 } 4816 } 4817 4818 private final boolean attachApplicationLocked(IApplicationThread thread, 4819 int pid) { 4820 4821 // Find the application record that is being attached... either via 4822 // the pid if we are running in multiple processes, or just pull the 4823 // next app record if we are emulating process with anonymous threads. 4824 ProcessRecord app; 4825 if (pid != MY_PID && pid >= 0) { 4826 synchronized (mPidsSelfLocked) { 4827 app = mPidsSelfLocked.get(pid); 4828 } 4829 } else { 4830 app = null; 4831 } 4832 4833 if (app == null) { 4834 Slog.w(TAG, "No pending application record for pid " + pid 4835 + " (IApplicationThread " + thread + "); dropping process"); 4836 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4837 if (pid > 0 && pid != MY_PID) { 4838 Process.killProcessQuiet(pid); 4839 } else { 4840 try { 4841 thread.scheduleExit(); 4842 } catch (Exception e) { 4843 // Ignore exceptions. 4844 } 4845 } 4846 return false; 4847 } 4848 4849 // If this application record is still attached to a previous 4850 // process, clean it up now. 4851 if (app.thread != null) { 4852 handleAppDiedLocked(app, true, true); 4853 } 4854 4855 // Tell the process all about itself. 4856 4857 if (localLOGV) Slog.v( 4858 TAG, "Binding process pid " + pid + " to record " + app); 4859 4860 final String processName = app.processName; 4861 try { 4862 AppDeathRecipient adr = new AppDeathRecipient( 4863 app, pid, thread); 4864 thread.asBinder().linkToDeath(adr, 0); 4865 app.deathRecipient = adr; 4866 } catch (RemoteException e) { 4867 app.resetPackageList(mProcessStats); 4868 startProcessLocked(app, "link fail", processName); 4869 return false; 4870 } 4871 4872 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4873 4874 app.makeActive(thread, mProcessStats); 4875 app.curAdj = app.setAdj = -100; 4876 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4877 app.forcingToForeground = null; 4878 updateProcessForegroundLocked(app, false, false); 4879 app.hasShownUi = false; 4880 app.debugging = false; 4881 app.cached = false; 4882 4883 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4884 4885 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4886 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4887 4888 if (!normalMode) { 4889 Slog.i(TAG, "Launching preboot mode app: " + app); 4890 } 4891 4892 if (localLOGV) Slog.v( 4893 TAG, "New app record " + app 4894 + " thread=" + thread.asBinder() + " pid=" + pid); 4895 try { 4896 int testMode = IApplicationThread.DEBUG_OFF; 4897 if (mDebugApp != null && mDebugApp.equals(processName)) { 4898 testMode = mWaitForDebugger 4899 ? IApplicationThread.DEBUG_WAIT 4900 : IApplicationThread.DEBUG_ON; 4901 app.debugging = true; 4902 if (mDebugTransient) { 4903 mDebugApp = mOrigDebugApp; 4904 mWaitForDebugger = mOrigWaitForDebugger; 4905 } 4906 } 4907 String profileFile = app.instrumentationProfileFile; 4908 ParcelFileDescriptor profileFd = null; 4909 boolean profileAutoStop = false; 4910 if (mProfileApp != null && mProfileApp.equals(processName)) { 4911 mProfileProc = app; 4912 profileFile = mProfileFile; 4913 profileFd = mProfileFd; 4914 profileAutoStop = mAutoStopProfiler; 4915 } 4916 boolean enableOpenGlTrace = false; 4917 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4918 enableOpenGlTrace = true; 4919 mOpenGlTraceApp = null; 4920 } 4921 4922 // If the app is being launched for restore or full backup, set it up specially 4923 boolean isRestrictedBackupMode = false; 4924 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4925 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4926 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4927 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4928 } 4929 4930 ensurePackageDexOpt(app.instrumentationInfo != null 4931 ? app.instrumentationInfo.packageName 4932 : app.info.packageName); 4933 if (app.instrumentationClass != null) { 4934 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4935 } 4936 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4937 + processName + " with config " + mConfiguration); 4938 ApplicationInfo appInfo = app.instrumentationInfo != null 4939 ? app.instrumentationInfo : app.info; 4940 app.compat = compatibilityInfoForPackageLocked(appInfo); 4941 if (profileFd != null) { 4942 profileFd = profileFd.dup(); 4943 } 4944 thread.bindApplication(processName, appInfo, providers, 4945 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4946 app.instrumentationArguments, app.instrumentationWatcher, 4947 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4948 isRestrictedBackupMode || !normalMode, app.persistent, 4949 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4950 mCoreSettingsObserver.getCoreSettingsLocked()); 4951 updateLruProcessLocked(app, false, null); 4952 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4953 } catch (Exception e) { 4954 // todo: Yikes! What should we do? For now we will try to 4955 // start another process, but that could easily get us in 4956 // an infinite loop of restarting processes... 4957 Slog.w(TAG, "Exception thrown during bind!", e); 4958 4959 app.resetPackageList(mProcessStats); 4960 app.unlinkDeathRecipient(); 4961 startProcessLocked(app, "bind fail", processName); 4962 return false; 4963 } 4964 4965 // Remove this record from the list of starting applications. 4966 mPersistentStartingProcesses.remove(app); 4967 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4968 "Attach application locked removing on hold: " + app); 4969 mProcessesOnHold.remove(app); 4970 4971 boolean badApp = false; 4972 boolean didSomething = false; 4973 4974 // See if the top visible activity is waiting to run in this process... 4975 if (normalMode) { 4976 try { 4977 if (mStackSupervisor.attachApplicationLocked(app)) { 4978 didSomething = true; 4979 } 4980 } catch (Exception e) { 4981 badApp = true; 4982 } 4983 } 4984 4985 // Find any services that should be running in this process... 4986 if (!badApp) { 4987 try { 4988 didSomething |= mServices.attachApplicationLocked(app, processName); 4989 } catch (Exception e) { 4990 badApp = true; 4991 } 4992 } 4993 4994 // Check if a next-broadcast receiver is in this process... 4995 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4996 try { 4997 didSomething |= sendPendingBroadcastsLocked(app); 4998 } catch (Exception e) { 4999 // If the app died trying to launch the receiver we declare it 'bad' 5000 badApp = true; 5001 } 5002 } 5003 5004 // Check whether the next backup agent is in this process... 5005 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5006 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5007 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5008 try { 5009 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5010 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5011 mBackupTarget.backupMode); 5012 } catch (Exception e) { 5013 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5014 e.printStackTrace(); 5015 } 5016 } 5017 5018 if (badApp) { 5019 // todo: Also need to kill application to deal with all 5020 // kinds of exceptions. 5021 handleAppDiedLocked(app, false, true); 5022 return false; 5023 } 5024 5025 if (!didSomething) { 5026 updateOomAdjLocked(); 5027 } 5028 5029 return true; 5030 } 5031 5032 @Override 5033 public final void attachApplication(IApplicationThread thread) { 5034 synchronized (this) { 5035 int callingPid = Binder.getCallingPid(); 5036 final long origId = Binder.clearCallingIdentity(); 5037 attachApplicationLocked(thread, callingPid); 5038 Binder.restoreCallingIdentity(origId); 5039 } 5040 } 5041 5042 @Override 5043 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5044 final long origId = Binder.clearCallingIdentity(); 5045 synchronized (this) { 5046 ActivityStack stack = ActivityRecord.getStackLocked(token); 5047 if (stack != null) { 5048 ActivityRecord r = 5049 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5050 if (stopProfiling) { 5051 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5052 try { 5053 mProfileFd.close(); 5054 } catch (IOException e) { 5055 } 5056 clearProfilerLocked(); 5057 } 5058 } 5059 } 5060 } 5061 Binder.restoreCallingIdentity(origId); 5062 } 5063 5064 void enableScreenAfterBoot() { 5065 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5066 SystemClock.uptimeMillis()); 5067 mWindowManager.enableScreenAfterBoot(); 5068 5069 synchronized (this) { 5070 updateEventDispatchingLocked(); 5071 } 5072 } 5073 5074 @Override 5075 public void showBootMessage(final CharSequence msg, final boolean always) { 5076 enforceNotIsolatedCaller("showBootMessage"); 5077 mWindowManager.showBootMessage(msg, always); 5078 } 5079 5080 @Override 5081 public void dismissKeyguardOnNextActivity() { 5082 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5083 final long token = Binder.clearCallingIdentity(); 5084 try { 5085 synchronized (this) { 5086 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5087 if (mLockScreenShown) { 5088 mLockScreenShown = false; 5089 comeOutOfSleepIfNeededLocked(); 5090 } 5091 mStackSupervisor.setDismissKeyguard(true); 5092 } 5093 } finally { 5094 Binder.restoreCallingIdentity(token); 5095 } 5096 } 5097 5098 final void finishBooting() { 5099 IntentFilter pkgFilter = new IntentFilter(); 5100 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5101 pkgFilter.addDataScheme("package"); 5102 mContext.registerReceiver(new BroadcastReceiver() { 5103 @Override 5104 public void onReceive(Context context, Intent intent) { 5105 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5106 if (pkgs != null) { 5107 for (String pkg : pkgs) { 5108 synchronized (ActivityManagerService.this) { 5109 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 5110 "finished booting")) { 5111 setResultCode(Activity.RESULT_OK); 5112 return; 5113 } 5114 } 5115 } 5116 } 5117 } 5118 }, pkgFilter); 5119 5120 synchronized (this) { 5121 // Ensure that any processes we had put on hold are now started 5122 // up. 5123 final int NP = mProcessesOnHold.size(); 5124 if (NP > 0) { 5125 ArrayList<ProcessRecord> procs = 5126 new ArrayList<ProcessRecord>(mProcessesOnHold); 5127 for (int ip=0; ip<NP; ip++) { 5128 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5129 + procs.get(ip)); 5130 startProcessLocked(procs.get(ip), "on-hold", null); 5131 } 5132 } 5133 5134 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5135 // Start looking for apps that are abusing wake locks. 5136 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5137 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5138 // Tell anyone interested that we are done booting! 5139 SystemProperties.set("sys.boot_completed", "1"); 5140 SystemProperties.set("dev.bootcomplete", "1"); 5141 for (int i=0; i<mStartedUsers.size(); i++) { 5142 UserStartedState uss = mStartedUsers.valueAt(i); 5143 if (uss.mState == UserStartedState.STATE_BOOTING) { 5144 uss.mState = UserStartedState.STATE_RUNNING; 5145 final int userId = mStartedUsers.keyAt(i); 5146 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5147 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5148 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5149 broadcastIntentLocked(null, null, intent, null, 5150 new IIntentReceiver.Stub() { 5151 @Override 5152 public void performReceive(Intent intent, int resultCode, 5153 String data, Bundle extras, boolean ordered, 5154 boolean sticky, int sendingUser) { 5155 synchronized (ActivityManagerService.this) { 5156 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5157 true, false); 5158 } 5159 } 5160 }, 5161 0, null, null, 5162 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5163 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5164 userId); 5165 } 5166 } 5167 } 5168 } 5169 } 5170 5171 final void ensureBootCompleted() { 5172 boolean booting; 5173 boolean enableScreen; 5174 synchronized (this) { 5175 booting = mBooting; 5176 mBooting = false; 5177 enableScreen = !mBooted; 5178 mBooted = true; 5179 } 5180 5181 if (booting) { 5182 finishBooting(); 5183 } 5184 5185 if (enableScreen) { 5186 enableScreenAfterBoot(); 5187 } 5188 } 5189 5190 @Override 5191 public final void activityResumed(IBinder token) { 5192 final long origId = Binder.clearCallingIdentity(); 5193 synchronized(this) { 5194 ActivityStack stack = ActivityRecord.getStackLocked(token); 5195 if (stack != null) { 5196 ActivityRecord.activityResumedLocked(token); 5197 } 5198 } 5199 Binder.restoreCallingIdentity(origId); 5200 } 5201 5202 @Override 5203 public final void activityPaused(IBinder token) { 5204 final long origId = Binder.clearCallingIdentity(); 5205 synchronized(this) { 5206 ActivityStack stack = ActivityRecord.getStackLocked(token); 5207 if (stack != null) { 5208 stack.activityPausedLocked(token, false); 5209 } 5210 } 5211 Binder.restoreCallingIdentity(origId); 5212 } 5213 5214 @Override 5215 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5216 CharSequence description) { 5217 if (localLOGV) Slog.v( 5218 TAG, "Activity stopped: token=" + token); 5219 5220 // Refuse possible leaked file descriptors 5221 if (icicle != null && icicle.hasFileDescriptors()) { 5222 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5223 } 5224 5225 ActivityRecord r = null; 5226 5227 final long origId = Binder.clearCallingIdentity(); 5228 5229 synchronized (this) { 5230 r = ActivityRecord.isInStackLocked(token); 5231 if (r != null) { 5232 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5233 } 5234 } 5235 5236 if (r != null) { 5237 sendPendingThumbnail(r, null, null, null, false); 5238 } 5239 5240 trimApplications(); 5241 5242 Binder.restoreCallingIdentity(origId); 5243 } 5244 5245 @Override 5246 public final void activityDestroyed(IBinder token) { 5247 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5248 synchronized (this) { 5249 ActivityStack stack = ActivityRecord.getStackLocked(token); 5250 if (stack != null) { 5251 stack.activityDestroyedLocked(token); 5252 } 5253 } 5254 } 5255 5256 @Override 5257 public String getCallingPackage(IBinder token) { 5258 synchronized (this) { 5259 ActivityRecord r = getCallingRecordLocked(token); 5260 return r != null ? r.info.packageName : null; 5261 } 5262 } 5263 5264 @Override 5265 public ComponentName getCallingActivity(IBinder token) { 5266 synchronized (this) { 5267 ActivityRecord r = getCallingRecordLocked(token); 5268 return r != null ? r.intent.getComponent() : null; 5269 } 5270 } 5271 5272 private ActivityRecord getCallingRecordLocked(IBinder token) { 5273 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5274 if (r == null) { 5275 return null; 5276 } 5277 return r.resultTo; 5278 } 5279 5280 @Override 5281 public ComponentName getActivityClassForToken(IBinder token) { 5282 synchronized(this) { 5283 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5284 if (r == null) { 5285 return null; 5286 } 5287 return r.intent.getComponent(); 5288 } 5289 } 5290 5291 @Override 5292 public String getPackageForToken(IBinder token) { 5293 synchronized(this) { 5294 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5295 if (r == null) { 5296 return null; 5297 } 5298 return r.packageName; 5299 } 5300 } 5301 5302 @Override 5303 public IIntentSender getIntentSender(int type, 5304 String packageName, IBinder token, String resultWho, 5305 int requestCode, Intent[] intents, String[] resolvedTypes, 5306 int flags, Bundle options, int userId) { 5307 enforceNotIsolatedCaller("getIntentSender"); 5308 // Refuse possible leaked file descriptors 5309 if (intents != null) { 5310 if (intents.length < 1) { 5311 throw new IllegalArgumentException("Intents array length must be >= 1"); 5312 } 5313 for (int i=0; i<intents.length; i++) { 5314 Intent intent = intents[i]; 5315 if (intent != null) { 5316 if (intent.hasFileDescriptors()) { 5317 throw new IllegalArgumentException("File descriptors passed in Intent"); 5318 } 5319 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5320 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5321 throw new IllegalArgumentException( 5322 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5323 } 5324 intents[i] = new Intent(intent); 5325 } 5326 } 5327 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5328 throw new IllegalArgumentException( 5329 "Intent array length does not match resolvedTypes length"); 5330 } 5331 } 5332 if (options != null) { 5333 if (options.hasFileDescriptors()) { 5334 throw new IllegalArgumentException("File descriptors passed in options"); 5335 } 5336 } 5337 5338 synchronized(this) { 5339 int callingUid = Binder.getCallingUid(); 5340 int origUserId = userId; 5341 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5342 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5343 "getIntentSender", null); 5344 if (origUserId == UserHandle.USER_CURRENT) { 5345 // We don't want to evaluate this until the pending intent is 5346 // actually executed. However, we do want to always do the 5347 // security checking for it above. 5348 userId = UserHandle.USER_CURRENT; 5349 } 5350 try { 5351 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5352 int uid = AppGlobals.getPackageManager() 5353 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5354 if (!UserHandle.isSameApp(callingUid, uid)) { 5355 String msg = "Permission Denial: getIntentSender() from pid=" 5356 + Binder.getCallingPid() 5357 + ", uid=" + Binder.getCallingUid() 5358 + ", (need uid=" + uid + ")" 5359 + " is not allowed to send as package " + packageName; 5360 Slog.w(TAG, msg); 5361 throw new SecurityException(msg); 5362 } 5363 } 5364 5365 return getIntentSenderLocked(type, packageName, callingUid, userId, 5366 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5367 5368 } catch (RemoteException e) { 5369 throw new SecurityException(e); 5370 } 5371 } 5372 } 5373 5374 IIntentSender getIntentSenderLocked(int type, String packageName, 5375 int callingUid, int userId, IBinder token, String resultWho, 5376 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5377 Bundle options) { 5378 if (DEBUG_MU) 5379 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5380 ActivityRecord activity = null; 5381 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5382 activity = ActivityRecord.isInStackLocked(token); 5383 if (activity == null) { 5384 return null; 5385 } 5386 if (activity.finishing) { 5387 return null; 5388 } 5389 } 5390 5391 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5392 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5393 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5394 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5395 |PendingIntent.FLAG_UPDATE_CURRENT); 5396 5397 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5398 type, packageName, activity, resultWho, 5399 requestCode, intents, resolvedTypes, flags, options, userId); 5400 WeakReference<PendingIntentRecord> ref; 5401 ref = mIntentSenderRecords.get(key); 5402 PendingIntentRecord rec = ref != null ? ref.get() : null; 5403 if (rec != null) { 5404 if (!cancelCurrent) { 5405 if (updateCurrent) { 5406 if (rec.key.requestIntent != null) { 5407 rec.key.requestIntent.replaceExtras(intents != null ? 5408 intents[intents.length - 1] : null); 5409 } 5410 if (intents != null) { 5411 intents[intents.length-1] = rec.key.requestIntent; 5412 rec.key.allIntents = intents; 5413 rec.key.allResolvedTypes = resolvedTypes; 5414 } else { 5415 rec.key.allIntents = null; 5416 rec.key.allResolvedTypes = null; 5417 } 5418 } 5419 return rec; 5420 } 5421 rec.canceled = true; 5422 mIntentSenderRecords.remove(key); 5423 } 5424 if (noCreate) { 5425 return rec; 5426 } 5427 rec = new PendingIntentRecord(this, key, callingUid); 5428 mIntentSenderRecords.put(key, rec.ref); 5429 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5430 if (activity.pendingResults == null) { 5431 activity.pendingResults 5432 = new HashSet<WeakReference<PendingIntentRecord>>(); 5433 } 5434 activity.pendingResults.add(rec.ref); 5435 } 5436 return rec; 5437 } 5438 5439 @Override 5440 public void cancelIntentSender(IIntentSender sender) { 5441 if (!(sender instanceof PendingIntentRecord)) { 5442 return; 5443 } 5444 synchronized(this) { 5445 PendingIntentRecord rec = (PendingIntentRecord)sender; 5446 try { 5447 int uid = AppGlobals.getPackageManager() 5448 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5449 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5450 String msg = "Permission Denial: cancelIntentSender() from pid=" 5451 + Binder.getCallingPid() 5452 + ", uid=" + Binder.getCallingUid() 5453 + " is not allowed to cancel packges " 5454 + rec.key.packageName; 5455 Slog.w(TAG, msg); 5456 throw new SecurityException(msg); 5457 } 5458 } catch (RemoteException e) { 5459 throw new SecurityException(e); 5460 } 5461 cancelIntentSenderLocked(rec, true); 5462 } 5463 } 5464 5465 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5466 rec.canceled = true; 5467 mIntentSenderRecords.remove(rec.key); 5468 if (cleanActivity && rec.key.activity != null) { 5469 rec.key.activity.pendingResults.remove(rec.ref); 5470 } 5471 } 5472 5473 @Override 5474 public String getPackageForIntentSender(IIntentSender pendingResult) { 5475 if (!(pendingResult instanceof PendingIntentRecord)) { 5476 return null; 5477 } 5478 try { 5479 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5480 return res.key.packageName; 5481 } catch (ClassCastException e) { 5482 } 5483 return null; 5484 } 5485 5486 @Override 5487 public int getUidForIntentSender(IIntentSender sender) { 5488 if (sender instanceof PendingIntentRecord) { 5489 try { 5490 PendingIntentRecord res = (PendingIntentRecord)sender; 5491 return res.uid; 5492 } catch (ClassCastException e) { 5493 } 5494 } 5495 return -1; 5496 } 5497 5498 @Override 5499 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5500 if (!(pendingResult instanceof PendingIntentRecord)) { 5501 return false; 5502 } 5503 try { 5504 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5505 if (res.key.allIntents == null) { 5506 return false; 5507 } 5508 for (int i=0; i<res.key.allIntents.length; i++) { 5509 Intent intent = res.key.allIntents[i]; 5510 if (intent.getPackage() != null && intent.getComponent() != null) { 5511 return false; 5512 } 5513 } 5514 return true; 5515 } catch (ClassCastException e) { 5516 } 5517 return false; 5518 } 5519 5520 @Override 5521 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5522 if (!(pendingResult instanceof PendingIntentRecord)) { 5523 return false; 5524 } 5525 try { 5526 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5527 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5528 return true; 5529 } 5530 return false; 5531 } catch (ClassCastException e) { 5532 } 5533 return false; 5534 } 5535 5536 @Override 5537 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5538 if (!(pendingResult instanceof PendingIntentRecord)) { 5539 return null; 5540 } 5541 try { 5542 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5543 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5544 } catch (ClassCastException e) { 5545 } 5546 return null; 5547 } 5548 5549 @Override 5550 public void setProcessLimit(int max) { 5551 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5552 "setProcessLimit()"); 5553 synchronized (this) { 5554 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5555 mProcessLimitOverride = max; 5556 } 5557 trimApplications(); 5558 } 5559 5560 @Override 5561 public int getProcessLimit() { 5562 synchronized (this) { 5563 return mProcessLimitOverride; 5564 } 5565 } 5566 5567 void foregroundTokenDied(ForegroundToken token) { 5568 synchronized (ActivityManagerService.this) { 5569 synchronized (mPidsSelfLocked) { 5570 ForegroundToken cur 5571 = mForegroundProcesses.get(token.pid); 5572 if (cur != token) { 5573 return; 5574 } 5575 mForegroundProcesses.remove(token.pid); 5576 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5577 if (pr == null) { 5578 return; 5579 } 5580 pr.forcingToForeground = null; 5581 updateProcessForegroundLocked(pr, false, false); 5582 } 5583 updateOomAdjLocked(); 5584 } 5585 } 5586 5587 @Override 5588 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5589 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5590 "setProcessForeground()"); 5591 synchronized(this) { 5592 boolean changed = false; 5593 5594 synchronized (mPidsSelfLocked) { 5595 ProcessRecord pr = mPidsSelfLocked.get(pid); 5596 if (pr == null && isForeground) { 5597 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5598 return; 5599 } 5600 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5601 if (oldToken != null) { 5602 oldToken.token.unlinkToDeath(oldToken, 0); 5603 mForegroundProcesses.remove(pid); 5604 if (pr != null) { 5605 pr.forcingToForeground = null; 5606 } 5607 changed = true; 5608 } 5609 if (isForeground && token != null) { 5610 ForegroundToken newToken = new ForegroundToken() { 5611 @Override 5612 public void binderDied() { 5613 foregroundTokenDied(this); 5614 } 5615 }; 5616 newToken.pid = pid; 5617 newToken.token = token; 5618 try { 5619 token.linkToDeath(newToken, 0); 5620 mForegroundProcesses.put(pid, newToken); 5621 pr.forcingToForeground = token; 5622 changed = true; 5623 } catch (RemoteException e) { 5624 // If the process died while doing this, we will later 5625 // do the cleanup with the process death link. 5626 } 5627 } 5628 } 5629 5630 if (changed) { 5631 updateOomAdjLocked(); 5632 } 5633 } 5634 } 5635 5636 // ========================================================= 5637 // PERMISSIONS 5638 // ========================================================= 5639 5640 static class PermissionController extends IPermissionController.Stub { 5641 ActivityManagerService mActivityManagerService; 5642 PermissionController(ActivityManagerService activityManagerService) { 5643 mActivityManagerService = activityManagerService; 5644 } 5645 5646 @Override 5647 public boolean checkPermission(String permission, int pid, int uid) { 5648 return mActivityManagerService.checkPermission(permission, pid, 5649 uid) == PackageManager.PERMISSION_GRANTED; 5650 } 5651 } 5652 5653 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5654 @Override 5655 public int checkComponentPermission(String permission, int pid, int uid, 5656 int owningUid, boolean exported) { 5657 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5658 owningUid, exported); 5659 } 5660 5661 @Override 5662 public Object getAMSLock() { 5663 return ActivityManagerService.this; 5664 } 5665 } 5666 5667 /** 5668 * This can be called with or without the global lock held. 5669 */ 5670 int checkComponentPermission(String permission, int pid, int uid, 5671 int owningUid, boolean exported) { 5672 // We might be performing an operation on behalf of an indirect binder 5673 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5674 // client identity accordingly before proceeding. 5675 Identity tlsIdentity = sCallerIdentity.get(); 5676 if (tlsIdentity != null) { 5677 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5678 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5679 uid = tlsIdentity.uid; 5680 pid = tlsIdentity.pid; 5681 } 5682 5683 if (pid == MY_PID) { 5684 return PackageManager.PERMISSION_GRANTED; 5685 } 5686 5687 return ActivityManager.checkComponentPermission(permission, uid, 5688 owningUid, exported); 5689 } 5690 5691 /** 5692 * As the only public entry point for permissions checking, this method 5693 * can enforce the semantic that requesting a check on a null global 5694 * permission is automatically denied. (Internally a null permission 5695 * string is used when calling {@link #checkComponentPermission} in cases 5696 * when only uid-based security is needed.) 5697 * 5698 * This can be called with or without the global lock held. 5699 */ 5700 @Override 5701 public int checkPermission(String permission, int pid, int uid) { 5702 if (permission == null) { 5703 return PackageManager.PERMISSION_DENIED; 5704 } 5705 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5706 } 5707 5708 /** 5709 * Binder IPC calls go through the public entry point. 5710 * This can be called with or without the global lock held. 5711 */ 5712 int checkCallingPermission(String permission) { 5713 return checkPermission(permission, 5714 Binder.getCallingPid(), 5715 UserHandle.getAppId(Binder.getCallingUid())); 5716 } 5717 5718 /** 5719 * This can be called with or without the global lock held. 5720 */ 5721 void enforceCallingPermission(String permission, String func) { 5722 if (checkCallingPermission(permission) 5723 == PackageManager.PERMISSION_GRANTED) { 5724 return; 5725 } 5726 5727 String msg = "Permission Denial: " + func + " from pid=" 5728 + Binder.getCallingPid() 5729 + ", uid=" + Binder.getCallingUid() 5730 + " requires " + permission; 5731 Slog.w(TAG, msg); 5732 throw new SecurityException(msg); 5733 } 5734 5735 /** 5736 * Determine if UID is holding permissions required to access {@link Uri} in 5737 * the given {@link ProviderInfo}. Final permission checking is always done 5738 * in {@link ContentProvider}. 5739 */ 5740 private final boolean checkHoldingPermissionsLocked( 5741 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5742 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5743 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5744 5745 if (pi.applicationInfo.uid == uid) { 5746 return true; 5747 } else if (!pi.exported) { 5748 return false; 5749 } 5750 5751 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5752 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5753 try { 5754 // check if target holds top-level <provider> permissions 5755 if (!readMet && pi.readPermission != null 5756 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5757 readMet = true; 5758 } 5759 if (!writeMet && pi.writePermission != null 5760 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5761 writeMet = true; 5762 } 5763 5764 // track if unprotected read/write is allowed; any denied 5765 // <path-permission> below removes this ability 5766 boolean allowDefaultRead = pi.readPermission == null; 5767 boolean allowDefaultWrite = pi.writePermission == null; 5768 5769 // check if target holds any <path-permission> that match uri 5770 final PathPermission[] pps = pi.pathPermissions; 5771 if (pps != null) { 5772 final String path = uri.getPath(); 5773 int i = pps.length; 5774 while (i > 0 && (!readMet || !writeMet)) { 5775 i--; 5776 PathPermission pp = pps[i]; 5777 if (pp.match(path)) { 5778 if (!readMet) { 5779 final String pprperm = pp.getReadPermission(); 5780 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5781 + pprperm + " for " + pp.getPath() 5782 + ": match=" + pp.match(path) 5783 + " check=" + pm.checkUidPermission(pprperm, uid)); 5784 if (pprperm != null) { 5785 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5786 readMet = true; 5787 } else { 5788 allowDefaultRead = false; 5789 } 5790 } 5791 } 5792 if (!writeMet) { 5793 final String ppwperm = pp.getWritePermission(); 5794 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5795 + ppwperm + " for " + pp.getPath() 5796 + ": match=" + pp.match(path) 5797 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5798 if (ppwperm != null) { 5799 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5800 writeMet = true; 5801 } else { 5802 allowDefaultWrite = false; 5803 } 5804 } 5805 } 5806 } 5807 } 5808 } 5809 5810 // grant unprotected <provider> read/write, if not blocked by 5811 // <path-permission> above 5812 if (allowDefaultRead) readMet = true; 5813 if (allowDefaultWrite) writeMet = true; 5814 5815 } catch (RemoteException e) { 5816 return false; 5817 } 5818 5819 return readMet && writeMet; 5820 } 5821 5822 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5823 ProviderInfo pi = null; 5824 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5825 if (cpr != null) { 5826 pi = cpr.info; 5827 } else { 5828 try { 5829 pi = AppGlobals.getPackageManager().resolveContentProvider( 5830 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5831 } catch (RemoteException ex) { 5832 } 5833 } 5834 return pi; 5835 } 5836 5837 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5838 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5839 if (targetUris != null) { 5840 return targetUris.get(uri); 5841 } else { 5842 return null; 5843 } 5844 } 5845 5846 private UriPermission findOrCreateUriPermissionLocked( 5847 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5848 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5849 if (targetUris == null) { 5850 targetUris = Maps.newArrayMap(); 5851 mGrantedUriPermissions.put(targetUid, targetUris); 5852 } 5853 5854 UriPermission perm = targetUris.get(uri); 5855 if (perm == null) { 5856 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5857 targetUris.put(uri, perm); 5858 } 5859 5860 return perm; 5861 } 5862 5863 private final boolean checkUriPermissionLocked( 5864 Uri uri, int uid, int modeFlags, int minStrength) { 5865 // Root gets to do everything. 5866 if (uid == 0) { 5867 return true; 5868 } 5869 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5870 if (perms == null) return false; 5871 UriPermission perm = perms.get(uri); 5872 if (perm == null) return false; 5873 return perm.getStrength(modeFlags) >= minStrength; 5874 } 5875 5876 @Override 5877 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5878 enforceNotIsolatedCaller("checkUriPermission"); 5879 5880 // Another redirected-binder-call permissions check as in 5881 // {@link checkComponentPermission}. 5882 Identity tlsIdentity = sCallerIdentity.get(); 5883 if (tlsIdentity != null) { 5884 uid = tlsIdentity.uid; 5885 pid = tlsIdentity.pid; 5886 } 5887 5888 // Our own process gets to do everything. 5889 if (pid == MY_PID) { 5890 return PackageManager.PERMISSION_GRANTED; 5891 } 5892 synchronized(this) { 5893 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5894 ? PackageManager.PERMISSION_GRANTED 5895 : PackageManager.PERMISSION_DENIED; 5896 } 5897 } 5898 5899 /** 5900 * Check if the targetPkg can be granted permission to access uri by 5901 * the callingUid using the given modeFlags. Throws a security exception 5902 * if callingUid is not allowed to do this. Returns the uid of the target 5903 * if the URI permission grant should be performed; returns -1 if it is not 5904 * needed (for example targetPkg already has permission to access the URI). 5905 * If you already know the uid of the target, you can supply it in 5906 * lastTargetUid else set that to -1. 5907 */ 5908 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5909 Uri uri, int modeFlags, int lastTargetUid) { 5910 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5911 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5912 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5913 if (modeFlags == 0) { 5914 return -1; 5915 } 5916 5917 if (targetPkg != null) { 5918 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5919 "Checking grant " + targetPkg + " permission to " + uri); 5920 } 5921 5922 final IPackageManager pm = AppGlobals.getPackageManager(); 5923 5924 // If this is not a content: uri, we can't do anything with it. 5925 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5926 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5927 "Can't grant URI permission for non-content URI: " + uri); 5928 return -1; 5929 } 5930 5931 final String authority = uri.getAuthority(); 5932 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 5933 if (pi == null) { 5934 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5935 return -1; 5936 } 5937 5938 int targetUid = lastTargetUid; 5939 if (targetUid < 0 && targetPkg != null) { 5940 try { 5941 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5942 if (targetUid < 0) { 5943 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5944 "Can't grant URI permission no uid for: " + targetPkg); 5945 return -1; 5946 } 5947 } catch (RemoteException ex) { 5948 return -1; 5949 } 5950 } 5951 5952 if (targetUid >= 0) { 5953 // First... does the target actually need this permission? 5954 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5955 // No need to grant the target this permission. 5956 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5957 "Target " + targetPkg + " already has full permission to " + uri); 5958 return -1; 5959 } 5960 } else { 5961 // First... there is no target package, so can anyone access it? 5962 boolean allowed = pi.exported; 5963 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5964 if (pi.readPermission != null) { 5965 allowed = false; 5966 } 5967 } 5968 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5969 if (pi.writePermission != null) { 5970 allowed = false; 5971 } 5972 } 5973 if (allowed) { 5974 return -1; 5975 } 5976 } 5977 5978 // Second... is the provider allowing granting of URI permissions? 5979 if (!pi.grantUriPermissions) { 5980 throw new SecurityException("Provider " + pi.packageName 5981 + "/" + pi.name 5982 + " does not allow granting of Uri permissions (uri " 5983 + uri + ")"); 5984 } 5985 if (pi.uriPermissionPatterns != null) { 5986 final int N = pi.uriPermissionPatterns.length; 5987 boolean allowed = false; 5988 for (int i=0; i<N; i++) { 5989 if (pi.uriPermissionPatterns[i] != null 5990 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5991 allowed = true; 5992 break; 5993 } 5994 } 5995 if (!allowed) { 5996 throw new SecurityException("Provider " + pi.packageName 5997 + "/" + pi.name 5998 + " does not allow granting of permission to path of Uri " 5999 + uri); 6000 } 6001 } 6002 6003 // Third... does the caller itself have permission to access 6004 // this uri? 6005 if (callingUid != Process.myUid()) { 6006 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6007 // Require they hold a strong enough Uri permission 6008 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6009 : UriPermission.STRENGTH_OWNED; 6010 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6011 throw new SecurityException("Uid " + callingUid 6012 + " does not have permission to uri " + uri); 6013 } 6014 } 6015 } 6016 6017 return targetUid; 6018 } 6019 6020 @Override 6021 public int checkGrantUriPermission(int callingUid, String targetPkg, 6022 Uri uri, int modeFlags) { 6023 enforceNotIsolatedCaller("checkGrantUriPermission"); 6024 synchronized(this) { 6025 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6026 } 6027 } 6028 6029 void grantUriPermissionUncheckedLocked( 6030 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6031 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6032 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6033 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6034 if (modeFlags == 0) { 6035 return; 6036 } 6037 6038 // So here we are: the caller has the assumed permission 6039 // to the uri, and the target doesn't. Let's now give this to 6040 // the target. 6041 6042 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6043 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6044 6045 final String authority = uri.getAuthority(); 6046 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6047 if (pi == null) { 6048 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6049 return; 6050 } 6051 6052 final UriPermission perm = findOrCreateUriPermissionLocked( 6053 pi.packageName, targetPkg, targetUid, uri); 6054 perm.grantModes(modeFlags, persistable, owner); 6055 } 6056 6057 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6058 int modeFlags, UriPermissionOwner owner) { 6059 if (targetPkg == null) { 6060 throw new NullPointerException("targetPkg"); 6061 } 6062 6063 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6064 if (targetUid < 0) { 6065 return; 6066 } 6067 6068 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6069 } 6070 6071 static class NeededUriGrants extends ArrayList<Uri> { 6072 final String targetPkg; 6073 final int targetUid; 6074 final int flags; 6075 6076 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6077 this.targetPkg = targetPkg; 6078 this.targetUid = targetUid; 6079 this.flags = flags; 6080 } 6081 } 6082 6083 /** 6084 * Like checkGrantUriPermissionLocked, but takes an Intent. 6085 */ 6086 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6087 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6088 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6089 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6090 + " clip=" + (intent != null ? intent.getClipData() : null) 6091 + " from " + intent + "; flags=0x" 6092 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6093 6094 if (targetPkg == null) { 6095 throw new NullPointerException("targetPkg"); 6096 } 6097 6098 if (intent == null) { 6099 return null; 6100 } 6101 Uri data = intent.getData(); 6102 ClipData clip = intent.getClipData(); 6103 if (data == null && clip == null) { 6104 return null; 6105 } 6106 6107 if (data != null) { 6108 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6109 mode, needed != null ? needed.targetUid : -1); 6110 if (targetUid > 0) { 6111 if (needed == null) { 6112 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6113 } 6114 needed.add(data); 6115 } 6116 } 6117 if (clip != null) { 6118 for (int i=0; i<clip.getItemCount(); i++) { 6119 Uri uri = clip.getItemAt(i).getUri(); 6120 if (uri != null) { 6121 int targetUid = -1; 6122 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6123 mode, needed != null ? needed.targetUid : -1); 6124 if (targetUid > 0) { 6125 if (needed == null) { 6126 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6127 } 6128 needed.add(uri); 6129 } 6130 } else { 6131 Intent clipIntent = clip.getItemAt(i).getIntent(); 6132 if (clipIntent != null) { 6133 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6134 callingUid, targetPkg, clipIntent, mode, needed); 6135 if (newNeeded != null) { 6136 needed = newNeeded; 6137 } 6138 } 6139 } 6140 } 6141 } 6142 6143 return needed; 6144 } 6145 6146 /** 6147 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6148 */ 6149 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6150 UriPermissionOwner owner) { 6151 if (needed != null) { 6152 for (int i=0; i<needed.size(); i++) { 6153 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6154 needed.get(i), needed.flags, owner); 6155 } 6156 } 6157 } 6158 6159 void grantUriPermissionFromIntentLocked(int callingUid, 6160 String targetPkg, Intent intent, UriPermissionOwner owner) { 6161 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6162 intent, intent != null ? intent.getFlags() : 0, null); 6163 if (needed == null) { 6164 return; 6165 } 6166 6167 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6168 } 6169 6170 @Override 6171 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6172 Uri uri, int modeFlags) { 6173 enforceNotIsolatedCaller("grantUriPermission"); 6174 synchronized(this) { 6175 final ProcessRecord r = getRecordForAppLocked(caller); 6176 if (r == null) { 6177 throw new SecurityException("Unable to find app for caller " 6178 + caller 6179 + " when granting permission to uri " + uri); 6180 } 6181 if (targetPkg == null) { 6182 throw new IllegalArgumentException("null target"); 6183 } 6184 if (uri == null) { 6185 throw new IllegalArgumentException("null uri"); 6186 } 6187 6188 // Persistable only supported through Intents 6189 Preconditions.checkFlagsArgument(modeFlags, 6190 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6191 6192 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6193 null); 6194 } 6195 } 6196 6197 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6198 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6199 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6200 ArrayMap<Uri, UriPermission> perms 6201 = mGrantedUriPermissions.get(perm.targetUid); 6202 if (perms != null) { 6203 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6204 "Removing " + perm.targetUid + " permission to " + perm.uri); 6205 perms.remove(perm.uri); 6206 if (perms.size() == 0) { 6207 mGrantedUriPermissions.remove(perm.targetUid); 6208 } 6209 } 6210 } 6211 } 6212 6213 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6214 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6215 6216 final IPackageManager pm = AppGlobals.getPackageManager(); 6217 final String authority = uri.getAuthority(); 6218 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6219 if (pi == null) { 6220 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6221 return; 6222 } 6223 6224 // Does the caller have this permission on the URI? 6225 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6226 // Right now, if you are not the original owner of the permission, 6227 // you are not allowed to revoke it. 6228 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6229 throw new SecurityException("Uid " + callingUid 6230 + " does not have permission to uri " + uri); 6231 //} 6232 } 6233 6234 boolean persistChanged = false; 6235 6236 // Go through all of the permissions and remove any that match. 6237 final List<String> SEGMENTS = uri.getPathSegments(); 6238 if (SEGMENTS != null) { 6239 final int NS = SEGMENTS.size(); 6240 int N = mGrantedUriPermissions.size(); 6241 for (int i=0; i<N; i++) { 6242 ArrayMap<Uri, UriPermission> perms 6243 = mGrantedUriPermissions.valueAt(i); 6244 Iterator<UriPermission> it = perms.values().iterator(); 6245 toploop: 6246 while (it.hasNext()) { 6247 UriPermission perm = it.next(); 6248 Uri targetUri = perm.uri; 6249 if (!authority.equals(targetUri.getAuthority())) { 6250 continue; 6251 } 6252 List<String> targetSegments = targetUri.getPathSegments(); 6253 if (targetSegments == null) { 6254 continue; 6255 } 6256 if (targetSegments.size() < NS) { 6257 continue; 6258 } 6259 for (int j=0; j<NS; j++) { 6260 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6261 continue toploop; 6262 } 6263 } 6264 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6265 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6266 persistChanged |= perm.clearModes(modeFlags, true); 6267 if (perm.modeFlags == 0) { 6268 it.remove(); 6269 } 6270 } 6271 if (perms.size() == 0) { 6272 mGrantedUriPermissions.remove( 6273 mGrantedUriPermissions.keyAt(i)); 6274 N--; 6275 i--; 6276 } 6277 } 6278 } 6279 6280 if (persistChanged) { 6281 schedulePersistUriGrants(); 6282 } 6283 } 6284 6285 @Override 6286 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6287 int modeFlags) { 6288 enforceNotIsolatedCaller("revokeUriPermission"); 6289 synchronized(this) { 6290 final ProcessRecord r = getRecordForAppLocked(caller); 6291 if (r == null) { 6292 throw new SecurityException("Unable to find app for caller " 6293 + caller 6294 + " when revoking permission to uri " + uri); 6295 } 6296 if (uri == null) { 6297 Slog.w(TAG, "revokeUriPermission: null uri"); 6298 return; 6299 } 6300 6301 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6302 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6303 if (modeFlags == 0) { 6304 return; 6305 } 6306 6307 final IPackageManager pm = AppGlobals.getPackageManager(); 6308 final String authority = uri.getAuthority(); 6309 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6310 if (pi == null) { 6311 Slog.w(TAG, "No content provider found for permission revoke: " 6312 + uri.toSafeString()); 6313 return; 6314 } 6315 6316 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6317 } 6318 } 6319 6320 /** 6321 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6322 * given package. 6323 * 6324 * @param packageName Package name to match, or {@code null} to apply to all 6325 * packages. 6326 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6327 * to all users. 6328 * @param persistable If persistable grants should be removed. 6329 */ 6330 private void removeUriPermissionsForPackageLocked( 6331 String packageName, int userHandle, boolean persistable) { 6332 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6333 throw new IllegalArgumentException("Must narrow by either package or user"); 6334 } 6335 6336 boolean persistChanged = false; 6337 6338 final int size = mGrantedUriPermissions.size(); 6339 for (int i = 0; i < size; i++) { 6340 // Only inspect grants matching user 6341 if (userHandle == UserHandle.USER_ALL 6342 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6343 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6344 .values().iterator(); 6345 while (it.hasNext()) { 6346 final UriPermission perm = it.next(); 6347 6348 // Only inspect grants matching package 6349 if (packageName == null || perm.sourcePkg.equals(packageName) 6350 || perm.targetPkg.equals(packageName)) { 6351 persistChanged |= perm.clearModes(~0, persistable); 6352 6353 // Only remove when no modes remain; any persisted grants 6354 // will keep this alive. 6355 if (perm.modeFlags == 0) { 6356 it.remove(); 6357 } 6358 } 6359 } 6360 } 6361 } 6362 6363 if (persistChanged) { 6364 schedulePersistUriGrants(); 6365 } 6366 } 6367 6368 @Override 6369 public IBinder newUriPermissionOwner(String name) { 6370 enforceNotIsolatedCaller("newUriPermissionOwner"); 6371 synchronized(this) { 6372 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6373 return owner.getExternalTokenLocked(); 6374 } 6375 } 6376 6377 @Override 6378 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6379 Uri uri, int modeFlags) { 6380 synchronized(this) { 6381 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6382 if (owner == null) { 6383 throw new IllegalArgumentException("Unknown owner: " + token); 6384 } 6385 if (fromUid != Binder.getCallingUid()) { 6386 if (Binder.getCallingUid() != Process.myUid()) { 6387 // Only system code can grant URI permissions on behalf 6388 // of other users. 6389 throw new SecurityException("nice try"); 6390 } 6391 } 6392 if (targetPkg == null) { 6393 throw new IllegalArgumentException("null target"); 6394 } 6395 if (uri == null) { 6396 throw new IllegalArgumentException("null uri"); 6397 } 6398 6399 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6400 } 6401 } 6402 6403 @Override 6404 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6405 synchronized(this) { 6406 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6407 if (owner == null) { 6408 throw new IllegalArgumentException("Unknown owner: " + token); 6409 } 6410 6411 if (uri == null) { 6412 owner.removeUriPermissionsLocked(mode); 6413 } else { 6414 owner.removeUriPermissionLocked(uri, mode); 6415 } 6416 } 6417 } 6418 6419 private void schedulePersistUriGrants() { 6420 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6421 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6422 10 * DateUtils.SECOND_IN_MILLIS); 6423 } 6424 } 6425 6426 private void writeGrantedUriPermissions() { 6427 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6428 6429 // Snapshot permissions so we can persist without lock 6430 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6431 synchronized (this) { 6432 final int size = mGrantedUriPermissions.size(); 6433 for (int i = 0 ; i < size; i++) { 6434 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6435 if (perm.persistedModeFlags != 0) { 6436 persist.add(perm.snapshot()); 6437 } 6438 } 6439 } 6440 } 6441 6442 FileOutputStream fos = null; 6443 try { 6444 fos = mGrantFile.startWrite(); 6445 6446 XmlSerializer out = new FastXmlSerializer(); 6447 out.setOutput(fos, "utf-8"); 6448 out.startDocument(null, true); 6449 out.startTag(null, TAG_URI_GRANTS); 6450 for (UriPermission.Snapshot perm : persist) { 6451 out.startTag(null, TAG_URI_GRANT); 6452 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6453 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6454 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6455 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6456 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6457 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6458 out.endTag(null, TAG_URI_GRANT); 6459 } 6460 out.endTag(null, TAG_URI_GRANTS); 6461 out.endDocument(); 6462 6463 mGrantFile.finishWrite(fos); 6464 } catch (IOException e) { 6465 if (fos != null) { 6466 mGrantFile.failWrite(fos); 6467 } 6468 } 6469 } 6470 6471 private void readGrantedUriPermissionsLocked() { 6472 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6473 6474 final long now = System.currentTimeMillis(); 6475 6476 FileInputStream fis = null; 6477 try { 6478 fis = mGrantFile.openRead(); 6479 final XmlPullParser in = Xml.newPullParser(); 6480 in.setInput(fis, null); 6481 6482 int type; 6483 while ((type = in.next()) != END_DOCUMENT) { 6484 final String tag = in.getName(); 6485 if (type == START_TAG) { 6486 if (TAG_URI_GRANT.equals(tag)) { 6487 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6488 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6489 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6490 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6491 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6492 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6493 6494 // Sanity check that provider still belongs to source package 6495 final ProviderInfo pi = getProviderInfoLocked( 6496 uri.getAuthority(), userHandle); 6497 if (pi != null && sourcePkg.equals(pi.packageName)) { 6498 int targetUid = -1; 6499 try { 6500 targetUid = AppGlobals.getPackageManager() 6501 .getPackageUid(targetPkg, userHandle); 6502 } catch (RemoteException e) { 6503 } 6504 if (targetUid != -1) { 6505 final UriPermission perm = findOrCreateUriPermissionLocked( 6506 sourcePkg, targetPkg, targetUid, uri); 6507 perm.initPersistedModes(modeFlags, createdTime); 6508 } 6509 } else { 6510 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6511 + " but instead found " + pi); 6512 } 6513 } 6514 } 6515 } 6516 } catch (FileNotFoundException e) { 6517 // Missing grants is okay 6518 } catch (IOException e) { 6519 Log.wtf(TAG, "Failed reading Uri grants", e); 6520 } catch (XmlPullParserException e) { 6521 Log.wtf(TAG, "Failed reading Uri grants", e); 6522 } finally { 6523 IoUtils.closeQuietly(fis); 6524 } 6525 } 6526 6527 @Override 6528 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6529 enforceNotIsolatedCaller("takePersistableUriPermission"); 6530 6531 Preconditions.checkFlagsArgument(modeFlags, 6532 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6533 6534 synchronized (this) { 6535 final int callingUid = Binder.getCallingUid(); 6536 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6537 if (perm == null) { 6538 throw new SecurityException("No permission grant found for UID " + callingUid 6539 + " and Uri " + uri.toSafeString()); 6540 } 6541 6542 boolean persistChanged = perm.takePersistableModes(modeFlags); 6543 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6544 6545 if (persistChanged) { 6546 schedulePersistUriGrants(); 6547 } 6548 } 6549 } 6550 6551 @Override 6552 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6553 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6554 6555 Preconditions.checkFlagsArgument(modeFlags, 6556 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6557 6558 synchronized (this) { 6559 final int callingUid = Binder.getCallingUid(); 6560 6561 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6562 if (perm == null) { 6563 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6564 + uri.toSafeString()); 6565 return; 6566 } 6567 6568 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6569 removeUriPermissionIfNeededLocked(perm); 6570 if (persistChanged) { 6571 schedulePersistUriGrants(); 6572 } 6573 } 6574 } 6575 6576 /** 6577 * Prune any older {@link UriPermission} for the given UID until outstanding 6578 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6579 * 6580 * @return if any mutations occured that require persisting. 6581 */ 6582 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6583 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6584 if (perms == null) return false; 6585 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6586 6587 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6588 for (UriPermission perm : perms.values()) { 6589 if (perm.persistedModeFlags != 0) { 6590 persisted.add(perm); 6591 } 6592 } 6593 6594 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6595 if (trimCount <= 0) return false; 6596 6597 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6598 for (int i = 0; i < trimCount; i++) { 6599 final UriPermission perm = persisted.get(i); 6600 6601 if (DEBUG_URI_PERMISSION) { 6602 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6603 } 6604 6605 perm.releasePersistableModes(~0); 6606 removeUriPermissionIfNeededLocked(perm); 6607 } 6608 6609 return true; 6610 } 6611 6612 @Override 6613 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6614 String packageName, boolean incoming) { 6615 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6616 Preconditions.checkNotNull(packageName, "packageName"); 6617 6618 final int callingUid = Binder.getCallingUid(); 6619 final IPackageManager pm = AppGlobals.getPackageManager(); 6620 try { 6621 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6622 if (packageUid != callingUid) { 6623 throw new SecurityException( 6624 "Package " + packageName + " does not belong to calling UID " + callingUid); 6625 } 6626 } catch (RemoteException e) { 6627 throw new SecurityException("Failed to verify package name ownership"); 6628 } 6629 6630 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6631 synchronized (this) { 6632 if (incoming) { 6633 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6634 if (perms == null) { 6635 Slog.w(TAG, "No permission grants found for " + packageName); 6636 } else { 6637 final int size = perms.size(); 6638 for (int i = 0; i < size; i++) { 6639 final UriPermission perm = perms.valueAt(i); 6640 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6641 result.add(perm.buildPersistedPublicApiObject()); 6642 } 6643 } 6644 } 6645 } else { 6646 final int size = mGrantedUriPermissions.size(); 6647 for (int i = 0; i < size; i++) { 6648 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6649 final int permsSize = perms.size(); 6650 for (int j = 0; j < permsSize; j++) { 6651 final UriPermission perm = perms.valueAt(j); 6652 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6653 result.add(perm.buildPersistedPublicApiObject()); 6654 } 6655 } 6656 } 6657 } 6658 } 6659 return new ParceledListSlice<android.content.UriPermission>(result); 6660 } 6661 6662 @Override 6663 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6664 synchronized (this) { 6665 ProcessRecord app = 6666 who != null ? getRecordForAppLocked(who) : null; 6667 if (app == null) return; 6668 6669 Message msg = Message.obtain(); 6670 msg.what = WAIT_FOR_DEBUGGER_MSG; 6671 msg.obj = app; 6672 msg.arg1 = waiting ? 1 : 0; 6673 mHandler.sendMessage(msg); 6674 } 6675 } 6676 6677 @Override 6678 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6679 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6680 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6681 outInfo.availMem = Process.getFreeMemory(); 6682 outInfo.totalMem = Process.getTotalMemory(); 6683 outInfo.threshold = homeAppMem; 6684 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6685 outInfo.hiddenAppThreshold = cachedAppMem; 6686 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6687 ProcessList.SERVICE_ADJ); 6688 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6689 ProcessList.VISIBLE_APP_ADJ); 6690 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6691 ProcessList.FOREGROUND_APP_ADJ); 6692 } 6693 6694 // ========================================================= 6695 // TASK MANAGEMENT 6696 // ========================================================= 6697 6698 @Override 6699 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6700 IThumbnailReceiver receiver) { 6701 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6702 6703 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6704 ActivityRecord topRecord = null; 6705 6706 synchronized(this) { 6707 if (localLOGV) Slog.v( 6708 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6709 + ", receiver=" + receiver); 6710 6711 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6712 != PackageManager.PERMISSION_GRANTED) { 6713 if (receiver != null) { 6714 // If the caller wants to wait for pending thumbnails, 6715 // it ain't gonna get them. 6716 try { 6717 receiver.finished(); 6718 } catch (RemoteException ex) { 6719 } 6720 } 6721 String msg = "Permission Denial: getTasks() from pid=" 6722 + Binder.getCallingPid() 6723 + ", uid=" + Binder.getCallingUid() 6724 + " requires " + android.Manifest.permission.GET_TASKS; 6725 Slog.w(TAG, msg); 6726 throw new SecurityException(msg); 6727 } 6728 6729 // TODO: Improve with MRU list from all ActivityStacks. 6730 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6731 6732 if (!pending.pendingRecords.isEmpty()) { 6733 mPendingThumbnails.add(pending); 6734 } 6735 } 6736 6737 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6738 6739 if (topRecord != null) { 6740 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6741 try { 6742 IApplicationThread topThumbnail = topRecord.app.thread; 6743 topThumbnail.requestThumbnail(topRecord.appToken); 6744 } catch (Exception e) { 6745 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6746 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6747 } 6748 } 6749 6750 if (pending == null && receiver != null) { 6751 // In this case all thumbnails were available and the client 6752 // is being asked to be told when the remaining ones come in... 6753 // which is unusually, since the top-most currently running 6754 // activity should never have a canned thumbnail! Oh well. 6755 try { 6756 receiver.finished(); 6757 } catch (RemoteException ex) { 6758 } 6759 } 6760 6761 return list; 6762 } 6763 6764 TaskRecord getMostRecentTask() { 6765 return mRecentTasks.get(0); 6766 } 6767 6768 @Override 6769 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6770 int flags, int userId) { 6771 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6772 false, true, "getRecentTasks", null); 6773 6774 synchronized (this) { 6775 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6776 "getRecentTasks()"); 6777 final boolean detailed = checkCallingPermission( 6778 android.Manifest.permission.GET_DETAILED_TASKS) 6779 == PackageManager.PERMISSION_GRANTED; 6780 6781 IPackageManager pm = AppGlobals.getPackageManager(); 6782 6783 final int N = mRecentTasks.size(); 6784 ArrayList<ActivityManager.RecentTaskInfo> res 6785 = new ArrayList<ActivityManager.RecentTaskInfo>( 6786 maxNum < N ? maxNum : N); 6787 for (int i=0; i<N && maxNum > 0; i++) { 6788 TaskRecord tr = mRecentTasks.get(i); 6789 // Only add calling user's recent tasks 6790 if (tr.userId != userId) continue; 6791 // Return the entry if desired by the caller. We always return 6792 // the first entry, because callers always expect this to be the 6793 // foreground app. We may filter others if the caller has 6794 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6795 // we should exclude the entry. 6796 6797 if (i == 0 6798 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6799 || (tr.intent == null) 6800 || ((tr.intent.getFlags() 6801 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6802 ActivityManager.RecentTaskInfo rti 6803 = new ActivityManager.RecentTaskInfo(); 6804 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6805 rti.persistentId = tr.taskId; 6806 rti.baseIntent = new Intent( 6807 tr.intent != null ? tr.intent : tr.affinityIntent); 6808 if (!detailed) { 6809 rti.baseIntent.replaceExtras((Bundle)null); 6810 } 6811 rti.origActivity = tr.origActivity; 6812 rti.description = tr.lastDescription; 6813 rti.stackId = tr.stack.mStackId; 6814 6815 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6816 // Check whether this activity is currently available. 6817 try { 6818 if (rti.origActivity != null) { 6819 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6820 == null) { 6821 continue; 6822 } 6823 } else if (rti.baseIntent != null) { 6824 if (pm.queryIntentActivities(rti.baseIntent, 6825 null, 0, userId) == null) { 6826 continue; 6827 } 6828 } 6829 } catch (RemoteException e) { 6830 // Will never happen. 6831 } 6832 } 6833 6834 res.add(rti); 6835 maxNum--; 6836 } 6837 } 6838 return res; 6839 } 6840 } 6841 6842 private TaskRecord recentTaskForIdLocked(int id) { 6843 final int N = mRecentTasks.size(); 6844 for (int i=0; i<N; i++) { 6845 TaskRecord tr = mRecentTasks.get(i); 6846 if (tr.taskId == id) { 6847 return tr; 6848 } 6849 } 6850 return null; 6851 } 6852 6853 @Override 6854 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6855 synchronized (this) { 6856 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6857 "getTaskThumbnails()"); 6858 TaskRecord tr = recentTaskForIdLocked(id); 6859 if (tr != null) { 6860 return tr.getTaskThumbnailsLocked(); 6861 } 6862 } 6863 return null; 6864 } 6865 6866 @Override 6867 public Bitmap getTaskTopThumbnail(int id) { 6868 synchronized (this) { 6869 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6870 "getTaskTopThumbnail()"); 6871 TaskRecord tr = recentTaskForIdLocked(id); 6872 if (tr != null) { 6873 return tr.getTaskTopThumbnailLocked(); 6874 } 6875 } 6876 return null; 6877 } 6878 6879 @Override 6880 public boolean removeSubTask(int taskId, int subTaskIndex) { 6881 synchronized (this) { 6882 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6883 "removeSubTask()"); 6884 long ident = Binder.clearCallingIdentity(); 6885 try { 6886 TaskRecord tr = recentTaskForIdLocked(taskId); 6887 if (tr != null) { 6888 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6889 } 6890 return false; 6891 } finally { 6892 Binder.restoreCallingIdentity(ident); 6893 } 6894 } 6895 } 6896 6897 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6898 if (!pr.killedByAm) { 6899 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6900 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6901 pr.processName, pr.setAdj, reason); 6902 pr.killedByAm = true; 6903 Process.killProcessQuiet(pr.pid); 6904 } 6905 } 6906 6907 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6908 tr.disposeThumbnail(); 6909 mRecentTasks.remove(tr); 6910 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6911 Intent baseIntent = new Intent( 6912 tr.intent != null ? tr.intent : tr.affinityIntent); 6913 ComponentName component = baseIntent.getComponent(); 6914 if (component == null) { 6915 Slog.w(TAG, "Now component for base intent of task: " + tr); 6916 return; 6917 } 6918 6919 // Find any running services associated with this app. 6920 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6921 6922 if (killProcesses) { 6923 // Find any running processes associated with this app. 6924 final String pkg = component.getPackageName(); 6925 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6926 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 6927 for (int i=0; i<pmap.size(); i++) { 6928 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 6929 for (int j=0; j<uids.size(); j++) { 6930 ProcessRecord proc = uids.valueAt(j); 6931 if (proc.userId != tr.userId) { 6932 continue; 6933 } 6934 if (!proc.pkgList.containsKey(pkg)) { 6935 continue; 6936 } 6937 procs.add(proc); 6938 } 6939 } 6940 6941 // Kill the running processes. 6942 for (int i=0; i<procs.size(); i++) { 6943 ProcessRecord pr = procs.get(i); 6944 if (pr == mHomeProcess) { 6945 // Don't kill the home process along with tasks from the same package. 6946 continue; 6947 } 6948 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 6949 killUnneededProcessLocked(pr, "remove task"); 6950 } else { 6951 pr.waitingToKill = "remove task"; 6952 } 6953 } 6954 } 6955 } 6956 6957 @Override 6958 public boolean removeTask(int taskId, int flags) { 6959 synchronized (this) { 6960 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6961 "removeTask()"); 6962 long ident = Binder.clearCallingIdentity(); 6963 try { 6964 TaskRecord tr = recentTaskForIdLocked(taskId); 6965 if (tr != null) { 6966 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 6967 if (r != null) { 6968 cleanUpRemovedTaskLocked(tr, flags); 6969 return true; 6970 } 6971 if (tr.mActivities.size() == 0) { 6972 // Caller is just removing a recent task that is 6973 // not actively running. That is easy! 6974 cleanUpRemovedTaskLocked(tr, flags); 6975 return true; 6976 } 6977 Slog.w(TAG, "removeTask: task " + taskId 6978 + " does not have activities to remove, " 6979 + " but numActivities=" + tr.numActivities 6980 + ": " + tr); 6981 } 6982 } finally { 6983 Binder.restoreCallingIdentity(ident); 6984 } 6985 } 6986 return false; 6987 } 6988 6989 /** 6990 * TODO: Add mController hook 6991 */ 6992 @Override 6993 public void moveTaskToFront(int task, int flags, Bundle options) { 6994 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6995 "moveTaskToFront()"); 6996 6997 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task); 6998 synchronized(this) { 6999 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7000 Binder.getCallingUid(), "Task to front")) { 7001 ActivityOptions.abort(options); 7002 return; 7003 } 7004 final long origId = Binder.clearCallingIdentity(); 7005 try { 7006 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7007 } finally { 7008 Binder.restoreCallingIdentity(origId); 7009 } 7010 ActivityOptions.abort(options); 7011 } 7012 } 7013 7014 @Override 7015 public void moveTaskToBack(int taskId) { 7016 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7017 "moveTaskToBack()"); 7018 7019 synchronized(this) { 7020 TaskRecord tr = recentTaskForIdLocked(taskId); 7021 if (tr != null) { 7022 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7023 ActivityStack stack = tr.stack; 7024 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7025 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7026 Binder.getCallingUid(), "Task to back")) { 7027 return; 7028 } 7029 } 7030 final long origId = Binder.clearCallingIdentity(); 7031 try { 7032 stack.moveTaskToBackLocked(taskId, null); 7033 } finally { 7034 Binder.restoreCallingIdentity(origId); 7035 } 7036 } 7037 } 7038 } 7039 7040 /** 7041 * Moves an activity, and all of the other activities within the same task, to the bottom 7042 * of the history stack. The activity's order within the task is unchanged. 7043 * 7044 * @param token A reference to the activity we wish to move 7045 * @param nonRoot If false then this only works if the activity is the root 7046 * of a task; if true it will work for any activity in a task. 7047 * @return Returns true if the move completed, false if not. 7048 */ 7049 @Override 7050 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7051 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7052 synchronized(this) { 7053 final long origId = Binder.clearCallingIdentity(); 7054 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7055 if (taskId >= 0) { 7056 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7057 } 7058 Binder.restoreCallingIdentity(origId); 7059 } 7060 return false; 7061 } 7062 7063 @Override 7064 public void moveTaskBackwards(int task) { 7065 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7066 "moveTaskBackwards()"); 7067 7068 synchronized(this) { 7069 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7070 Binder.getCallingUid(), "Task backwards")) { 7071 return; 7072 } 7073 final long origId = Binder.clearCallingIdentity(); 7074 moveTaskBackwardsLocked(task); 7075 Binder.restoreCallingIdentity(origId); 7076 } 7077 } 7078 7079 private final void moveTaskBackwardsLocked(int task) { 7080 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7081 } 7082 7083 @Override 7084 public IBinder getHomeActivityToken() throws RemoteException { 7085 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7086 "getHomeActivityToken()"); 7087 synchronized (this) { 7088 return mStackSupervisor.getHomeActivityToken(); 7089 } 7090 } 7091 7092 @Override 7093 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7094 IActivityContainerCallback callback) throws RemoteException { 7095 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7096 "createActivityContainer()"); 7097 synchronized (this) { 7098 if (parentActivityToken == null) { 7099 throw new IllegalArgumentException("parent token must not be null"); 7100 } 7101 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7102 if (r == null) { 7103 return null; 7104 } 7105 return mStackSupervisor.createActivityContainer(r, callback); 7106 } 7107 } 7108 7109 @Override 7110 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7111 throws RemoteException { 7112 synchronized (this) { 7113 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7114 if (stack != null) { 7115 return stack.mActivityContainer; 7116 } 7117 return null; 7118 } 7119 } 7120 7121 @Override 7122 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7123 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7124 "moveTaskToStack()"); 7125 if (stackId == HOME_STACK_ID) { 7126 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7127 new RuntimeException("here").fillInStackTrace()); 7128 } 7129 synchronized (this) { 7130 long ident = Binder.clearCallingIdentity(); 7131 try { 7132 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7133 + stackId + " toTop=" + toTop); 7134 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7135 } finally { 7136 Binder.restoreCallingIdentity(ident); 7137 } 7138 } 7139 } 7140 7141 @Override 7142 public void resizeStack(int stackBoxId, Rect bounds) { 7143 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7144 "resizeStackBox()"); 7145 long ident = Binder.clearCallingIdentity(); 7146 try { 7147 mWindowManager.resizeStack(stackBoxId, bounds); 7148 } finally { 7149 Binder.restoreCallingIdentity(ident); 7150 } 7151 } 7152 7153 @Override 7154 public List<StackInfo> getAllStackInfos() { 7155 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7156 "getAllStackInfos()"); 7157 long ident = Binder.clearCallingIdentity(); 7158 try { 7159 synchronized (this) { 7160 return mStackSupervisor.getAllStackInfosLocked(); 7161 } 7162 } finally { 7163 Binder.restoreCallingIdentity(ident); 7164 } 7165 } 7166 7167 @Override 7168 public StackInfo getStackInfo(int stackId) { 7169 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7170 "getStackInfo()"); 7171 long ident = Binder.clearCallingIdentity(); 7172 try { 7173 synchronized (this) { 7174 return mStackSupervisor.getStackInfoLocked(stackId); 7175 } 7176 } finally { 7177 Binder.restoreCallingIdentity(ident); 7178 } 7179 } 7180 7181 @Override 7182 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7183 synchronized(this) { 7184 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7185 } 7186 } 7187 7188 // ========================================================= 7189 // THUMBNAILS 7190 // ========================================================= 7191 7192 public void reportThumbnail(IBinder token, 7193 Bitmap thumbnail, CharSequence description) { 7194 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7195 final long origId = Binder.clearCallingIdentity(); 7196 sendPendingThumbnail(null, token, thumbnail, description, true); 7197 Binder.restoreCallingIdentity(origId); 7198 } 7199 7200 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7201 Bitmap thumbnail, CharSequence description, boolean always) { 7202 TaskRecord task; 7203 ArrayList<PendingThumbnailsRecord> receivers = null; 7204 7205 //System.out.println("Send pending thumbnail: " + r); 7206 7207 synchronized(this) { 7208 if (r == null) { 7209 r = ActivityRecord.isInStackLocked(token); 7210 if (r == null) { 7211 return; 7212 } 7213 } 7214 if (thumbnail == null && r.thumbHolder != null) { 7215 thumbnail = r.thumbHolder.lastThumbnail; 7216 description = r.thumbHolder.lastDescription; 7217 } 7218 if (thumbnail == null && !always) { 7219 // If there is no thumbnail, and this entry is not actually 7220 // going away, then abort for now and pick up the next 7221 // thumbnail we get. 7222 return; 7223 } 7224 task = r.task; 7225 7226 int N = mPendingThumbnails.size(); 7227 int i=0; 7228 while (i<N) { 7229 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7230 //System.out.println("Looking in " + pr.pendingRecords); 7231 if (pr.pendingRecords.remove(r)) { 7232 if (receivers == null) { 7233 receivers = new ArrayList<PendingThumbnailsRecord>(); 7234 } 7235 receivers.add(pr); 7236 if (pr.pendingRecords.size() == 0) { 7237 pr.finished = true; 7238 mPendingThumbnails.remove(i); 7239 N--; 7240 continue; 7241 } 7242 } 7243 i++; 7244 } 7245 } 7246 7247 if (receivers != null) { 7248 final int N = receivers.size(); 7249 for (int i=0; i<N; i++) { 7250 try { 7251 PendingThumbnailsRecord pr = receivers.get(i); 7252 pr.receiver.newThumbnail( 7253 task != null ? task.taskId : -1, thumbnail, description); 7254 if (pr.finished) { 7255 pr.receiver.finished(); 7256 } 7257 } catch (Exception e) { 7258 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7259 } 7260 } 7261 } 7262 } 7263 7264 // ========================================================= 7265 // CONTENT PROVIDERS 7266 // ========================================================= 7267 7268 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7269 List<ProviderInfo> providers = null; 7270 try { 7271 providers = AppGlobals.getPackageManager(). 7272 queryContentProviders(app.processName, app.uid, 7273 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7274 } catch (RemoteException ex) { 7275 } 7276 if (DEBUG_MU) 7277 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7278 int userId = app.userId; 7279 if (providers != null) { 7280 int N = providers.size(); 7281 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7282 for (int i=0; i<N; i++) { 7283 ProviderInfo cpi = 7284 (ProviderInfo)providers.get(i); 7285 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7286 cpi.name, cpi.flags); 7287 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7288 // This is a singleton provider, but a user besides the 7289 // default user is asking to initialize a process it runs 7290 // in... well, no, it doesn't actually run in this process, 7291 // it runs in the process of the default user. Get rid of it. 7292 providers.remove(i); 7293 N--; 7294 i--; 7295 continue; 7296 } 7297 7298 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7299 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7300 if (cpr == null) { 7301 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7302 mProviderMap.putProviderByClass(comp, cpr); 7303 } 7304 if (DEBUG_MU) 7305 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7306 app.pubProviders.put(cpi.name, cpr); 7307 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7308 // Don't add this if it is a platform component that is marked 7309 // to run in multiple processes, because this is actually 7310 // part of the framework so doesn't make sense to track as a 7311 // separate apk in the process. 7312 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7313 } 7314 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7315 } 7316 } 7317 return providers; 7318 } 7319 7320 /** 7321 * Check if {@link ProcessRecord} has a possible chance at accessing the 7322 * given {@link ProviderInfo}. Final permission checking is always done 7323 * in {@link ContentProvider}. 7324 */ 7325 private final String checkContentProviderPermissionLocked( 7326 ProviderInfo cpi, ProcessRecord r) { 7327 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7328 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7329 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7330 cpi.applicationInfo.uid, cpi.exported) 7331 == PackageManager.PERMISSION_GRANTED) { 7332 return null; 7333 } 7334 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7335 cpi.applicationInfo.uid, cpi.exported) 7336 == PackageManager.PERMISSION_GRANTED) { 7337 return null; 7338 } 7339 7340 PathPermission[] pps = cpi.pathPermissions; 7341 if (pps != null) { 7342 int i = pps.length; 7343 while (i > 0) { 7344 i--; 7345 PathPermission pp = pps[i]; 7346 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7347 cpi.applicationInfo.uid, cpi.exported) 7348 == PackageManager.PERMISSION_GRANTED) { 7349 return null; 7350 } 7351 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7352 cpi.applicationInfo.uid, cpi.exported) 7353 == PackageManager.PERMISSION_GRANTED) { 7354 return null; 7355 } 7356 } 7357 } 7358 7359 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7360 if (perms != null) { 7361 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7362 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7363 return null; 7364 } 7365 } 7366 } 7367 7368 String msg; 7369 if (!cpi.exported) { 7370 msg = "Permission Denial: opening provider " + cpi.name 7371 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7372 + ", uid=" + callingUid + ") that is not exported from uid " 7373 + cpi.applicationInfo.uid; 7374 } else { 7375 msg = "Permission Denial: opening provider " + cpi.name 7376 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7377 + ", uid=" + callingUid + ") requires " 7378 + cpi.readPermission + " or " + cpi.writePermission; 7379 } 7380 Slog.w(TAG, msg); 7381 return msg; 7382 } 7383 7384 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7385 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7386 if (r != null) { 7387 for (int i=0; i<r.conProviders.size(); i++) { 7388 ContentProviderConnection conn = r.conProviders.get(i); 7389 if (conn.provider == cpr) { 7390 if (DEBUG_PROVIDER) Slog.v(TAG, 7391 "Adding provider requested by " 7392 + r.processName + " from process " 7393 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7394 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7395 if (stable) { 7396 conn.stableCount++; 7397 conn.numStableIncs++; 7398 } else { 7399 conn.unstableCount++; 7400 conn.numUnstableIncs++; 7401 } 7402 return conn; 7403 } 7404 } 7405 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7406 if (stable) { 7407 conn.stableCount = 1; 7408 conn.numStableIncs = 1; 7409 } else { 7410 conn.unstableCount = 1; 7411 conn.numUnstableIncs = 1; 7412 } 7413 cpr.connections.add(conn); 7414 r.conProviders.add(conn); 7415 return conn; 7416 } 7417 cpr.addExternalProcessHandleLocked(externalProcessToken); 7418 return null; 7419 } 7420 7421 boolean decProviderCountLocked(ContentProviderConnection conn, 7422 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7423 if (conn != null) { 7424 cpr = conn.provider; 7425 if (DEBUG_PROVIDER) Slog.v(TAG, 7426 "Removing provider requested by " 7427 + conn.client.processName + " from process " 7428 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7429 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7430 if (stable) { 7431 conn.stableCount--; 7432 } else { 7433 conn.unstableCount--; 7434 } 7435 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7436 cpr.connections.remove(conn); 7437 conn.client.conProviders.remove(conn); 7438 return true; 7439 } 7440 return false; 7441 } 7442 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7443 return false; 7444 } 7445 7446 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7447 String name, IBinder token, boolean stable, int userId) { 7448 ContentProviderRecord cpr; 7449 ContentProviderConnection conn = null; 7450 ProviderInfo cpi = null; 7451 7452 synchronized(this) { 7453 ProcessRecord r = null; 7454 if (caller != null) { 7455 r = getRecordForAppLocked(caller); 7456 if (r == null) { 7457 throw new SecurityException( 7458 "Unable to find app for caller " + caller 7459 + " (pid=" + Binder.getCallingPid() 7460 + ") when getting content provider " + name); 7461 } 7462 } 7463 7464 // First check if this content provider has been published... 7465 cpr = mProviderMap.getProviderByName(name, userId); 7466 boolean providerRunning = cpr != null; 7467 if (providerRunning) { 7468 cpi = cpr.info; 7469 String msg; 7470 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7471 throw new SecurityException(msg); 7472 } 7473 7474 if (r != null && cpr.canRunHere(r)) { 7475 // This provider has been published or is in the process 7476 // of being published... but it is also allowed to run 7477 // in the caller's process, so don't make a connection 7478 // and just let the caller instantiate its own instance. 7479 ContentProviderHolder holder = cpr.newHolder(null); 7480 // don't give caller the provider object, it needs 7481 // to make its own. 7482 holder.provider = null; 7483 return holder; 7484 } 7485 7486 final long origId = Binder.clearCallingIdentity(); 7487 7488 // In this case the provider instance already exists, so we can 7489 // return it right away. 7490 conn = incProviderCountLocked(r, cpr, token, stable); 7491 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7492 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7493 // If this is a perceptible app accessing the provider, 7494 // make sure to count it as being accessed and thus 7495 // back up on the LRU list. This is good because 7496 // content providers are often expensive to start. 7497 updateLruProcessLocked(cpr.proc, false, null); 7498 } 7499 } 7500 7501 if (cpr.proc != null) { 7502 if (false) { 7503 if (cpr.name.flattenToShortString().equals( 7504 "com.android.providers.calendar/.CalendarProvider2")) { 7505 Slog.v(TAG, "****************** KILLING " 7506 + cpr.name.flattenToShortString()); 7507 Process.killProcess(cpr.proc.pid); 7508 } 7509 } 7510 boolean success = updateOomAdjLocked(cpr.proc); 7511 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7512 // NOTE: there is still a race here where a signal could be 7513 // pending on the process even though we managed to update its 7514 // adj level. Not sure what to do about this, but at least 7515 // the race is now smaller. 7516 if (!success) { 7517 // Uh oh... it looks like the provider's process 7518 // has been killed on us. We need to wait for a new 7519 // process to be started, and make sure its death 7520 // doesn't kill our process. 7521 Slog.i(TAG, 7522 "Existing provider " + cpr.name.flattenToShortString() 7523 + " is crashing; detaching " + r); 7524 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7525 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7526 if (!lastRef) { 7527 // This wasn't the last ref our process had on 7528 // the provider... we have now been killed, bail. 7529 return null; 7530 } 7531 providerRunning = false; 7532 conn = null; 7533 } 7534 } 7535 7536 Binder.restoreCallingIdentity(origId); 7537 } 7538 7539 boolean singleton; 7540 if (!providerRunning) { 7541 try { 7542 cpi = AppGlobals.getPackageManager(). 7543 resolveContentProvider(name, 7544 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7545 } catch (RemoteException ex) { 7546 } 7547 if (cpi == null) { 7548 return null; 7549 } 7550 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7551 cpi.name, cpi.flags); 7552 if (singleton) { 7553 userId = 0; 7554 } 7555 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7556 7557 String msg; 7558 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7559 throw new SecurityException(msg); 7560 } 7561 7562 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7563 && !cpi.processName.equals("system")) { 7564 // If this content provider does not run in the system 7565 // process, and the system is not yet ready to run other 7566 // processes, then fail fast instead of hanging. 7567 throw new IllegalArgumentException( 7568 "Attempt to launch content provider before system ready"); 7569 } 7570 7571 // Make sure that the user who owns this provider is started. If not, 7572 // we don't want to allow it to run. 7573 if (mStartedUsers.get(userId) == null) { 7574 Slog.w(TAG, "Unable to launch app " 7575 + cpi.applicationInfo.packageName + "/" 7576 + cpi.applicationInfo.uid + " for provider " 7577 + name + ": user " + userId + " is stopped"); 7578 return null; 7579 } 7580 7581 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7582 cpr = mProviderMap.getProviderByClass(comp, userId); 7583 final boolean firstClass = cpr == null; 7584 if (firstClass) { 7585 try { 7586 ApplicationInfo ai = 7587 AppGlobals.getPackageManager(). 7588 getApplicationInfo( 7589 cpi.applicationInfo.packageName, 7590 STOCK_PM_FLAGS, userId); 7591 if (ai == null) { 7592 Slog.w(TAG, "No package info for content provider " 7593 + cpi.name); 7594 return null; 7595 } 7596 ai = getAppInfoForUser(ai, userId); 7597 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7598 } catch (RemoteException ex) { 7599 // pm is in same process, this will never happen. 7600 } 7601 } 7602 7603 if (r != null && cpr.canRunHere(r)) { 7604 // If this is a multiprocess provider, then just return its 7605 // info and allow the caller to instantiate it. Only do 7606 // this if the provider is the same user as the caller's 7607 // process, or can run as root (so can be in any process). 7608 return cpr.newHolder(null); 7609 } 7610 7611 if (DEBUG_PROVIDER) { 7612 RuntimeException e = new RuntimeException("here"); 7613 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7614 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7615 } 7616 7617 // This is single process, and our app is now connecting to it. 7618 // See if we are already in the process of launching this 7619 // provider. 7620 final int N = mLaunchingProviders.size(); 7621 int i; 7622 for (i=0; i<N; i++) { 7623 if (mLaunchingProviders.get(i) == cpr) { 7624 break; 7625 } 7626 } 7627 7628 // If the provider is not already being launched, then get it 7629 // started. 7630 if (i >= N) { 7631 final long origId = Binder.clearCallingIdentity(); 7632 7633 try { 7634 // Content provider is now in use, its package can't be stopped. 7635 try { 7636 AppGlobals.getPackageManager().setPackageStoppedState( 7637 cpr.appInfo.packageName, false, userId); 7638 } catch (RemoteException e) { 7639 } catch (IllegalArgumentException e) { 7640 Slog.w(TAG, "Failed trying to unstop package " 7641 + cpr.appInfo.packageName + ": " + e); 7642 } 7643 7644 // Use existing process if already started 7645 ProcessRecord proc = getProcessRecordLocked( 7646 cpi.processName, cpr.appInfo.uid, false); 7647 if (proc != null && proc.thread != null) { 7648 if (DEBUG_PROVIDER) { 7649 Slog.d(TAG, "Installing in existing process " + proc); 7650 } 7651 proc.pubProviders.put(cpi.name, cpr); 7652 try { 7653 proc.thread.scheduleInstallProvider(cpi); 7654 } catch (RemoteException e) { 7655 } 7656 } else { 7657 proc = startProcessLocked(cpi.processName, 7658 cpr.appInfo, false, 0, "content provider", 7659 new ComponentName(cpi.applicationInfo.packageName, 7660 cpi.name), false, false, false); 7661 if (proc == null) { 7662 Slog.w(TAG, "Unable to launch app " 7663 + cpi.applicationInfo.packageName + "/" 7664 + cpi.applicationInfo.uid + " for provider " 7665 + name + ": process is bad"); 7666 return null; 7667 } 7668 } 7669 cpr.launchingApp = proc; 7670 mLaunchingProviders.add(cpr); 7671 } finally { 7672 Binder.restoreCallingIdentity(origId); 7673 } 7674 } 7675 7676 // Make sure the provider is published (the same provider class 7677 // may be published under multiple names). 7678 if (firstClass) { 7679 mProviderMap.putProviderByClass(comp, cpr); 7680 } 7681 7682 mProviderMap.putProviderByName(name, cpr); 7683 conn = incProviderCountLocked(r, cpr, token, stable); 7684 if (conn != null) { 7685 conn.waiting = true; 7686 } 7687 } 7688 } 7689 7690 // Wait for the provider to be published... 7691 synchronized (cpr) { 7692 while (cpr.provider == null) { 7693 if (cpr.launchingApp == null) { 7694 Slog.w(TAG, "Unable to launch app " 7695 + cpi.applicationInfo.packageName + "/" 7696 + cpi.applicationInfo.uid + " for provider " 7697 + name + ": launching app became null"); 7698 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7699 UserHandle.getUserId(cpi.applicationInfo.uid), 7700 cpi.applicationInfo.packageName, 7701 cpi.applicationInfo.uid, name); 7702 return null; 7703 } 7704 try { 7705 if (DEBUG_MU) { 7706 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7707 + cpr.launchingApp); 7708 } 7709 if (conn != null) { 7710 conn.waiting = true; 7711 } 7712 cpr.wait(); 7713 } catch (InterruptedException ex) { 7714 } finally { 7715 if (conn != null) { 7716 conn.waiting = false; 7717 } 7718 } 7719 } 7720 } 7721 return cpr != null ? cpr.newHolder(conn) : null; 7722 } 7723 7724 public final ContentProviderHolder getContentProvider( 7725 IApplicationThread caller, String name, int userId, boolean stable) { 7726 enforceNotIsolatedCaller("getContentProvider"); 7727 if (caller == null) { 7728 String msg = "null IApplicationThread when getting content provider " 7729 + name; 7730 Slog.w(TAG, msg); 7731 throw new SecurityException(msg); 7732 } 7733 7734 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7735 false, true, "getContentProvider", null); 7736 return getContentProviderImpl(caller, name, null, stable, userId); 7737 } 7738 7739 public ContentProviderHolder getContentProviderExternal( 7740 String name, int userId, IBinder token) { 7741 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7742 "Do not have permission in call getContentProviderExternal()"); 7743 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7744 false, true, "getContentProvider", null); 7745 return getContentProviderExternalUnchecked(name, token, userId); 7746 } 7747 7748 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7749 IBinder token, int userId) { 7750 return getContentProviderImpl(null, name, token, true, userId); 7751 } 7752 7753 /** 7754 * Drop a content provider from a ProcessRecord's bookkeeping 7755 */ 7756 public void removeContentProvider(IBinder connection, boolean stable) { 7757 enforceNotIsolatedCaller("removeContentProvider"); 7758 long ident = Binder.clearCallingIdentity(); 7759 try { 7760 synchronized (this) { 7761 ContentProviderConnection conn; 7762 try { 7763 conn = (ContentProviderConnection)connection; 7764 } catch (ClassCastException e) { 7765 String msg ="removeContentProvider: " + connection 7766 + " not a ContentProviderConnection"; 7767 Slog.w(TAG, msg); 7768 throw new IllegalArgumentException(msg); 7769 } 7770 if (conn == null) { 7771 throw new NullPointerException("connection is null"); 7772 } 7773 if (decProviderCountLocked(conn, null, null, stable)) { 7774 updateOomAdjLocked(); 7775 } 7776 } 7777 } finally { 7778 Binder.restoreCallingIdentity(ident); 7779 } 7780 } 7781 7782 public void removeContentProviderExternal(String name, IBinder token) { 7783 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7784 "Do not have permission in call removeContentProviderExternal()"); 7785 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7786 } 7787 7788 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7789 synchronized (this) { 7790 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7791 if(cpr == null) { 7792 //remove from mProvidersByClass 7793 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7794 return; 7795 } 7796 7797 //update content provider record entry info 7798 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7799 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7800 if (localCpr.hasExternalProcessHandles()) { 7801 if (localCpr.removeExternalProcessHandleLocked(token)) { 7802 updateOomAdjLocked(); 7803 } else { 7804 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7805 + " with no external reference for token: " 7806 + token + "."); 7807 } 7808 } else { 7809 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7810 + " with no external references."); 7811 } 7812 } 7813 } 7814 7815 public final void publishContentProviders(IApplicationThread caller, 7816 List<ContentProviderHolder> providers) { 7817 if (providers == null) { 7818 return; 7819 } 7820 7821 enforceNotIsolatedCaller("publishContentProviders"); 7822 synchronized (this) { 7823 final ProcessRecord r = getRecordForAppLocked(caller); 7824 if (DEBUG_MU) 7825 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 7826 if (r == null) { 7827 throw new SecurityException( 7828 "Unable to find app for caller " + caller 7829 + " (pid=" + Binder.getCallingPid() 7830 + ") when publishing content providers"); 7831 } 7832 7833 final long origId = Binder.clearCallingIdentity(); 7834 7835 final int N = providers.size(); 7836 for (int i=0; i<N; i++) { 7837 ContentProviderHolder src = providers.get(i); 7838 if (src == null || src.info == null || src.provider == null) { 7839 continue; 7840 } 7841 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 7842 if (DEBUG_MU) 7843 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 7844 if (dst != null) { 7845 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 7846 mProviderMap.putProviderByClass(comp, dst); 7847 String names[] = dst.info.authority.split(";"); 7848 for (int j = 0; j < names.length; j++) { 7849 mProviderMap.putProviderByName(names[j], dst); 7850 } 7851 7852 int NL = mLaunchingProviders.size(); 7853 int j; 7854 for (j=0; j<NL; j++) { 7855 if (mLaunchingProviders.get(j) == dst) { 7856 mLaunchingProviders.remove(j); 7857 j--; 7858 NL--; 7859 } 7860 } 7861 synchronized (dst) { 7862 dst.provider = src.provider; 7863 dst.proc = r; 7864 dst.notifyAll(); 7865 } 7866 updateOomAdjLocked(r); 7867 } 7868 } 7869 7870 Binder.restoreCallingIdentity(origId); 7871 } 7872 } 7873 7874 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 7875 ContentProviderConnection conn; 7876 try { 7877 conn = (ContentProviderConnection)connection; 7878 } catch (ClassCastException e) { 7879 String msg ="refContentProvider: " + connection 7880 + " not a ContentProviderConnection"; 7881 Slog.w(TAG, msg); 7882 throw new IllegalArgumentException(msg); 7883 } 7884 if (conn == null) { 7885 throw new NullPointerException("connection is null"); 7886 } 7887 7888 synchronized (this) { 7889 if (stable > 0) { 7890 conn.numStableIncs += stable; 7891 } 7892 stable = conn.stableCount + stable; 7893 if (stable < 0) { 7894 throw new IllegalStateException("stableCount < 0: " + stable); 7895 } 7896 7897 if (unstable > 0) { 7898 conn.numUnstableIncs += unstable; 7899 } 7900 unstable = conn.unstableCount + unstable; 7901 if (unstable < 0) { 7902 throw new IllegalStateException("unstableCount < 0: " + unstable); 7903 } 7904 7905 if ((stable+unstable) <= 0) { 7906 throw new IllegalStateException("ref counts can't go to zero here: stable=" 7907 + stable + " unstable=" + unstable); 7908 } 7909 conn.stableCount = stable; 7910 conn.unstableCount = unstable; 7911 return !conn.dead; 7912 } 7913 } 7914 7915 public void unstableProviderDied(IBinder connection) { 7916 ContentProviderConnection conn; 7917 try { 7918 conn = (ContentProviderConnection)connection; 7919 } catch (ClassCastException e) { 7920 String msg ="refContentProvider: " + connection 7921 + " not a ContentProviderConnection"; 7922 Slog.w(TAG, msg); 7923 throw new IllegalArgumentException(msg); 7924 } 7925 if (conn == null) { 7926 throw new NullPointerException("connection is null"); 7927 } 7928 7929 // Safely retrieve the content provider associated with the connection. 7930 IContentProvider provider; 7931 synchronized (this) { 7932 provider = conn.provider.provider; 7933 } 7934 7935 if (provider == null) { 7936 // Um, yeah, we're way ahead of you. 7937 return; 7938 } 7939 7940 // Make sure the caller is being honest with us. 7941 if (provider.asBinder().pingBinder()) { 7942 // Er, no, still looks good to us. 7943 synchronized (this) { 7944 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 7945 + " says " + conn + " died, but we don't agree"); 7946 return; 7947 } 7948 } 7949 7950 // Well look at that! It's dead! 7951 synchronized (this) { 7952 if (conn.provider.provider != provider) { 7953 // But something changed... good enough. 7954 return; 7955 } 7956 7957 ProcessRecord proc = conn.provider.proc; 7958 if (proc == null || proc.thread == null) { 7959 // Seems like the process is already cleaned up. 7960 return; 7961 } 7962 7963 // As far as we're concerned, this is just like receiving a 7964 // death notification... just a bit prematurely. 7965 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 7966 + ") early provider death"); 7967 final long ident = Binder.clearCallingIdentity(); 7968 try { 7969 appDiedLocked(proc, proc.pid, proc.thread); 7970 } finally { 7971 Binder.restoreCallingIdentity(ident); 7972 } 7973 } 7974 } 7975 7976 @Override 7977 public void appNotRespondingViaProvider(IBinder connection) { 7978 enforceCallingPermission( 7979 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 7980 7981 final ContentProviderConnection conn = (ContentProviderConnection) connection; 7982 if (conn == null) { 7983 Slog.w(TAG, "ContentProviderConnection is null"); 7984 return; 7985 } 7986 7987 final ProcessRecord host = conn.provider.proc; 7988 if (host == null) { 7989 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 7990 return; 7991 } 7992 7993 final long token = Binder.clearCallingIdentity(); 7994 try { 7995 appNotResponding(host, null, null, false, "ContentProvider not responding"); 7996 } finally { 7997 Binder.restoreCallingIdentity(token); 7998 } 7999 } 8000 8001 public final void installSystemProviders() { 8002 List<ProviderInfo> providers; 8003 synchronized (this) { 8004 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8005 providers = generateApplicationProvidersLocked(app); 8006 if (providers != null) { 8007 for (int i=providers.size()-1; i>=0; i--) { 8008 ProviderInfo pi = (ProviderInfo)providers.get(i); 8009 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8010 Slog.w(TAG, "Not installing system proc provider " + pi.name 8011 + ": not system .apk"); 8012 providers.remove(i); 8013 } 8014 } 8015 } 8016 } 8017 if (providers != null) { 8018 mSystemThread.installSystemProviders(providers); 8019 } 8020 8021 mCoreSettingsObserver = new CoreSettingsObserver(this); 8022 8023 mUsageStatsService.monitorPackages(); 8024 } 8025 8026 /** 8027 * Allows app to retrieve the MIME type of a URI without having permission 8028 * to access its content provider. 8029 * 8030 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8031 * 8032 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8033 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8034 */ 8035 public String getProviderMimeType(Uri uri, int userId) { 8036 enforceNotIsolatedCaller("getProviderMimeType"); 8037 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8038 userId, false, true, "getProviderMimeType", null); 8039 final String name = uri.getAuthority(); 8040 final long ident = Binder.clearCallingIdentity(); 8041 ContentProviderHolder holder = null; 8042 8043 try { 8044 holder = getContentProviderExternalUnchecked(name, null, userId); 8045 if (holder != null) { 8046 return holder.provider.getType(uri); 8047 } 8048 } catch (RemoteException e) { 8049 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8050 return null; 8051 } finally { 8052 if (holder != null) { 8053 removeContentProviderExternalUnchecked(name, null, userId); 8054 } 8055 Binder.restoreCallingIdentity(ident); 8056 } 8057 8058 return null; 8059 } 8060 8061 // ========================================================= 8062 // GLOBAL MANAGEMENT 8063 // ========================================================= 8064 8065 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8066 boolean isolated) { 8067 String proc = customProcess != null ? customProcess : info.processName; 8068 BatteryStatsImpl.Uid.Proc ps = null; 8069 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8070 int uid = info.uid; 8071 if (isolated) { 8072 int userId = UserHandle.getUserId(uid); 8073 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8074 while (true) { 8075 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8076 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8077 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8078 } 8079 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8080 mNextIsolatedProcessUid++; 8081 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8082 // No process for this uid, use it. 8083 break; 8084 } 8085 stepsLeft--; 8086 if (stepsLeft <= 0) { 8087 return null; 8088 } 8089 } 8090 } 8091 return new ProcessRecord(stats, info, proc, uid); 8092 } 8093 8094 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8095 ProcessRecord app; 8096 if (!isolated) { 8097 app = getProcessRecordLocked(info.processName, info.uid, true); 8098 } else { 8099 app = null; 8100 } 8101 8102 if (app == null) { 8103 app = newProcessRecordLocked(info, null, isolated); 8104 mProcessNames.put(info.processName, app.uid, app); 8105 if (isolated) { 8106 mIsolatedProcesses.put(app.uid, app); 8107 } 8108 updateLruProcessLocked(app, false, null); 8109 updateOomAdjLocked(); 8110 } 8111 8112 // This package really, really can not be stopped. 8113 try { 8114 AppGlobals.getPackageManager().setPackageStoppedState( 8115 info.packageName, false, UserHandle.getUserId(app.uid)); 8116 } catch (RemoteException e) { 8117 } catch (IllegalArgumentException e) { 8118 Slog.w(TAG, "Failed trying to unstop package " 8119 + info.packageName + ": " + e); 8120 } 8121 8122 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8123 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8124 app.persistent = true; 8125 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8126 } 8127 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8128 mPersistentStartingProcesses.add(app); 8129 startProcessLocked(app, "added application", app.processName); 8130 } 8131 8132 return app; 8133 } 8134 8135 public void unhandledBack() { 8136 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8137 "unhandledBack()"); 8138 8139 synchronized(this) { 8140 final long origId = Binder.clearCallingIdentity(); 8141 try { 8142 getFocusedStack().unhandledBackLocked(); 8143 } finally { 8144 Binder.restoreCallingIdentity(origId); 8145 } 8146 } 8147 } 8148 8149 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8150 enforceNotIsolatedCaller("openContentUri"); 8151 final int userId = UserHandle.getCallingUserId(); 8152 String name = uri.getAuthority(); 8153 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8154 ParcelFileDescriptor pfd = null; 8155 if (cph != null) { 8156 // We record the binder invoker's uid in thread-local storage before 8157 // going to the content provider to open the file. Later, in the code 8158 // that handles all permissions checks, we look for this uid and use 8159 // that rather than the Activity Manager's own uid. The effect is that 8160 // we do the check against the caller's permissions even though it looks 8161 // to the content provider like the Activity Manager itself is making 8162 // the request. 8163 sCallerIdentity.set(new Identity( 8164 Binder.getCallingPid(), Binder.getCallingUid())); 8165 try { 8166 pfd = cph.provider.openFile(null, uri, "r", null); 8167 } catch (FileNotFoundException e) { 8168 // do nothing; pfd will be returned null 8169 } finally { 8170 // Ensure that whatever happens, we clean up the identity state 8171 sCallerIdentity.remove(); 8172 } 8173 8174 // We've got the fd now, so we're done with the provider. 8175 removeContentProviderExternalUnchecked(name, null, userId); 8176 } else { 8177 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8178 } 8179 return pfd; 8180 } 8181 8182 // Actually is sleeping or shutting down or whatever else in the future 8183 // is an inactive state. 8184 public boolean isSleepingOrShuttingDown() { 8185 return mSleeping || mShuttingDown; 8186 } 8187 8188 public void goingToSleep() { 8189 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8190 != PackageManager.PERMISSION_GRANTED) { 8191 throw new SecurityException("Requires permission " 8192 + android.Manifest.permission.DEVICE_POWER); 8193 } 8194 8195 synchronized(this) { 8196 mWentToSleep = true; 8197 updateEventDispatchingLocked(); 8198 8199 if (!mSleeping) { 8200 mSleeping = true; 8201 mStackSupervisor.goingToSleepLocked(); 8202 8203 // Initialize the wake times of all processes. 8204 checkExcessivePowerUsageLocked(false); 8205 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8206 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8207 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8208 } 8209 } 8210 } 8211 8212 @Override 8213 public boolean shutdown(int timeout) { 8214 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8215 != PackageManager.PERMISSION_GRANTED) { 8216 throw new SecurityException("Requires permission " 8217 + android.Manifest.permission.SHUTDOWN); 8218 } 8219 8220 boolean timedout = false; 8221 8222 synchronized(this) { 8223 mShuttingDown = true; 8224 updateEventDispatchingLocked(); 8225 timedout = mStackSupervisor.shutdownLocked(timeout); 8226 } 8227 8228 mAppOpsService.shutdown(); 8229 mUsageStatsService.shutdown(); 8230 mBatteryStatsService.shutdown(); 8231 synchronized (this) { 8232 mProcessStats.shutdownLocked(); 8233 } 8234 8235 return timedout; 8236 } 8237 8238 public final void activitySlept(IBinder token) { 8239 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8240 8241 final long origId = Binder.clearCallingIdentity(); 8242 8243 synchronized (this) { 8244 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8245 if (r != null) { 8246 mStackSupervisor.activitySleptLocked(r); 8247 } 8248 } 8249 8250 Binder.restoreCallingIdentity(origId); 8251 } 8252 8253 void logLockScreen(String msg) { 8254 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8255 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8256 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8257 mStackSupervisor.mDismissKeyguardOnNextActivity); 8258 } 8259 8260 private void comeOutOfSleepIfNeededLocked() { 8261 if (!mWentToSleep && !mLockScreenShown) { 8262 if (mSleeping) { 8263 mSleeping = false; 8264 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8265 } 8266 } 8267 } 8268 8269 public void wakingUp() { 8270 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8271 != PackageManager.PERMISSION_GRANTED) { 8272 throw new SecurityException("Requires permission " 8273 + android.Manifest.permission.DEVICE_POWER); 8274 } 8275 8276 synchronized(this) { 8277 mWentToSleep = false; 8278 updateEventDispatchingLocked(); 8279 comeOutOfSleepIfNeededLocked(); 8280 } 8281 } 8282 8283 private void updateEventDispatchingLocked() { 8284 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8285 } 8286 8287 public void setLockScreenShown(boolean shown) { 8288 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8289 != PackageManager.PERMISSION_GRANTED) { 8290 throw new SecurityException("Requires permission " 8291 + android.Manifest.permission.DEVICE_POWER); 8292 } 8293 8294 synchronized(this) { 8295 long ident = Binder.clearCallingIdentity(); 8296 try { 8297 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8298 mLockScreenShown = shown; 8299 comeOutOfSleepIfNeededLocked(); 8300 } finally { 8301 Binder.restoreCallingIdentity(ident); 8302 } 8303 } 8304 } 8305 8306 public void stopAppSwitches() { 8307 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8308 != PackageManager.PERMISSION_GRANTED) { 8309 throw new SecurityException("Requires permission " 8310 + android.Manifest.permission.STOP_APP_SWITCHES); 8311 } 8312 8313 synchronized(this) { 8314 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8315 + APP_SWITCH_DELAY_TIME; 8316 mDidAppSwitch = false; 8317 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8318 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8319 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8320 } 8321 } 8322 8323 public void resumeAppSwitches() { 8324 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8325 != PackageManager.PERMISSION_GRANTED) { 8326 throw new SecurityException("Requires permission " 8327 + android.Manifest.permission.STOP_APP_SWITCHES); 8328 } 8329 8330 synchronized(this) { 8331 // Note that we don't execute any pending app switches... we will 8332 // let those wait until either the timeout, or the next start 8333 // activity request. 8334 mAppSwitchesAllowedTime = 0; 8335 } 8336 } 8337 8338 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8339 String name) { 8340 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8341 return true; 8342 } 8343 8344 final int perm = checkComponentPermission( 8345 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8346 callingUid, -1, true); 8347 if (perm == PackageManager.PERMISSION_GRANTED) { 8348 return true; 8349 } 8350 8351 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8352 return false; 8353 } 8354 8355 public void setDebugApp(String packageName, boolean waitForDebugger, 8356 boolean persistent) { 8357 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8358 "setDebugApp()"); 8359 8360 long ident = Binder.clearCallingIdentity(); 8361 try { 8362 // Note that this is not really thread safe if there are multiple 8363 // callers into it at the same time, but that's not a situation we 8364 // care about. 8365 if (persistent) { 8366 final ContentResolver resolver = mContext.getContentResolver(); 8367 Settings.Global.putString( 8368 resolver, Settings.Global.DEBUG_APP, 8369 packageName); 8370 Settings.Global.putInt( 8371 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8372 waitForDebugger ? 1 : 0); 8373 } 8374 8375 synchronized (this) { 8376 if (!persistent) { 8377 mOrigDebugApp = mDebugApp; 8378 mOrigWaitForDebugger = mWaitForDebugger; 8379 } 8380 mDebugApp = packageName; 8381 mWaitForDebugger = waitForDebugger; 8382 mDebugTransient = !persistent; 8383 if (packageName != null) { 8384 forceStopPackageLocked(packageName, -1, false, false, true, true, 8385 false, UserHandle.USER_ALL, "set debug app"); 8386 } 8387 } 8388 } finally { 8389 Binder.restoreCallingIdentity(ident); 8390 } 8391 } 8392 8393 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8394 synchronized (this) { 8395 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8396 if (!isDebuggable) { 8397 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8398 throw new SecurityException("Process not debuggable: " + app.packageName); 8399 } 8400 } 8401 8402 mOpenGlTraceApp = processName; 8403 } 8404 } 8405 8406 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8407 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8408 synchronized (this) { 8409 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8410 if (!isDebuggable) { 8411 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8412 throw new SecurityException("Process not debuggable: " + app.packageName); 8413 } 8414 } 8415 mProfileApp = processName; 8416 mProfileFile = profileFile; 8417 if (mProfileFd != null) { 8418 try { 8419 mProfileFd.close(); 8420 } catch (IOException e) { 8421 } 8422 mProfileFd = null; 8423 } 8424 mProfileFd = profileFd; 8425 mProfileType = 0; 8426 mAutoStopProfiler = autoStopProfiler; 8427 } 8428 } 8429 8430 @Override 8431 public void setAlwaysFinish(boolean enabled) { 8432 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8433 "setAlwaysFinish()"); 8434 8435 Settings.Global.putInt( 8436 mContext.getContentResolver(), 8437 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8438 8439 synchronized (this) { 8440 mAlwaysFinishActivities = enabled; 8441 } 8442 } 8443 8444 @Override 8445 public void setActivityController(IActivityController controller) { 8446 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8447 "setActivityController()"); 8448 synchronized (this) { 8449 mController = controller; 8450 Watchdog.getInstance().setActivityController(controller); 8451 } 8452 } 8453 8454 @Override 8455 public void setUserIsMonkey(boolean userIsMonkey) { 8456 synchronized (this) { 8457 synchronized (mPidsSelfLocked) { 8458 final int callingPid = Binder.getCallingPid(); 8459 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8460 if (precessRecord == null) { 8461 throw new SecurityException("Unknown process: " + callingPid); 8462 } 8463 if (precessRecord.instrumentationUiAutomationConnection == null) { 8464 throw new SecurityException("Only an instrumentation process " 8465 + "with a UiAutomation can call setUserIsMonkey"); 8466 } 8467 } 8468 mUserIsMonkey = userIsMonkey; 8469 } 8470 } 8471 8472 @Override 8473 public boolean isUserAMonkey() { 8474 synchronized (this) { 8475 // If there is a controller also implies the user is a monkey. 8476 return (mUserIsMonkey || mController != null); 8477 } 8478 } 8479 8480 public void requestBugReport() { 8481 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8482 SystemProperties.set("ctl.start", "bugreport"); 8483 } 8484 8485 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8486 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8487 } 8488 8489 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8490 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8491 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8492 } 8493 return KEY_DISPATCHING_TIMEOUT; 8494 } 8495 8496 @Override 8497 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8498 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8499 != PackageManager.PERMISSION_GRANTED) { 8500 throw new SecurityException("Requires permission " 8501 + android.Manifest.permission.FILTER_EVENTS); 8502 } 8503 ProcessRecord proc; 8504 long timeout; 8505 synchronized (this) { 8506 synchronized (mPidsSelfLocked) { 8507 proc = mPidsSelfLocked.get(pid); 8508 } 8509 timeout = getInputDispatchingTimeoutLocked(proc); 8510 } 8511 8512 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8513 return -1; 8514 } 8515 8516 return timeout; 8517 } 8518 8519 /** 8520 * Handle input dispatching timeouts. 8521 * Returns whether input dispatching should be aborted or not. 8522 */ 8523 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8524 final ActivityRecord activity, final ActivityRecord parent, 8525 final boolean aboveSystem, String reason) { 8526 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8527 != PackageManager.PERMISSION_GRANTED) { 8528 throw new SecurityException("Requires permission " 8529 + android.Manifest.permission.FILTER_EVENTS); 8530 } 8531 8532 final String annotation; 8533 if (reason == null) { 8534 annotation = "Input dispatching timed out"; 8535 } else { 8536 annotation = "Input dispatching timed out (" + reason + ")"; 8537 } 8538 8539 if (proc != null) { 8540 synchronized (this) { 8541 if (proc.debugging) { 8542 return false; 8543 } 8544 8545 if (mDidDexOpt) { 8546 // Give more time since we were dexopting. 8547 mDidDexOpt = false; 8548 return false; 8549 } 8550 8551 if (proc.instrumentationClass != null) { 8552 Bundle info = new Bundle(); 8553 info.putString("shortMsg", "keyDispatchingTimedOut"); 8554 info.putString("longMsg", annotation); 8555 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8556 return true; 8557 } 8558 } 8559 mHandler.post(new Runnable() { 8560 @Override 8561 public void run() { 8562 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8563 } 8564 }); 8565 } 8566 8567 return true; 8568 } 8569 8570 public Bundle getAssistContextExtras(int requestType) { 8571 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8572 "getAssistContextExtras()"); 8573 PendingAssistExtras pae; 8574 Bundle extras = new Bundle(); 8575 synchronized (this) { 8576 ActivityRecord activity = getFocusedStack().mResumedActivity; 8577 if (activity == null) { 8578 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8579 return null; 8580 } 8581 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8582 if (activity.app == null || activity.app.thread == null) { 8583 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8584 return extras; 8585 } 8586 if (activity.app.pid == Binder.getCallingPid()) { 8587 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8588 return extras; 8589 } 8590 pae = new PendingAssistExtras(activity); 8591 try { 8592 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8593 requestType); 8594 mPendingAssistExtras.add(pae); 8595 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8596 } catch (RemoteException e) { 8597 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8598 return extras; 8599 } 8600 } 8601 synchronized (pae) { 8602 while (!pae.haveResult) { 8603 try { 8604 pae.wait(); 8605 } catch (InterruptedException e) { 8606 } 8607 } 8608 if (pae.result != null) { 8609 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8610 } 8611 } 8612 synchronized (this) { 8613 mPendingAssistExtras.remove(pae); 8614 mHandler.removeCallbacks(pae); 8615 } 8616 return extras; 8617 } 8618 8619 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8620 PendingAssistExtras pae = (PendingAssistExtras)token; 8621 synchronized (pae) { 8622 pae.result = extras; 8623 pae.haveResult = true; 8624 pae.notifyAll(); 8625 } 8626 } 8627 8628 public void registerProcessObserver(IProcessObserver observer) { 8629 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8630 "registerProcessObserver()"); 8631 synchronized (this) { 8632 mProcessObservers.register(observer); 8633 } 8634 } 8635 8636 @Override 8637 public void unregisterProcessObserver(IProcessObserver observer) { 8638 synchronized (this) { 8639 mProcessObservers.unregister(observer); 8640 } 8641 } 8642 8643 @Override 8644 public boolean convertFromTranslucent(IBinder token) { 8645 final long origId = Binder.clearCallingIdentity(); 8646 try { 8647 synchronized (this) { 8648 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8649 if (r == null) { 8650 return false; 8651 } 8652 if (r.changeWindowTranslucency(true)) { 8653 mWindowManager.setAppFullscreen(token, true); 8654 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8655 return true; 8656 } 8657 return false; 8658 } 8659 } finally { 8660 Binder.restoreCallingIdentity(origId); 8661 } 8662 } 8663 8664 @Override 8665 public boolean convertToTranslucent(IBinder token) { 8666 final long origId = Binder.clearCallingIdentity(); 8667 try { 8668 synchronized (this) { 8669 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8670 if (r == null) { 8671 return false; 8672 } 8673 if (r.changeWindowTranslucency(false)) { 8674 r.task.stack.convertToTranslucent(r); 8675 mWindowManager.setAppFullscreen(token, false); 8676 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8677 return true; 8678 } 8679 return false; 8680 } 8681 } finally { 8682 Binder.restoreCallingIdentity(origId); 8683 } 8684 } 8685 8686 @Override 8687 public void setImmersive(IBinder token, boolean immersive) { 8688 synchronized(this) { 8689 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8690 if (r == null) { 8691 throw new IllegalArgumentException(); 8692 } 8693 r.immersive = immersive; 8694 8695 // update associated state if we're frontmost 8696 if (r == mFocusedActivity) { 8697 if (DEBUG_IMMERSIVE) { 8698 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8699 } 8700 applyUpdateLockStateLocked(r); 8701 } 8702 } 8703 } 8704 8705 @Override 8706 public boolean isImmersive(IBinder token) { 8707 synchronized (this) { 8708 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8709 if (r == null) { 8710 throw new IllegalArgumentException(); 8711 } 8712 return r.immersive; 8713 } 8714 } 8715 8716 public boolean isTopActivityImmersive() { 8717 enforceNotIsolatedCaller("startActivity"); 8718 synchronized (this) { 8719 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8720 return (r != null) ? r.immersive : false; 8721 } 8722 } 8723 8724 public final void enterSafeMode() { 8725 synchronized(this) { 8726 // It only makes sense to do this before the system is ready 8727 // and started launching other packages. 8728 if (!mSystemReady) { 8729 try { 8730 AppGlobals.getPackageManager().enterSafeMode(); 8731 } catch (RemoteException e) { 8732 } 8733 } 8734 } 8735 } 8736 8737 public final void showSafeModeOverlay() { 8738 View v = LayoutInflater.from(mContext).inflate( 8739 com.android.internal.R.layout.safe_mode, null); 8740 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8741 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8742 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8743 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8744 lp.gravity = Gravity.BOTTOM | Gravity.START; 8745 lp.format = v.getBackground().getOpacity(); 8746 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8747 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8748 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8749 ((WindowManager)mContext.getSystemService( 8750 Context.WINDOW_SERVICE)).addView(v, lp); 8751 } 8752 8753 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 8754 if (!(sender instanceof PendingIntentRecord)) { 8755 return; 8756 } 8757 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8758 synchronized (stats) { 8759 if (mBatteryStatsService.isOnBattery()) { 8760 mBatteryStatsService.enforceCallingPermission(); 8761 PendingIntentRecord rec = (PendingIntentRecord)sender; 8762 int MY_UID = Binder.getCallingUid(); 8763 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8764 BatteryStatsImpl.Uid.Pkg pkg = 8765 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 8766 sourcePkg != null ? sourcePkg : rec.key.packageName); 8767 pkg.incWakeupsLocked(); 8768 } 8769 } 8770 } 8771 8772 public boolean killPids(int[] pids, String pReason, boolean secure) { 8773 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8774 throw new SecurityException("killPids only available to the system"); 8775 } 8776 String reason = (pReason == null) ? "Unknown" : pReason; 8777 // XXX Note: don't acquire main activity lock here, because the window 8778 // manager calls in with its locks held. 8779 8780 boolean killed = false; 8781 synchronized (mPidsSelfLocked) { 8782 int[] types = new int[pids.length]; 8783 int worstType = 0; 8784 for (int i=0; i<pids.length; i++) { 8785 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8786 if (proc != null) { 8787 int type = proc.setAdj; 8788 types[i] = type; 8789 if (type > worstType) { 8790 worstType = type; 8791 } 8792 } 8793 } 8794 8795 // If the worst oom_adj is somewhere in the cached proc LRU range, 8796 // then constrain it so we will kill all cached procs. 8797 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8798 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8799 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8800 } 8801 8802 // If this is not a secure call, don't let it kill processes that 8803 // are important. 8804 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8805 worstType = ProcessList.SERVICE_ADJ; 8806 } 8807 8808 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8809 for (int i=0; i<pids.length; i++) { 8810 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8811 if (proc == null) { 8812 continue; 8813 } 8814 int adj = proc.setAdj; 8815 if (adj >= worstType && !proc.killedByAm) { 8816 killUnneededProcessLocked(proc, reason); 8817 killed = true; 8818 } 8819 } 8820 } 8821 return killed; 8822 } 8823 8824 @Override 8825 public void killUid(int uid, String reason) { 8826 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8827 throw new SecurityException("killUid only available to the system"); 8828 } 8829 synchronized (this) { 8830 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 8831 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 8832 reason != null ? reason : "kill uid"); 8833 } 8834 } 8835 8836 @Override 8837 public boolean killProcessesBelowForeground(String reason) { 8838 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8839 throw new SecurityException("killProcessesBelowForeground() only available to system"); 8840 } 8841 8842 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 8843 } 8844 8845 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 8846 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8847 throw new SecurityException("killProcessesBelowAdj() only available to system"); 8848 } 8849 8850 boolean killed = false; 8851 synchronized (mPidsSelfLocked) { 8852 final int size = mPidsSelfLocked.size(); 8853 for (int i = 0; i < size; i++) { 8854 final int pid = mPidsSelfLocked.keyAt(i); 8855 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8856 if (proc == null) continue; 8857 8858 final int adj = proc.setAdj; 8859 if (adj > belowAdj && !proc.killedByAm) { 8860 killUnneededProcessLocked(proc, reason); 8861 killed = true; 8862 } 8863 } 8864 } 8865 return killed; 8866 } 8867 8868 @Override 8869 public void hang(final IBinder who, boolean allowRestart) { 8870 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8871 != PackageManager.PERMISSION_GRANTED) { 8872 throw new SecurityException("Requires permission " 8873 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8874 } 8875 8876 final IBinder.DeathRecipient death = new DeathRecipient() { 8877 @Override 8878 public void binderDied() { 8879 synchronized (this) { 8880 notifyAll(); 8881 } 8882 } 8883 }; 8884 8885 try { 8886 who.linkToDeath(death, 0); 8887 } catch (RemoteException e) { 8888 Slog.w(TAG, "hang: given caller IBinder is already dead."); 8889 return; 8890 } 8891 8892 synchronized (this) { 8893 Watchdog.getInstance().setAllowRestart(allowRestart); 8894 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 8895 synchronized (death) { 8896 while (who.isBinderAlive()) { 8897 try { 8898 death.wait(); 8899 } catch (InterruptedException e) { 8900 } 8901 } 8902 } 8903 Watchdog.getInstance().setAllowRestart(true); 8904 } 8905 } 8906 8907 @Override 8908 public void restart() { 8909 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8910 != PackageManager.PERMISSION_GRANTED) { 8911 throw new SecurityException("Requires permission " 8912 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8913 } 8914 8915 Log.i(TAG, "Sending shutdown broadcast..."); 8916 8917 BroadcastReceiver br = new BroadcastReceiver() { 8918 @Override public void onReceive(Context context, Intent intent) { 8919 // Now the broadcast is done, finish up the low-level shutdown. 8920 Log.i(TAG, "Shutting down activity manager..."); 8921 shutdown(10000); 8922 Log.i(TAG, "Shutdown complete, restarting!"); 8923 Process.killProcess(Process.myPid()); 8924 System.exit(10); 8925 } 8926 }; 8927 8928 // First send the high-level shut down broadcast. 8929 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 8930 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 8931 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 8932 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 8933 mContext.sendOrderedBroadcastAsUser(intent, 8934 UserHandle.ALL, null, br, mHandler, 0, null, null); 8935 */ 8936 br.onReceive(mContext, intent); 8937 } 8938 8939 private long getLowRamTimeSinceIdle(long now) { 8940 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 8941 } 8942 8943 @Override 8944 public void performIdleMaintenance() { 8945 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8946 != PackageManager.PERMISSION_GRANTED) { 8947 throw new SecurityException("Requires permission " 8948 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8949 } 8950 8951 synchronized (this) { 8952 final long now = SystemClock.uptimeMillis(); 8953 final long timeSinceLastIdle = now - mLastIdleTime; 8954 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 8955 mLastIdleTime = now; 8956 mLowRamTimeSinceLastIdle = 0; 8957 if (mLowRamStartTime != 0) { 8958 mLowRamStartTime = now; 8959 } 8960 8961 StringBuilder sb = new StringBuilder(128); 8962 sb.append("Idle maintenance over "); 8963 TimeUtils.formatDuration(timeSinceLastIdle, sb); 8964 sb.append(" low RAM for "); 8965 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 8966 Slog.i(TAG, sb.toString()); 8967 8968 // If at least 1/3 of our time since the last idle period has been spent 8969 // with RAM low, then we want to kill processes. 8970 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 8971 8972 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 8973 ProcessRecord proc = mLruProcesses.get(i); 8974 if (proc.notCachedSinceIdle) { 8975 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 8976 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 8977 if (doKilling && proc.initialIdlePss != 0 8978 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 8979 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 8980 + " from " + proc.initialIdlePss + ")"); 8981 } 8982 } 8983 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 8984 proc.notCachedSinceIdle = true; 8985 proc.initialIdlePss = 0; 8986 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 8987 mSleeping, now); 8988 } 8989 } 8990 8991 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 8992 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 8993 } 8994 } 8995 8996 public final void startRunning(String pkg, String cls, String action, 8997 String data) { 8998 synchronized(this) { 8999 if (mStartRunning) { 9000 return; 9001 } 9002 mStartRunning = true; 9003 mTopComponent = pkg != null && cls != null 9004 ? new ComponentName(pkg, cls) : null; 9005 mTopAction = action != null ? action : Intent.ACTION_MAIN; 9006 mTopData = data; 9007 if (!mSystemReady) { 9008 return; 9009 } 9010 } 9011 9012 systemReady(null); 9013 } 9014 9015 private void retrieveSettings() { 9016 final ContentResolver resolver = mContext.getContentResolver(); 9017 String debugApp = Settings.Global.getString( 9018 resolver, Settings.Global.DEBUG_APP); 9019 boolean waitForDebugger = Settings.Global.getInt( 9020 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9021 boolean alwaysFinishActivities = Settings.Global.getInt( 9022 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9023 boolean forceRtl = Settings.Global.getInt( 9024 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9025 // Transfer any global setting for forcing RTL layout, into a System Property 9026 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9027 9028 Configuration configuration = new Configuration(); 9029 Settings.System.getConfiguration(resolver, configuration); 9030 if (forceRtl) { 9031 // This will take care of setting the correct layout direction flags 9032 configuration.setLayoutDirection(configuration.locale); 9033 } 9034 9035 synchronized (this) { 9036 mDebugApp = mOrigDebugApp = debugApp; 9037 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9038 mAlwaysFinishActivities = alwaysFinishActivities; 9039 // This happens before any activities are started, so we can 9040 // change mConfiguration in-place. 9041 updateConfigurationLocked(configuration, null, false, true); 9042 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9043 } 9044 } 9045 9046 public boolean testIsSystemReady() { 9047 // no need to synchronize(this) just to read & return the value 9048 return mSystemReady; 9049 } 9050 9051 private static File getCalledPreBootReceiversFile() { 9052 File dataDir = Environment.getDataDirectory(); 9053 File systemDir = new File(dataDir, "system"); 9054 File fname = new File(systemDir, "called_pre_boots.dat"); 9055 return fname; 9056 } 9057 9058 static final int LAST_DONE_VERSION = 10000; 9059 9060 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9061 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9062 File file = getCalledPreBootReceiversFile(); 9063 FileInputStream fis = null; 9064 try { 9065 fis = new FileInputStream(file); 9066 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9067 int fvers = dis.readInt(); 9068 if (fvers == LAST_DONE_VERSION) { 9069 String vers = dis.readUTF(); 9070 String codename = dis.readUTF(); 9071 String build = dis.readUTF(); 9072 if (android.os.Build.VERSION.RELEASE.equals(vers) 9073 && android.os.Build.VERSION.CODENAME.equals(codename) 9074 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9075 int num = dis.readInt(); 9076 while (num > 0) { 9077 num--; 9078 String pkg = dis.readUTF(); 9079 String cls = dis.readUTF(); 9080 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9081 } 9082 } 9083 } 9084 } catch (FileNotFoundException e) { 9085 } catch (IOException e) { 9086 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9087 } finally { 9088 if (fis != null) { 9089 try { 9090 fis.close(); 9091 } catch (IOException e) { 9092 } 9093 } 9094 } 9095 return lastDoneReceivers; 9096 } 9097 9098 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9099 File file = getCalledPreBootReceiversFile(); 9100 FileOutputStream fos = null; 9101 DataOutputStream dos = null; 9102 try { 9103 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9104 fos = new FileOutputStream(file); 9105 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9106 dos.writeInt(LAST_DONE_VERSION); 9107 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9108 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9109 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9110 dos.writeInt(list.size()); 9111 for (int i=0; i<list.size(); i++) { 9112 dos.writeUTF(list.get(i).getPackageName()); 9113 dos.writeUTF(list.get(i).getClassName()); 9114 } 9115 } catch (IOException e) { 9116 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9117 file.delete(); 9118 } finally { 9119 FileUtils.sync(fos); 9120 if (dos != null) { 9121 try { 9122 dos.close(); 9123 } catch (IOException e) { 9124 // TODO Auto-generated catch block 9125 e.printStackTrace(); 9126 } 9127 } 9128 } 9129 } 9130 9131 public void systemReady(final Runnable goingCallback) { 9132 synchronized(this) { 9133 if (mSystemReady) { 9134 if (goingCallback != null) goingCallback.run(); 9135 return; 9136 } 9137 9138 // Check to see if there are any update receivers to run. 9139 if (!mDidUpdate) { 9140 if (mWaitingUpdate) { 9141 return; 9142 } 9143 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9144 List<ResolveInfo> ris = null; 9145 try { 9146 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9147 intent, null, 0, 0); 9148 } catch (RemoteException e) { 9149 } 9150 if (ris != null) { 9151 for (int i=ris.size()-1; i>=0; i--) { 9152 if ((ris.get(i).activityInfo.applicationInfo.flags 9153 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9154 ris.remove(i); 9155 } 9156 } 9157 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9158 9159 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9160 9161 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9162 for (int i=0; i<ris.size(); i++) { 9163 ActivityInfo ai = ris.get(i).activityInfo; 9164 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9165 if (lastDoneReceivers.contains(comp)) { 9166 ris.remove(i); 9167 i--; 9168 } 9169 } 9170 9171 final int[] users = getUsersLocked(); 9172 for (int i=0; i<ris.size(); i++) { 9173 ActivityInfo ai = ris.get(i).activityInfo; 9174 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9175 doneReceivers.add(comp); 9176 intent.setComponent(comp); 9177 for (int j=0; j<users.length; j++) { 9178 IIntentReceiver finisher = null; 9179 if (i == ris.size()-1 && j == users.length-1) { 9180 finisher = new IIntentReceiver.Stub() { 9181 public void performReceive(Intent intent, int resultCode, 9182 String data, Bundle extras, boolean ordered, 9183 boolean sticky, int sendingUser) { 9184 // The raw IIntentReceiver interface is called 9185 // with the AM lock held, so redispatch to 9186 // execute our code without the lock. 9187 mHandler.post(new Runnable() { 9188 public void run() { 9189 synchronized (ActivityManagerService.this) { 9190 mDidUpdate = true; 9191 } 9192 writeLastDonePreBootReceivers(doneReceivers); 9193 showBootMessage(mContext.getText( 9194 R.string.android_upgrading_complete), 9195 false); 9196 systemReady(goingCallback); 9197 } 9198 }); 9199 } 9200 }; 9201 } 9202 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9203 + " for user " + users[j]); 9204 broadcastIntentLocked(null, null, intent, null, finisher, 9205 0, null, null, null, AppOpsManager.OP_NONE, 9206 true, false, MY_PID, Process.SYSTEM_UID, 9207 users[j]); 9208 if (finisher != null) { 9209 mWaitingUpdate = true; 9210 } 9211 } 9212 } 9213 } 9214 if (mWaitingUpdate) { 9215 return; 9216 } 9217 mDidUpdate = true; 9218 } 9219 9220 mAppOpsService.systemReady(); 9221 mSystemReady = true; 9222 if (!mStartRunning) { 9223 return; 9224 } 9225 } 9226 9227 ArrayList<ProcessRecord> procsToKill = null; 9228 synchronized(mPidsSelfLocked) { 9229 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9230 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9231 if (!isAllowedWhileBooting(proc.info)){ 9232 if (procsToKill == null) { 9233 procsToKill = new ArrayList<ProcessRecord>(); 9234 } 9235 procsToKill.add(proc); 9236 } 9237 } 9238 } 9239 9240 synchronized(this) { 9241 if (procsToKill != null) { 9242 for (int i=procsToKill.size()-1; i>=0; i--) { 9243 ProcessRecord proc = procsToKill.get(i); 9244 Slog.i(TAG, "Removing system update proc: " + proc); 9245 removeProcessLocked(proc, true, false, "system update done"); 9246 } 9247 } 9248 9249 // Now that we have cleaned up any update processes, we 9250 // are ready to start launching real processes and know that 9251 // we won't trample on them any more. 9252 mProcessesReady = true; 9253 } 9254 9255 Slog.i(TAG, "System now ready"); 9256 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9257 SystemClock.uptimeMillis()); 9258 9259 synchronized(this) { 9260 // Make sure we have no pre-ready processes sitting around. 9261 9262 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9263 ResolveInfo ri = mContext.getPackageManager() 9264 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9265 STOCK_PM_FLAGS); 9266 CharSequence errorMsg = null; 9267 if (ri != null) { 9268 ActivityInfo ai = ri.activityInfo; 9269 ApplicationInfo app = ai.applicationInfo; 9270 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9271 mTopAction = Intent.ACTION_FACTORY_TEST; 9272 mTopData = null; 9273 mTopComponent = new ComponentName(app.packageName, 9274 ai.name); 9275 } else { 9276 errorMsg = mContext.getResources().getText( 9277 com.android.internal.R.string.factorytest_not_system); 9278 } 9279 } else { 9280 errorMsg = mContext.getResources().getText( 9281 com.android.internal.R.string.factorytest_no_action); 9282 } 9283 if (errorMsg != null) { 9284 mTopAction = null; 9285 mTopData = null; 9286 mTopComponent = null; 9287 Message msg = Message.obtain(); 9288 msg.what = SHOW_FACTORY_ERROR_MSG; 9289 msg.getData().putCharSequence("msg", errorMsg); 9290 mHandler.sendMessage(msg); 9291 } 9292 } 9293 } 9294 9295 retrieveSettings(); 9296 9297 synchronized (this) { 9298 readGrantedUriPermissionsLocked(); 9299 } 9300 9301 if (goingCallback != null) goingCallback.run(); 9302 9303 synchronized (this) { 9304 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9305 try { 9306 List apps = AppGlobals.getPackageManager(). 9307 getPersistentApplications(STOCK_PM_FLAGS); 9308 if (apps != null) { 9309 int N = apps.size(); 9310 int i; 9311 for (i=0; i<N; i++) { 9312 ApplicationInfo info 9313 = (ApplicationInfo)apps.get(i); 9314 if (info != null && 9315 !info.packageName.equals("android")) { 9316 addAppLocked(info, false); 9317 } 9318 } 9319 } 9320 } catch (RemoteException ex) { 9321 // pm is in same process, this will never happen. 9322 } 9323 } 9324 9325 // Start up initial activity. 9326 mBooting = true; 9327 9328 try { 9329 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9330 Message msg = Message.obtain(); 9331 msg.what = SHOW_UID_ERROR_MSG; 9332 mHandler.sendMessage(msg); 9333 } 9334 } catch (RemoteException e) { 9335 } 9336 9337 long ident = Binder.clearCallingIdentity(); 9338 try { 9339 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9340 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9341 | Intent.FLAG_RECEIVER_FOREGROUND); 9342 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9343 broadcastIntentLocked(null, null, intent, 9344 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9345 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9346 intent = new Intent(Intent.ACTION_USER_STARTING); 9347 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9348 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9349 broadcastIntentLocked(null, null, intent, 9350 null, new IIntentReceiver.Stub() { 9351 @Override 9352 public void performReceive(Intent intent, int resultCode, String data, 9353 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9354 throws RemoteException { 9355 } 9356 }, 0, null, null, 9357 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9358 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9359 } finally { 9360 Binder.restoreCallingIdentity(ident); 9361 } 9362 mStackSupervisor.resumeTopActivitiesLocked(); 9363 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9364 } 9365 } 9366 9367 private boolean makeAppCrashingLocked(ProcessRecord app, 9368 String shortMsg, String longMsg, String stackTrace) { 9369 app.crashing = true; 9370 app.crashingReport = generateProcessError(app, 9371 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9372 startAppProblemLocked(app); 9373 app.stopFreezingAllLocked(); 9374 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9375 } 9376 9377 private void makeAppNotRespondingLocked(ProcessRecord app, 9378 String activity, String shortMsg, String longMsg) { 9379 app.notResponding = true; 9380 app.notRespondingReport = generateProcessError(app, 9381 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9382 activity, shortMsg, longMsg, null); 9383 startAppProblemLocked(app); 9384 app.stopFreezingAllLocked(); 9385 } 9386 9387 /** 9388 * Generate a process error record, suitable for attachment to a ProcessRecord. 9389 * 9390 * @param app The ProcessRecord in which the error occurred. 9391 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9392 * ActivityManager.AppErrorStateInfo 9393 * @param activity The activity associated with the crash, if known. 9394 * @param shortMsg Short message describing the crash. 9395 * @param longMsg Long message describing the crash. 9396 * @param stackTrace Full crash stack trace, may be null. 9397 * 9398 * @return Returns a fully-formed AppErrorStateInfo record. 9399 */ 9400 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9401 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9402 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9403 9404 report.condition = condition; 9405 report.processName = app.processName; 9406 report.pid = app.pid; 9407 report.uid = app.info.uid; 9408 report.tag = activity; 9409 report.shortMsg = shortMsg; 9410 report.longMsg = longMsg; 9411 report.stackTrace = stackTrace; 9412 9413 return report; 9414 } 9415 9416 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9417 synchronized (this) { 9418 app.crashing = false; 9419 app.crashingReport = null; 9420 app.notResponding = false; 9421 app.notRespondingReport = null; 9422 if (app.anrDialog == fromDialog) { 9423 app.anrDialog = null; 9424 } 9425 if (app.waitDialog == fromDialog) { 9426 app.waitDialog = null; 9427 } 9428 if (app.pid > 0 && app.pid != MY_PID) { 9429 handleAppCrashLocked(app, null, null, null); 9430 killUnneededProcessLocked(app, "user request after error"); 9431 } 9432 } 9433 } 9434 9435 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9436 String stackTrace) { 9437 long now = SystemClock.uptimeMillis(); 9438 9439 Long crashTime; 9440 if (!app.isolated) { 9441 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9442 } else { 9443 crashTime = null; 9444 } 9445 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9446 // This process loses! 9447 Slog.w(TAG, "Process " + app.info.processName 9448 + " has crashed too many times: killing!"); 9449 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9450 app.userId, app.info.processName, app.uid); 9451 mStackSupervisor.handleAppCrashLocked(app); 9452 if (!app.persistent) { 9453 // We don't want to start this process again until the user 9454 // explicitly does so... but for persistent process, we really 9455 // need to keep it running. If a persistent process is actually 9456 // repeatedly crashing, then badness for everyone. 9457 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9458 app.info.processName); 9459 if (!app.isolated) { 9460 // XXX We don't have a way to mark isolated processes 9461 // as bad, since they don't have a peristent identity. 9462 mBadProcesses.put(app.info.processName, app.uid, 9463 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9464 mProcessCrashTimes.remove(app.info.processName, app.uid); 9465 } 9466 app.bad = true; 9467 app.removed = true; 9468 // Don't let services in this process be restarted and potentially 9469 // annoy the user repeatedly. Unless it is persistent, since those 9470 // processes run critical code. 9471 removeProcessLocked(app, false, false, "crash"); 9472 mStackSupervisor.resumeTopActivitiesLocked(); 9473 return false; 9474 } 9475 mStackSupervisor.resumeTopActivitiesLocked(); 9476 } else { 9477 mStackSupervisor.finishTopRunningActivityLocked(app); 9478 } 9479 9480 // Bump up the crash count of any services currently running in the proc. 9481 for (int i=app.services.size()-1; i>=0; i--) { 9482 // Any services running in the application need to be placed 9483 // back in the pending list. 9484 ServiceRecord sr = app.services.valueAt(i); 9485 sr.crashCount++; 9486 } 9487 9488 // If the crashing process is what we consider to be the "home process" and it has been 9489 // replaced by a third-party app, clear the package preferred activities from packages 9490 // with a home activity running in the process to prevent a repeatedly crashing app 9491 // from blocking the user to manually clear the list. 9492 final ArrayList<ActivityRecord> activities = app.activities; 9493 if (app == mHomeProcess && activities.size() > 0 9494 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9495 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9496 final ActivityRecord r = activities.get(activityNdx); 9497 if (r.isHomeActivity()) { 9498 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9499 try { 9500 ActivityThread.getPackageManager() 9501 .clearPackagePreferredActivities(r.packageName); 9502 } catch (RemoteException c) { 9503 // pm is in same process, this will never happen. 9504 } 9505 } 9506 } 9507 } 9508 9509 if (!app.isolated) { 9510 // XXX Can't keep track of crash times for isolated processes, 9511 // because they don't have a perisistent identity. 9512 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9513 } 9514 9515 return true; 9516 } 9517 9518 void startAppProblemLocked(ProcessRecord app) { 9519 if (app.userId == mCurrentUserId) { 9520 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9521 mContext, app.info.packageName, app.info.flags); 9522 } else { 9523 // If this app is not running under the current user, then we 9524 // can't give it a report button because that would require 9525 // launching the report UI under a different user. 9526 app.errorReportReceiver = null; 9527 } 9528 skipCurrentReceiverLocked(app); 9529 } 9530 9531 void skipCurrentReceiverLocked(ProcessRecord app) { 9532 for (BroadcastQueue queue : mBroadcastQueues) { 9533 queue.skipCurrentReceiverLocked(app); 9534 } 9535 } 9536 9537 /** 9538 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9539 * The application process will exit immediately after this call returns. 9540 * @param app object of the crashing app, null for the system server 9541 * @param crashInfo describing the exception 9542 */ 9543 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9544 ProcessRecord r = findAppProcess(app, "Crash"); 9545 final String processName = app == null ? "system_server" 9546 : (r == null ? "unknown" : r.processName); 9547 9548 handleApplicationCrashInner("crash", r, processName, crashInfo); 9549 } 9550 9551 /* Native crash reporting uses this inner version because it needs to be somewhat 9552 * decoupled from the AM-managed cleanup lifecycle 9553 */ 9554 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9555 ApplicationErrorReport.CrashInfo crashInfo) { 9556 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9557 UserHandle.getUserId(Binder.getCallingUid()), processName, 9558 r == null ? -1 : r.info.flags, 9559 crashInfo.exceptionClassName, 9560 crashInfo.exceptionMessage, 9561 crashInfo.throwFileName, 9562 crashInfo.throwLineNumber); 9563 9564 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9565 9566 crashApplication(r, crashInfo); 9567 } 9568 9569 public void handleApplicationStrictModeViolation( 9570 IBinder app, 9571 int violationMask, 9572 StrictMode.ViolationInfo info) { 9573 ProcessRecord r = findAppProcess(app, "StrictMode"); 9574 if (r == null) { 9575 return; 9576 } 9577 9578 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9579 Integer stackFingerprint = info.hashCode(); 9580 boolean logIt = true; 9581 synchronized (mAlreadyLoggedViolatedStacks) { 9582 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9583 logIt = false; 9584 // TODO: sub-sample into EventLog for these, with 9585 // the info.durationMillis? Then we'd get 9586 // the relative pain numbers, without logging all 9587 // the stack traces repeatedly. We'd want to do 9588 // likewise in the client code, which also does 9589 // dup suppression, before the Binder call. 9590 } else { 9591 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9592 mAlreadyLoggedViolatedStacks.clear(); 9593 } 9594 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9595 } 9596 } 9597 if (logIt) { 9598 logStrictModeViolationToDropBox(r, info); 9599 } 9600 } 9601 9602 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9603 AppErrorResult result = new AppErrorResult(); 9604 synchronized (this) { 9605 final long origId = Binder.clearCallingIdentity(); 9606 9607 Message msg = Message.obtain(); 9608 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9609 HashMap<String, Object> data = new HashMap<String, Object>(); 9610 data.put("result", result); 9611 data.put("app", r); 9612 data.put("violationMask", violationMask); 9613 data.put("info", info); 9614 msg.obj = data; 9615 mHandler.sendMessage(msg); 9616 9617 Binder.restoreCallingIdentity(origId); 9618 } 9619 int res = result.get(); 9620 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9621 } 9622 } 9623 9624 // Depending on the policy in effect, there could be a bunch of 9625 // these in quick succession so we try to batch these together to 9626 // minimize disk writes, number of dropbox entries, and maximize 9627 // compression, by having more fewer, larger records. 9628 private void logStrictModeViolationToDropBox( 9629 ProcessRecord process, 9630 StrictMode.ViolationInfo info) { 9631 if (info == null) { 9632 return; 9633 } 9634 final boolean isSystemApp = process == null || 9635 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9636 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9637 final String processName = process == null ? "unknown" : process.processName; 9638 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9639 final DropBoxManager dbox = (DropBoxManager) 9640 mContext.getSystemService(Context.DROPBOX_SERVICE); 9641 9642 // Exit early if the dropbox isn't configured to accept this report type. 9643 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9644 9645 boolean bufferWasEmpty; 9646 boolean needsFlush; 9647 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9648 synchronized (sb) { 9649 bufferWasEmpty = sb.length() == 0; 9650 appendDropBoxProcessHeaders(process, processName, sb); 9651 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9652 sb.append("System-App: ").append(isSystemApp).append("\n"); 9653 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9654 if (info.violationNumThisLoop != 0) { 9655 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9656 } 9657 if (info.numAnimationsRunning != 0) { 9658 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9659 } 9660 if (info.broadcastIntentAction != null) { 9661 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9662 } 9663 if (info.durationMillis != -1) { 9664 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9665 } 9666 if (info.numInstances != -1) { 9667 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9668 } 9669 if (info.tags != null) { 9670 for (String tag : info.tags) { 9671 sb.append("Span-Tag: ").append(tag).append("\n"); 9672 } 9673 } 9674 sb.append("\n"); 9675 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9676 sb.append(info.crashInfo.stackTrace); 9677 } 9678 sb.append("\n"); 9679 9680 // Only buffer up to ~64k. Various logging bits truncate 9681 // things at 128k. 9682 needsFlush = (sb.length() > 64 * 1024); 9683 } 9684 9685 // Flush immediately if the buffer's grown too large, or this 9686 // is a non-system app. Non-system apps are isolated with a 9687 // different tag & policy and not batched. 9688 // 9689 // Batching is useful during internal testing with 9690 // StrictMode settings turned up high. Without batching, 9691 // thousands of separate files could be created on boot. 9692 if (!isSystemApp || needsFlush) { 9693 new Thread("Error dump: " + dropboxTag) { 9694 @Override 9695 public void run() { 9696 String report; 9697 synchronized (sb) { 9698 report = sb.toString(); 9699 sb.delete(0, sb.length()); 9700 sb.trimToSize(); 9701 } 9702 if (report.length() != 0) { 9703 dbox.addText(dropboxTag, report); 9704 } 9705 } 9706 }.start(); 9707 return; 9708 } 9709 9710 // System app batching: 9711 if (!bufferWasEmpty) { 9712 // An existing dropbox-writing thread is outstanding, so 9713 // we don't need to start it up. The existing thread will 9714 // catch the buffer appends we just did. 9715 return; 9716 } 9717 9718 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9719 // (After this point, we shouldn't access AMS internal data structures.) 9720 new Thread("Error dump: " + dropboxTag) { 9721 @Override 9722 public void run() { 9723 // 5 second sleep to let stacks arrive and be batched together 9724 try { 9725 Thread.sleep(5000); // 5 seconds 9726 } catch (InterruptedException e) {} 9727 9728 String errorReport; 9729 synchronized (mStrictModeBuffer) { 9730 errorReport = mStrictModeBuffer.toString(); 9731 if (errorReport.length() == 0) { 9732 return; 9733 } 9734 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9735 mStrictModeBuffer.trimToSize(); 9736 } 9737 dbox.addText(dropboxTag, errorReport); 9738 } 9739 }.start(); 9740 } 9741 9742 /** 9743 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9744 * @param app object of the crashing app, null for the system server 9745 * @param tag reported by the caller 9746 * @param crashInfo describing the context of the error 9747 * @return true if the process should exit immediately (WTF is fatal) 9748 */ 9749 public boolean handleApplicationWtf(IBinder app, String tag, 9750 ApplicationErrorReport.CrashInfo crashInfo) { 9751 ProcessRecord r = findAppProcess(app, "WTF"); 9752 final String processName = app == null ? "system_server" 9753 : (r == null ? "unknown" : r.processName); 9754 9755 EventLog.writeEvent(EventLogTags.AM_WTF, 9756 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9757 processName, 9758 r == null ? -1 : r.info.flags, 9759 tag, crashInfo.exceptionMessage); 9760 9761 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9762 9763 if (r != null && r.pid != Process.myPid() && 9764 Settings.Global.getInt(mContext.getContentResolver(), 9765 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9766 crashApplication(r, crashInfo); 9767 return true; 9768 } else { 9769 return false; 9770 } 9771 } 9772 9773 /** 9774 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9775 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9776 */ 9777 private ProcessRecord findAppProcess(IBinder app, String reason) { 9778 if (app == null) { 9779 return null; 9780 } 9781 9782 synchronized (this) { 9783 final int NP = mProcessNames.getMap().size(); 9784 for (int ip=0; ip<NP; ip++) { 9785 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9786 final int NA = apps.size(); 9787 for (int ia=0; ia<NA; ia++) { 9788 ProcessRecord p = apps.valueAt(ia); 9789 if (p.thread != null && p.thread.asBinder() == app) { 9790 return p; 9791 } 9792 } 9793 } 9794 9795 Slog.w(TAG, "Can't find mystery application for " + reason 9796 + " from pid=" + Binder.getCallingPid() 9797 + " uid=" + Binder.getCallingUid() + ": " + app); 9798 return null; 9799 } 9800 } 9801 9802 /** 9803 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9804 * to append various headers to the dropbox log text. 9805 */ 9806 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9807 StringBuilder sb) { 9808 // Watchdog thread ends up invoking this function (with 9809 // a null ProcessRecord) to add the stack file to dropbox. 9810 // Do not acquire a lock on this (am) in such cases, as it 9811 // could cause a potential deadlock, if and when watchdog 9812 // is invoked due to unavailability of lock on am and it 9813 // would prevent watchdog from killing system_server. 9814 if (process == null) { 9815 sb.append("Process: ").append(processName).append("\n"); 9816 return; 9817 } 9818 // Note: ProcessRecord 'process' is guarded by the service 9819 // instance. (notably process.pkgList, which could otherwise change 9820 // concurrently during execution of this method) 9821 synchronized (this) { 9822 sb.append("Process: ").append(processName).append("\n"); 9823 int flags = process.info.flags; 9824 IPackageManager pm = AppGlobals.getPackageManager(); 9825 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 9826 for (int ip=0; ip<process.pkgList.size(); ip++) { 9827 String pkg = process.pkgList.keyAt(ip); 9828 sb.append("Package: ").append(pkg); 9829 try { 9830 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 9831 if (pi != null) { 9832 sb.append(" v").append(pi.versionCode); 9833 if (pi.versionName != null) { 9834 sb.append(" (").append(pi.versionName).append(")"); 9835 } 9836 } 9837 } catch (RemoteException e) { 9838 Slog.e(TAG, "Error getting package info: " + pkg, e); 9839 } 9840 sb.append("\n"); 9841 } 9842 } 9843 } 9844 9845 private static String processClass(ProcessRecord process) { 9846 if (process == null || process.pid == MY_PID) { 9847 return "system_server"; 9848 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9849 return "system_app"; 9850 } else { 9851 return "data_app"; 9852 } 9853 } 9854 9855 /** 9856 * Write a description of an error (crash, WTF, ANR) to the drop box. 9857 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 9858 * @param process which caused the error, null means the system server 9859 * @param activity which triggered the error, null if unknown 9860 * @param parent activity related to the error, null if unknown 9861 * @param subject line related to the error, null if absent 9862 * @param report in long form describing the error, null if absent 9863 * @param logFile to include in the report, null if none 9864 * @param crashInfo giving an application stack trace, null if absent 9865 */ 9866 public void addErrorToDropBox(String eventType, 9867 ProcessRecord process, String processName, ActivityRecord activity, 9868 ActivityRecord parent, String subject, 9869 final String report, final File logFile, 9870 final ApplicationErrorReport.CrashInfo crashInfo) { 9871 // NOTE -- this must never acquire the ActivityManagerService lock, 9872 // otherwise the watchdog may be prevented from resetting the system. 9873 9874 final String dropboxTag = processClass(process) + "_" + eventType; 9875 final DropBoxManager dbox = (DropBoxManager) 9876 mContext.getSystemService(Context.DROPBOX_SERVICE); 9877 9878 // Exit early if the dropbox isn't configured to accept this report type. 9879 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9880 9881 final StringBuilder sb = new StringBuilder(1024); 9882 appendDropBoxProcessHeaders(process, processName, sb); 9883 if (activity != null) { 9884 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 9885 } 9886 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 9887 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 9888 } 9889 if (parent != null && parent != activity) { 9890 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 9891 } 9892 if (subject != null) { 9893 sb.append("Subject: ").append(subject).append("\n"); 9894 } 9895 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9896 if (Debug.isDebuggerConnected()) { 9897 sb.append("Debugger: Connected\n"); 9898 } 9899 sb.append("\n"); 9900 9901 // Do the rest in a worker thread to avoid blocking the caller on I/O 9902 // (After this point, we shouldn't access AMS internal data structures.) 9903 Thread worker = new Thread("Error dump: " + dropboxTag) { 9904 @Override 9905 public void run() { 9906 if (report != null) { 9907 sb.append(report); 9908 } 9909 if (logFile != null) { 9910 try { 9911 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 9912 "\n\n[[TRUNCATED]]")); 9913 } catch (IOException e) { 9914 Slog.e(TAG, "Error reading " + logFile, e); 9915 } 9916 } 9917 if (crashInfo != null && crashInfo.stackTrace != null) { 9918 sb.append(crashInfo.stackTrace); 9919 } 9920 9921 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 9922 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 9923 if (lines > 0) { 9924 sb.append("\n"); 9925 9926 // Merge several logcat streams, and take the last N lines 9927 InputStreamReader input = null; 9928 try { 9929 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 9930 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 9931 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 9932 9933 try { logcat.getOutputStream().close(); } catch (IOException e) {} 9934 try { logcat.getErrorStream().close(); } catch (IOException e) {} 9935 input = new InputStreamReader(logcat.getInputStream()); 9936 9937 int num; 9938 char[] buf = new char[8192]; 9939 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 9940 } catch (IOException e) { 9941 Slog.e(TAG, "Error running logcat", e); 9942 } finally { 9943 if (input != null) try { input.close(); } catch (IOException e) {} 9944 } 9945 } 9946 9947 dbox.addText(dropboxTag, sb.toString()); 9948 } 9949 }; 9950 9951 if (process == null) { 9952 // If process is null, we are being called from some internal code 9953 // and may be about to die -- run this synchronously. 9954 worker.run(); 9955 } else { 9956 worker.start(); 9957 } 9958 } 9959 9960 /** 9961 * Bring up the "unexpected error" dialog box for a crashing app. 9962 * Deal with edge cases (intercepts from instrumented applications, 9963 * ActivityController, error intent receivers, that sort of thing). 9964 * @param r the application crashing 9965 * @param crashInfo describing the failure 9966 */ 9967 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 9968 long timeMillis = System.currentTimeMillis(); 9969 String shortMsg = crashInfo.exceptionClassName; 9970 String longMsg = crashInfo.exceptionMessage; 9971 String stackTrace = crashInfo.stackTrace; 9972 if (shortMsg != null && longMsg != null) { 9973 longMsg = shortMsg + ": " + longMsg; 9974 } else if (shortMsg != null) { 9975 longMsg = shortMsg; 9976 } 9977 9978 AppErrorResult result = new AppErrorResult(); 9979 synchronized (this) { 9980 if (mController != null) { 9981 try { 9982 String name = r != null ? r.processName : null; 9983 int pid = r != null ? r.pid : Binder.getCallingPid(); 9984 if (!mController.appCrashed(name, pid, 9985 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 9986 Slog.w(TAG, "Force-killing crashed app " + name 9987 + " at watcher's request"); 9988 Process.killProcess(pid); 9989 return; 9990 } 9991 } catch (RemoteException e) { 9992 mController = null; 9993 Watchdog.getInstance().setActivityController(null); 9994 } 9995 } 9996 9997 final long origId = Binder.clearCallingIdentity(); 9998 9999 // If this process is running instrumentation, finish it. 10000 if (r != null && r.instrumentationClass != null) { 10001 Slog.w(TAG, "Error in app " + r.processName 10002 + " running instrumentation " + r.instrumentationClass + ":"); 10003 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10004 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10005 Bundle info = new Bundle(); 10006 info.putString("shortMsg", shortMsg); 10007 info.putString("longMsg", longMsg); 10008 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10009 Binder.restoreCallingIdentity(origId); 10010 return; 10011 } 10012 10013 // If we can't identify the process or it's already exceeded its crash quota, 10014 // quit right away without showing a crash dialog. 10015 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10016 Binder.restoreCallingIdentity(origId); 10017 return; 10018 } 10019 10020 Message msg = Message.obtain(); 10021 msg.what = SHOW_ERROR_MSG; 10022 HashMap data = new HashMap(); 10023 data.put("result", result); 10024 data.put("app", r); 10025 msg.obj = data; 10026 mHandler.sendMessage(msg); 10027 10028 Binder.restoreCallingIdentity(origId); 10029 } 10030 10031 int res = result.get(); 10032 10033 Intent appErrorIntent = null; 10034 synchronized (this) { 10035 if (r != null && !r.isolated) { 10036 // XXX Can't keep track of crash time for isolated processes, 10037 // since they don't have a persistent identity. 10038 mProcessCrashTimes.put(r.info.processName, r.uid, 10039 SystemClock.uptimeMillis()); 10040 } 10041 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10042 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10043 } 10044 } 10045 10046 if (appErrorIntent != null) { 10047 try { 10048 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10049 } catch (ActivityNotFoundException e) { 10050 Slog.w(TAG, "bug report receiver dissappeared", e); 10051 } 10052 } 10053 } 10054 10055 Intent createAppErrorIntentLocked(ProcessRecord r, 10056 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10057 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10058 if (report == null) { 10059 return null; 10060 } 10061 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10062 result.setComponent(r.errorReportReceiver); 10063 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10064 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10065 return result; 10066 } 10067 10068 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10069 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10070 if (r.errorReportReceiver == null) { 10071 return null; 10072 } 10073 10074 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10075 return null; 10076 } 10077 10078 ApplicationErrorReport report = new ApplicationErrorReport(); 10079 report.packageName = r.info.packageName; 10080 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10081 report.processName = r.processName; 10082 report.time = timeMillis; 10083 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10084 10085 if (r.crashing || r.forceCrashReport) { 10086 report.type = ApplicationErrorReport.TYPE_CRASH; 10087 report.crashInfo = crashInfo; 10088 } else if (r.notResponding) { 10089 report.type = ApplicationErrorReport.TYPE_ANR; 10090 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10091 10092 report.anrInfo.activity = r.notRespondingReport.tag; 10093 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10094 report.anrInfo.info = r.notRespondingReport.longMsg; 10095 } 10096 10097 return report; 10098 } 10099 10100 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10101 enforceNotIsolatedCaller("getProcessesInErrorState"); 10102 // assume our apps are happy - lazy create the list 10103 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10104 10105 final boolean allUsers = ActivityManager.checkUidPermission( 10106 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10107 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10108 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10109 10110 synchronized (this) { 10111 10112 // iterate across all processes 10113 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10114 ProcessRecord app = mLruProcesses.get(i); 10115 if (!allUsers && app.userId != userId) { 10116 continue; 10117 } 10118 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10119 // This one's in trouble, so we'll generate a report for it 10120 // crashes are higher priority (in case there's a crash *and* an anr) 10121 ActivityManager.ProcessErrorStateInfo report = null; 10122 if (app.crashing) { 10123 report = app.crashingReport; 10124 } else if (app.notResponding) { 10125 report = app.notRespondingReport; 10126 } 10127 10128 if (report != null) { 10129 if (errList == null) { 10130 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10131 } 10132 errList.add(report); 10133 } else { 10134 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10135 " crashing = " + app.crashing + 10136 " notResponding = " + app.notResponding); 10137 } 10138 } 10139 } 10140 } 10141 10142 return errList; 10143 } 10144 10145 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10146 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10147 if (currApp != null) { 10148 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10149 } 10150 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10151 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10152 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10153 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10154 if (currApp != null) { 10155 currApp.lru = 0; 10156 } 10157 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10158 } else if (adj >= ProcessList.SERVICE_ADJ) { 10159 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10160 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10161 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10162 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10163 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10164 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10165 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10166 } else { 10167 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10168 } 10169 } 10170 10171 private void fillInProcMemInfo(ProcessRecord app, 10172 ActivityManager.RunningAppProcessInfo outInfo) { 10173 outInfo.pid = app.pid; 10174 outInfo.uid = app.info.uid; 10175 if (mHeavyWeightProcess == app) { 10176 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10177 } 10178 if (app.persistent) { 10179 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10180 } 10181 if (app.activities.size() > 0) { 10182 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10183 } 10184 outInfo.lastTrimLevel = app.trimMemoryLevel; 10185 int adj = app.curAdj; 10186 outInfo.importance = oomAdjToImportance(adj, outInfo); 10187 outInfo.importanceReasonCode = app.adjTypeCode; 10188 } 10189 10190 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10191 enforceNotIsolatedCaller("getRunningAppProcesses"); 10192 // Lazy instantiation of list 10193 List<ActivityManager.RunningAppProcessInfo> runList = null; 10194 final boolean allUsers = ActivityManager.checkUidPermission( 10195 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10196 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10197 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10198 synchronized (this) { 10199 // Iterate across all processes 10200 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10201 ProcessRecord app = mLruProcesses.get(i); 10202 if (!allUsers && app.userId != userId) { 10203 continue; 10204 } 10205 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10206 // Generate process state info for running application 10207 ActivityManager.RunningAppProcessInfo currApp = 10208 new ActivityManager.RunningAppProcessInfo(app.processName, 10209 app.pid, app.getPackageList()); 10210 fillInProcMemInfo(app, currApp); 10211 if (app.adjSource instanceof ProcessRecord) { 10212 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10213 currApp.importanceReasonImportance = oomAdjToImportance( 10214 app.adjSourceOom, null); 10215 } else if (app.adjSource instanceof ActivityRecord) { 10216 ActivityRecord r = (ActivityRecord)app.adjSource; 10217 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10218 } 10219 if (app.adjTarget instanceof ComponentName) { 10220 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10221 } 10222 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10223 // + " lru=" + currApp.lru); 10224 if (runList == null) { 10225 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10226 } 10227 runList.add(currApp); 10228 } 10229 } 10230 } 10231 return runList; 10232 } 10233 10234 public List<ApplicationInfo> getRunningExternalApplications() { 10235 enforceNotIsolatedCaller("getRunningExternalApplications"); 10236 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10237 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10238 if (runningApps != null && runningApps.size() > 0) { 10239 Set<String> extList = new HashSet<String>(); 10240 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10241 if (app.pkgList != null) { 10242 for (String pkg : app.pkgList) { 10243 extList.add(pkg); 10244 } 10245 } 10246 } 10247 IPackageManager pm = AppGlobals.getPackageManager(); 10248 for (String pkg : extList) { 10249 try { 10250 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10251 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10252 retList.add(info); 10253 } 10254 } catch (RemoteException e) { 10255 } 10256 } 10257 } 10258 return retList; 10259 } 10260 10261 @Override 10262 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10263 enforceNotIsolatedCaller("getMyMemoryState"); 10264 synchronized (this) { 10265 ProcessRecord proc; 10266 synchronized (mPidsSelfLocked) { 10267 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10268 } 10269 fillInProcMemInfo(proc, outInfo); 10270 } 10271 } 10272 10273 @Override 10274 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10275 if (checkCallingPermission(android.Manifest.permission.DUMP) 10276 != PackageManager.PERMISSION_GRANTED) { 10277 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10278 + Binder.getCallingPid() 10279 + ", uid=" + Binder.getCallingUid() 10280 + " without permission " 10281 + android.Manifest.permission.DUMP); 10282 return; 10283 } 10284 10285 boolean dumpAll = false; 10286 boolean dumpClient = false; 10287 String dumpPackage = null; 10288 10289 int opti = 0; 10290 while (opti < args.length) { 10291 String opt = args[opti]; 10292 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10293 break; 10294 } 10295 opti++; 10296 if ("-a".equals(opt)) { 10297 dumpAll = true; 10298 } else if ("-c".equals(opt)) { 10299 dumpClient = true; 10300 } else if ("-h".equals(opt)) { 10301 pw.println("Activity manager dump options:"); 10302 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10303 pw.println(" cmd may be one of:"); 10304 pw.println(" a[ctivities]: activity stack state"); 10305 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10306 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10307 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10308 pw.println(" o[om]: out of memory management"); 10309 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10310 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10311 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10312 pw.println(" service [COMP_SPEC]: service client-side state"); 10313 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10314 pw.println(" all: dump all activities"); 10315 pw.println(" top: dump the top activity"); 10316 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10317 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10318 pw.println(" a partial substring in a component name, a"); 10319 pw.println(" hex object identifier."); 10320 pw.println(" -a: include all available server state."); 10321 pw.println(" -c: include client state."); 10322 return; 10323 } else { 10324 pw.println("Unknown argument: " + opt + "; use -h for help"); 10325 } 10326 } 10327 10328 long origId = Binder.clearCallingIdentity(); 10329 boolean more = false; 10330 // Is the caller requesting to dump a particular piece of data? 10331 if (opti < args.length) { 10332 String cmd = args[opti]; 10333 opti++; 10334 if ("activities".equals(cmd) || "a".equals(cmd)) { 10335 synchronized (this) { 10336 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10337 } 10338 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10339 String[] newArgs; 10340 String name; 10341 if (opti >= args.length) { 10342 name = null; 10343 newArgs = EMPTY_STRING_ARRAY; 10344 } else { 10345 name = args[opti]; 10346 opti++; 10347 newArgs = new String[args.length - opti]; 10348 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10349 args.length - opti); 10350 } 10351 synchronized (this) { 10352 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10353 } 10354 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10355 String[] newArgs; 10356 String name; 10357 if (opti >= args.length) { 10358 name = null; 10359 newArgs = EMPTY_STRING_ARRAY; 10360 } else { 10361 name = args[opti]; 10362 opti++; 10363 newArgs = new String[args.length - opti]; 10364 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10365 args.length - opti); 10366 } 10367 synchronized (this) { 10368 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10369 } 10370 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10371 String[] newArgs; 10372 String name; 10373 if (opti >= args.length) { 10374 name = null; 10375 newArgs = EMPTY_STRING_ARRAY; 10376 } else { 10377 name = args[opti]; 10378 opti++; 10379 newArgs = new String[args.length - opti]; 10380 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10381 args.length - opti); 10382 } 10383 synchronized (this) { 10384 dumpProcessesLocked(fd, pw, args, opti, true, name); 10385 } 10386 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10387 synchronized (this) { 10388 dumpOomLocked(fd, pw, args, opti, true); 10389 } 10390 } else if ("provider".equals(cmd)) { 10391 String[] newArgs; 10392 String name; 10393 if (opti >= args.length) { 10394 name = null; 10395 newArgs = EMPTY_STRING_ARRAY; 10396 } else { 10397 name = args[opti]; 10398 opti++; 10399 newArgs = new String[args.length - opti]; 10400 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10401 } 10402 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10403 pw.println("No providers match: " + name); 10404 pw.println("Use -h for help."); 10405 } 10406 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10407 synchronized (this) { 10408 dumpProvidersLocked(fd, pw, args, opti, true, null); 10409 } 10410 } else if ("service".equals(cmd)) { 10411 String[] newArgs; 10412 String name; 10413 if (opti >= args.length) { 10414 name = null; 10415 newArgs = EMPTY_STRING_ARRAY; 10416 } else { 10417 name = args[opti]; 10418 opti++; 10419 newArgs = new String[args.length - opti]; 10420 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10421 args.length - opti); 10422 } 10423 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10424 pw.println("No services match: " + name); 10425 pw.println("Use -h for help."); 10426 } 10427 } else if ("package".equals(cmd)) { 10428 String[] newArgs; 10429 if (opti >= args.length) { 10430 pw.println("package: no package name specified"); 10431 pw.println("Use -h for help."); 10432 } else { 10433 dumpPackage = args[opti]; 10434 opti++; 10435 newArgs = new String[args.length - opti]; 10436 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10437 args.length - opti); 10438 args = newArgs; 10439 opti = 0; 10440 more = true; 10441 } 10442 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10443 synchronized (this) { 10444 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10445 } 10446 } else { 10447 // Dumping a single activity? 10448 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10449 pw.println("Bad activity command, or no activities match: " + cmd); 10450 pw.println("Use -h for help."); 10451 } 10452 } 10453 if (!more) { 10454 Binder.restoreCallingIdentity(origId); 10455 return; 10456 } 10457 } 10458 10459 // No piece of data specified, dump everything. 10460 synchronized (this) { 10461 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10462 pw.println(); 10463 if (dumpAll) { 10464 pw.println("-------------------------------------------------------------------------------"); 10465 } 10466 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10467 pw.println(); 10468 if (dumpAll) { 10469 pw.println("-------------------------------------------------------------------------------"); 10470 } 10471 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10472 pw.println(); 10473 if (dumpAll) { 10474 pw.println("-------------------------------------------------------------------------------"); 10475 } 10476 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10477 pw.println(); 10478 if (dumpAll) { 10479 pw.println("-------------------------------------------------------------------------------"); 10480 } 10481 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10482 pw.println(); 10483 if (dumpAll) { 10484 pw.println("-------------------------------------------------------------------------------"); 10485 } 10486 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10487 } 10488 Binder.restoreCallingIdentity(origId); 10489 } 10490 10491 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10492 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10493 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10494 10495 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10496 dumpPackage); 10497 boolean needSep = printedAnything; 10498 10499 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10500 dumpPackage, needSep, " mFocusedActivity: "); 10501 if (printed) { 10502 printedAnything = true; 10503 needSep = false; 10504 } 10505 10506 if (dumpPackage == null) { 10507 if (needSep) { 10508 pw.println(); 10509 } 10510 needSep = true; 10511 printedAnything = true; 10512 mStackSupervisor.dump(pw, " "); 10513 } 10514 10515 if (mRecentTasks.size() > 0) { 10516 boolean printedHeader = false; 10517 10518 final int N = mRecentTasks.size(); 10519 for (int i=0; i<N; i++) { 10520 TaskRecord tr = mRecentTasks.get(i); 10521 if (dumpPackage != null) { 10522 if (tr.realActivity == null || 10523 !dumpPackage.equals(tr.realActivity)) { 10524 continue; 10525 } 10526 } 10527 if (!printedHeader) { 10528 if (needSep) { 10529 pw.println(); 10530 } 10531 pw.println(" Recent tasks:"); 10532 printedHeader = true; 10533 printedAnything = true; 10534 } 10535 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10536 pw.println(tr); 10537 if (dumpAll) { 10538 mRecentTasks.get(i).dump(pw, " "); 10539 } 10540 } 10541 } 10542 10543 if (!printedAnything) { 10544 pw.println(" (nothing)"); 10545 } 10546 } 10547 10548 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10549 int opti, boolean dumpAll, String dumpPackage) { 10550 boolean needSep = false; 10551 boolean printedAnything = false; 10552 int numPers = 0; 10553 10554 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10555 10556 if (dumpAll) { 10557 final int NP = mProcessNames.getMap().size(); 10558 for (int ip=0; ip<NP; ip++) { 10559 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10560 final int NA = procs.size(); 10561 for (int ia=0; ia<NA; ia++) { 10562 ProcessRecord r = procs.valueAt(ia); 10563 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10564 continue; 10565 } 10566 if (!needSep) { 10567 pw.println(" All known processes:"); 10568 needSep = true; 10569 printedAnything = true; 10570 } 10571 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10572 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10573 pw.print(" "); pw.println(r); 10574 r.dump(pw, " "); 10575 if (r.persistent) { 10576 numPers++; 10577 } 10578 } 10579 } 10580 } 10581 10582 if (mIsolatedProcesses.size() > 0) { 10583 boolean printed = false; 10584 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10585 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10586 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10587 continue; 10588 } 10589 if (!printed) { 10590 if (needSep) { 10591 pw.println(); 10592 } 10593 pw.println(" Isolated process list (sorted by uid):"); 10594 printedAnything = true; 10595 printed = true; 10596 needSep = true; 10597 } 10598 pw.println(String.format("%sIsolated #%2d: %s", 10599 " ", i, r.toString())); 10600 } 10601 } 10602 10603 if (mLruProcesses.size() > 0) { 10604 if (needSep) { 10605 pw.println(); 10606 } 10607 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10608 pw.print(" total, non-act at "); 10609 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10610 pw.print(", non-svc at "); 10611 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10612 pw.println("):"); 10613 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10614 needSep = true; 10615 printedAnything = true; 10616 } 10617 10618 if (dumpAll || dumpPackage != null) { 10619 synchronized (mPidsSelfLocked) { 10620 boolean printed = false; 10621 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10622 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10623 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10624 continue; 10625 } 10626 if (!printed) { 10627 if (needSep) pw.println(); 10628 needSep = true; 10629 pw.println(" PID mappings:"); 10630 printed = true; 10631 printedAnything = true; 10632 } 10633 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10634 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10635 } 10636 } 10637 } 10638 10639 if (mForegroundProcesses.size() > 0) { 10640 synchronized (mPidsSelfLocked) { 10641 boolean printed = false; 10642 for (int i=0; i<mForegroundProcesses.size(); i++) { 10643 ProcessRecord r = mPidsSelfLocked.get( 10644 mForegroundProcesses.valueAt(i).pid); 10645 if (dumpPackage != null && (r == null 10646 || !r.pkgList.containsKey(dumpPackage))) { 10647 continue; 10648 } 10649 if (!printed) { 10650 if (needSep) pw.println(); 10651 needSep = true; 10652 pw.println(" Foreground Processes:"); 10653 printed = true; 10654 printedAnything = true; 10655 } 10656 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10657 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10658 } 10659 } 10660 } 10661 10662 if (mPersistentStartingProcesses.size() > 0) { 10663 if (needSep) pw.println(); 10664 needSep = true; 10665 printedAnything = true; 10666 pw.println(" Persisent processes that are starting:"); 10667 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10668 "Starting Norm", "Restarting PERS", dumpPackage); 10669 } 10670 10671 if (mRemovedProcesses.size() > 0) { 10672 if (needSep) pw.println(); 10673 needSep = true; 10674 printedAnything = true; 10675 pw.println(" Processes that are being removed:"); 10676 dumpProcessList(pw, this, mRemovedProcesses, " ", 10677 "Removed Norm", "Removed PERS", dumpPackage); 10678 } 10679 10680 if (mProcessesOnHold.size() > 0) { 10681 if (needSep) pw.println(); 10682 needSep = true; 10683 printedAnything = true; 10684 pw.println(" Processes that are on old until the system is ready:"); 10685 dumpProcessList(pw, this, mProcessesOnHold, " ", 10686 "OnHold Norm", "OnHold PERS", dumpPackage); 10687 } 10688 10689 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10690 10691 if (mProcessCrashTimes.getMap().size() > 0) { 10692 boolean printed = false; 10693 long now = SystemClock.uptimeMillis(); 10694 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10695 final int NP = pmap.size(); 10696 for (int ip=0; ip<NP; ip++) { 10697 String pname = pmap.keyAt(ip); 10698 SparseArray<Long> 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(" Time since processes crashed:"); 10711 printed = true; 10712 printedAnything = true; 10713 } 10714 pw.print(" Process "); pw.print(pname); 10715 pw.print(" uid "); pw.print(puid); 10716 pw.print(": last crashed "); 10717 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10718 pw.println(" ago"); 10719 } 10720 } 10721 } 10722 10723 if (mBadProcesses.getMap().size() > 0) { 10724 boolean printed = false; 10725 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10726 final int NP = pmap.size(); 10727 for (int ip=0; ip<NP; ip++) { 10728 String pname = pmap.keyAt(ip); 10729 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10730 final int N = uids.size(); 10731 for (int i=0; i<N; i++) { 10732 int puid = uids.keyAt(i); 10733 ProcessRecord r = mProcessNames.get(pname, puid); 10734 if (dumpPackage != null && (r == null 10735 || !r.pkgList.containsKey(dumpPackage))) { 10736 continue; 10737 } 10738 if (!printed) { 10739 if (needSep) pw.println(); 10740 needSep = true; 10741 pw.println(" Bad processes:"); 10742 printedAnything = true; 10743 } 10744 BadProcessInfo info = uids.valueAt(i); 10745 pw.print(" Bad process "); pw.print(pname); 10746 pw.print(" uid "); pw.print(puid); 10747 pw.print(": crashed at time "); pw.println(info.time); 10748 if (info.shortMsg != null) { 10749 pw.print(" Short msg: "); pw.println(info.shortMsg); 10750 } 10751 if (info.longMsg != null) { 10752 pw.print(" Long msg: "); pw.println(info.longMsg); 10753 } 10754 if (info.stack != null) { 10755 pw.println(" Stack:"); 10756 int lastPos = 0; 10757 for (int pos=0; pos<info.stack.length(); pos++) { 10758 if (info.stack.charAt(pos) == '\n') { 10759 pw.print(" "); 10760 pw.write(info.stack, lastPos, pos-lastPos); 10761 pw.println(); 10762 lastPos = pos+1; 10763 } 10764 } 10765 if (lastPos < info.stack.length()) { 10766 pw.print(" "); 10767 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10768 pw.println(); 10769 } 10770 } 10771 } 10772 } 10773 } 10774 10775 if (dumpPackage == null) { 10776 pw.println(); 10777 needSep = false; 10778 pw.println(" mStartedUsers:"); 10779 for (int i=0; i<mStartedUsers.size(); i++) { 10780 UserStartedState uss = mStartedUsers.valueAt(i); 10781 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10782 pw.print(": "); uss.dump("", pw); 10783 } 10784 pw.print(" mStartedUserArray: ["); 10785 for (int i=0; i<mStartedUserArray.length; i++) { 10786 if (i > 0) pw.print(", "); 10787 pw.print(mStartedUserArray[i]); 10788 } 10789 pw.println("]"); 10790 pw.print(" mUserLru: ["); 10791 for (int i=0; i<mUserLru.size(); i++) { 10792 if (i > 0) pw.print(", "); 10793 pw.print(mUserLru.get(i)); 10794 } 10795 pw.println("]"); 10796 if (dumpAll) { 10797 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10798 } 10799 } 10800 if (mHomeProcess != null && (dumpPackage == null 10801 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10802 if (needSep) { 10803 pw.println(); 10804 needSep = false; 10805 } 10806 pw.println(" mHomeProcess: " + mHomeProcess); 10807 } 10808 if (mPreviousProcess != null && (dumpPackage == null 10809 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 10810 if (needSep) { 10811 pw.println(); 10812 needSep = false; 10813 } 10814 pw.println(" mPreviousProcess: " + mPreviousProcess); 10815 } 10816 if (dumpAll) { 10817 StringBuilder sb = new StringBuilder(128); 10818 sb.append(" mPreviousProcessVisibleTime: "); 10819 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 10820 pw.println(sb); 10821 } 10822 if (mHeavyWeightProcess != null && (dumpPackage == null 10823 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 10824 if (needSep) { 10825 pw.println(); 10826 needSep = false; 10827 } 10828 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10829 } 10830 if (dumpPackage == null) { 10831 pw.println(" mConfiguration: " + mConfiguration); 10832 } 10833 if (dumpAll) { 10834 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 10835 if (mCompatModePackages.getPackages().size() > 0) { 10836 boolean printed = false; 10837 for (Map.Entry<String, Integer> entry 10838 : mCompatModePackages.getPackages().entrySet()) { 10839 String pkg = entry.getKey(); 10840 int mode = entry.getValue(); 10841 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 10842 continue; 10843 } 10844 if (!printed) { 10845 pw.println(" mScreenCompatPackages:"); 10846 printed = true; 10847 } 10848 pw.print(" "); pw.print(pkg); pw.print(": "); 10849 pw.print(mode); pw.println(); 10850 } 10851 } 10852 } 10853 if (dumpPackage == null) { 10854 if (mSleeping || mWentToSleep || mLockScreenShown) { 10855 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 10856 + " mLockScreenShown " + mLockScreenShown); 10857 } 10858 if (mShuttingDown) { 10859 pw.println(" mShuttingDown=" + mShuttingDown); 10860 } 10861 } 10862 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 10863 || mOrigWaitForDebugger) { 10864 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 10865 || dumpPackage.equals(mOrigDebugApp)) { 10866 if (needSep) { 10867 pw.println(); 10868 needSep = false; 10869 } 10870 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 10871 + " mDebugTransient=" + mDebugTransient 10872 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 10873 } 10874 } 10875 if (mOpenGlTraceApp != null) { 10876 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 10877 if (needSep) { 10878 pw.println(); 10879 needSep = false; 10880 } 10881 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 10882 } 10883 } 10884 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 10885 || mProfileFd != null) { 10886 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 10887 if (needSep) { 10888 pw.println(); 10889 needSep = false; 10890 } 10891 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 10892 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 10893 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 10894 + mAutoStopProfiler); 10895 } 10896 } 10897 if (dumpPackage == null) { 10898 if (mAlwaysFinishActivities || mController != null) { 10899 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 10900 + " mController=" + mController); 10901 } 10902 if (dumpAll) { 10903 pw.println(" Total persistent processes: " + numPers); 10904 pw.println(" mStartRunning=" + mStartRunning 10905 + " mProcessesReady=" + mProcessesReady 10906 + " mSystemReady=" + mSystemReady); 10907 pw.println(" mBooting=" + mBooting 10908 + " mBooted=" + mBooted 10909 + " mFactoryTest=" + mFactoryTest); 10910 pw.print(" mLastPowerCheckRealtime="); 10911 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 10912 pw.println(""); 10913 pw.print(" mLastPowerCheckUptime="); 10914 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 10915 pw.println(""); 10916 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 10917 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 10918 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 10919 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 10920 + " (" + mLruProcesses.size() + " total)" 10921 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 10922 + " mNumServiceProcs=" + mNumServiceProcs 10923 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 10924 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 10925 + " mLastMemoryLevel" + mLastMemoryLevel 10926 + " mLastNumProcesses" + mLastNumProcesses); 10927 long now = SystemClock.uptimeMillis(); 10928 pw.print(" mLastIdleTime="); 10929 TimeUtils.formatDuration(now, mLastIdleTime, pw); 10930 pw.print(" mLowRamSinceLastIdle="); 10931 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 10932 pw.println(); 10933 } 10934 } 10935 10936 if (!printedAnything) { 10937 pw.println(" (nothing)"); 10938 } 10939 } 10940 10941 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 10942 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 10943 if (mProcessesToGc.size() > 0) { 10944 boolean printed = false; 10945 long now = SystemClock.uptimeMillis(); 10946 for (int i=0; i<mProcessesToGc.size(); i++) { 10947 ProcessRecord proc = mProcessesToGc.get(i); 10948 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 10949 continue; 10950 } 10951 if (!printed) { 10952 if (needSep) pw.println(); 10953 needSep = true; 10954 pw.println(" Processes that are waiting to GC:"); 10955 printed = true; 10956 } 10957 pw.print(" Process "); pw.println(proc); 10958 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 10959 pw.print(", last gced="); 10960 pw.print(now-proc.lastRequestedGc); 10961 pw.print(" ms ago, last lowMem="); 10962 pw.print(now-proc.lastLowMemory); 10963 pw.println(" ms ago"); 10964 10965 } 10966 } 10967 return needSep; 10968 } 10969 10970 void printOomLevel(PrintWriter pw, String name, int adj) { 10971 pw.print(" "); 10972 if (adj >= 0) { 10973 pw.print(' '); 10974 if (adj < 10) pw.print(' '); 10975 } else { 10976 if (adj > -10) pw.print(' '); 10977 } 10978 pw.print(adj); 10979 pw.print(": "); 10980 pw.print(name); 10981 pw.print(" ("); 10982 pw.print(mProcessList.getMemLevel(adj)/1024); 10983 pw.println(" kB)"); 10984 } 10985 10986 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10987 int opti, boolean dumpAll) { 10988 boolean needSep = false; 10989 10990 if (mLruProcesses.size() > 0) { 10991 if (needSep) pw.println(); 10992 needSep = true; 10993 pw.println(" OOM levels:"); 10994 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 10995 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 10996 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 10997 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 10998 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 10999 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11000 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11001 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11002 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11003 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11004 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11005 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11006 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11007 11008 if (needSep) pw.println(); 11009 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11010 pw.print(" total, non-act at "); 11011 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11012 pw.print(", non-svc at "); 11013 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11014 pw.println("):"); 11015 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11016 needSep = true; 11017 } 11018 11019 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11020 11021 pw.println(); 11022 pw.println(" mHomeProcess: " + mHomeProcess); 11023 pw.println(" mPreviousProcess: " + mPreviousProcess); 11024 if (mHeavyWeightProcess != null) { 11025 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11026 } 11027 11028 return true; 11029 } 11030 11031 /** 11032 * There are three ways to call this: 11033 * - no provider specified: dump all the providers 11034 * - a flattened component name that matched an existing provider was specified as the 11035 * first arg: dump that one provider 11036 * - the first arg isn't the flattened component name of an existing provider: 11037 * dump all providers whose component contains the first arg as a substring 11038 */ 11039 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11040 int opti, boolean dumpAll) { 11041 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11042 } 11043 11044 static class ItemMatcher { 11045 ArrayList<ComponentName> components; 11046 ArrayList<String> strings; 11047 ArrayList<Integer> objects; 11048 boolean all; 11049 11050 ItemMatcher() { 11051 all = true; 11052 } 11053 11054 void build(String name) { 11055 ComponentName componentName = ComponentName.unflattenFromString(name); 11056 if (componentName != null) { 11057 if (components == null) { 11058 components = new ArrayList<ComponentName>(); 11059 } 11060 components.add(componentName); 11061 all = false; 11062 } else { 11063 int objectId = 0; 11064 // Not a '/' separated full component name; maybe an object ID? 11065 try { 11066 objectId = Integer.parseInt(name, 16); 11067 if (objects == null) { 11068 objects = new ArrayList<Integer>(); 11069 } 11070 objects.add(objectId); 11071 all = false; 11072 } catch (RuntimeException e) { 11073 // Not an integer; just do string match. 11074 if (strings == null) { 11075 strings = new ArrayList<String>(); 11076 } 11077 strings.add(name); 11078 all = false; 11079 } 11080 } 11081 } 11082 11083 int build(String[] args, int opti) { 11084 for (; opti<args.length; opti++) { 11085 String name = args[opti]; 11086 if ("--".equals(name)) { 11087 return opti+1; 11088 } 11089 build(name); 11090 } 11091 return opti; 11092 } 11093 11094 boolean match(Object object, ComponentName comp) { 11095 if (all) { 11096 return true; 11097 } 11098 if (components != null) { 11099 for (int i=0; i<components.size(); i++) { 11100 if (components.get(i).equals(comp)) { 11101 return true; 11102 } 11103 } 11104 } 11105 if (objects != null) { 11106 for (int i=0; i<objects.size(); i++) { 11107 if (System.identityHashCode(object) == objects.get(i)) { 11108 return true; 11109 } 11110 } 11111 } 11112 if (strings != null) { 11113 String flat = comp.flattenToString(); 11114 for (int i=0; i<strings.size(); i++) { 11115 if (flat.contains(strings.get(i))) { 11116 return true; 11117 } 11118 } 11119 } 11120 return false; 11121 } 11122 } 11123 11124 /** 11125 * There are three things that cmd can be: 11126 * - a flattened component name that matches an existing activity 11127 * - the cmd arg isn't the flattened component name of an existing activity: 11128 * dump all activity whose component contains the cmd as a substring 11129 * - A hex number of the ActivityRecord object instance. 11130 */ 11131 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11132 int opti, boolean dumpAll) { 11133 ArrayList<ActivityRecord> activities; 11134 11135 synchronized (this) { 11136 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11137 } 11138 11139 if (activities.size() <= 0) { 11140 return false; 11141 } 11142 11143 String[] newArgs = new String[args.length - opti]; 11144 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11145 11146 TaskRecord lastTask = null; 11147 boolean needSep = false; 11148 for (int i=activities.size()-1; i>=0; i--) { 11149 ActivityRecord r = activities.get(i); 11150 if (needSep) { 11151 pw.println(); 11152 } 11153 needSep = true; 11154 synchronized (this) { 11155 if (lastTask != r.task) { 11156 lastTask = r.task; 11157 pw.print("TASK "); pw.print(lastTask.affinity); 11158 pw.print(" id="); pw.println(lastTask.taskId); 11159 if (dumpAll) { 11160 lastTask.dump(pw, " "); 11161 } 11162 } 11163 } 11164 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11165 } 11166 return true; 11167 } 11168 11169 /** 11170 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11171 * there is a thread associated with the activity. 11172 */ 11173 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11174 final ActivityRecord r, String[] args, boolean dumpAll) { 11175 String innerPrefix = prefix + " "; 11176 synchronized (this) { 11177 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11178 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11179 pw.print(" pid="); 11180 if (r.app != null) pw.println(r.app.pid); 11181 else pw.println("(not running)"); 11182 if (dumpAll) { 11183 r.dump(pw, innerPrefix); 11184 } 11185 } 11186 if (r.app != null && r.app.thread != null) { 11187 // flush anything that is already in the PrintWriter since the thread is going 11188 // to write to the file descriptor directly 11189 pw.flush(); 11190 try { 11191 TransferPipe tp = new TransferPipe(); 11192 try { 11193 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11194 r.appToken, innerPrefix, args); 11195 tp.go(fd); 11196 } finally { 11197 tp.kill(); 11198 } 11199 } catch (IOException e) { 11200 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11201 } catch (RemoteException e) { 11202 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11203 } 11204 } 11205 } 11206 11207 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11208 int opti, boolean dumpAll, String dumpPackage) { 11209 boolean needSep = false; 11210 boolean onlyHistory = false; 11211 boolean printedAnything = false; 11212 11213 if ("history".equals(dumpPackage)) { 11214 if (opti < args.length && "-s".equals(args[opti])) { 11215 dumpAll = false; 11216 } 11217 onlyHistory = true; 11218 dumpPackage = null; 11219 } 11220 11221 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11222 if (!onlyHistory && dumpAll) { 11223 if (mRegisteredReceivers.size() > 0) { 11224 boolean printed = false; 11225 Iterator it = mRegisteredReceivers.values().iterator(); 11226 while (it.hasNext()) { 11227 ReceiverList r = (ReceiverList)it.next(); 11228 if (dumpPackage != null && (r.app == null || 11229 !dumpPackage.equals(r.app.info.packageName))) { 11230 continue; 11231 } 11232 if (!printed) { 11233 pw.println(" Registered Receivers:"); 11234 needSep = true; 11235 printed = true; 11236 printedAnything = true; 11237 } 11238 pw.print(" * "); pw.println(r); 11239 r.dump(pw, " "); 11240 } 11241 } 11242 11243 if (mReceiverResolver.dump(pw, needSep ? 11244 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11245 " ", dumpPackage, false)) { 11246 needSep = true; 11247 printedAnything = true; 11248 } 11249 } 11250 11251 for (BroadcastQueue q : mBroadcastQueues) { 11252 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11253 printedAnything |= needSep; 11254 } 11255 11256 needSep = true; 11257 11258 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11259 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11260 if (needSep) { 11261 pw.println(); 11262 } 11263 needSep = true; 11264 printedAnything = true; 11265 pw.print(" Sticky broadcasts for user "); 11266 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11267 StringBuilder sb = new StringBuilder(128); 11268 for (Map.Entry<String, ArrayList<Intent>> ent 11269 : mStickyBroadcasts.valueAt(user).entrySet()) { 11270 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11271 if (dumpAll) { 11272 pw.println(":"); 11273 ArrayList<Intent> intents = ent.getValue(); 11274 final int N = intents.size(); 11275 for (int i=0; i<N; i++) { 11276 sb.setLength(0); 11277 sb.append(" Intent: "); 11278 intents.get(i).toShortString(sb, false, true, false, false); 11279 pw.println(sb.toString()); 11280 Bundle bundle = intents.get(i).getExtras(); 11281 if (bundle != null) { 11282 pw.print(" "); 11283 pw.println(bundle.toString()); 11284 } 11285 } 11286 } else { 11287 pw.println(""); 11288 } 11289 } 11290 } 11291 } 11292 11293 if (!onlyHistory && dumpAll) { 11294 pw.println(); 11295 for (BroadcastQueue queue : mBroadcastQueues) { 11296 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11297 + queue.mBroadcastsScheduled); 11298 } 11299 pw.println(" mHandler:"); 11300 mHandler.dump(new PrintWriterPrinter(pw), " "); 11301 needSep = true; 11302 printedAnything = true; 11303 } 11304 11305 if (!printedAnything) { 11306 pw.println(" (nothing)"); 11307 } 11308 } 11309 11310 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11311 int opti, boolean dumpAll, String dumpPackage) { 11312 boolean needSep; 11313 boolean printedAnything = false; 11314 11315 ItemMatcher matcher = new ItemMatcher(); 11316 matcher.build(args, opti); 11317 11318 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11319 11320 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11321 printedAnything |= needSep; 11322 11323 if (mLaunchingProviders.size() > 0) { 11324 boolean printed = false; 11325 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11326 ContentProviderRecord r = mLaunchingProviders.get(i); 11327 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11328 continue; 11329 } 11330 if (!printed) { 11331 if (needSep) pw.println(); 11332 needSep = true; 11333 pw.println(" Launching content providers:"); 11334 printed = true; 11335 printedAnything = true; 11336 } 11337 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11338 pw.println(r); 11339 } 11340 } 11341 11342 if (mGrantedUriPermissions.size() > 0) { 11343 boolean printed = false; 11344 int dumpUid = -2; 11345 if (dumpPackage != null) { 11346 try { 11347 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11348 } catch (NameNotFoundException e) { 11349 dumpUid = -1; 11350 } 11351 } 11352 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11353 int uid = mGrantedUriPermissions.keyAt(i); 11354 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11355 continue; 11356 } 11357 ArrayMap<Uri, UriPermission> perms 11358 = mGrantedUriPermissions.valueAt(i); 11359 if (!printed) { 11360 if (needSep) pw.println(); 11361 needSep = true; 11362 pw.println(" Granted Uri Permissions:"); 11363 printed = true; 11364 printedAnything = true; 11365 } 11366 pw.print(" * UID "); pw.print(uid); 11367 pw.println(" holds:"); 11368 for (UriPermission perm : perms.values()) { 11369 pw.print(" "); pw.println(perm); 11370 if (dumpAll) { 11371 perm.dump(pw, " "); 11372 } 11373 } 11374 } 11375 } 11376 11377 if (!printedAnything) { 11378 pw.println(" (nothing)"); 11379 } 11380 } 11381 11382 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11383 int opti, boolean dumpAll, String dumpPackage) { 11384 boolean printed = false; 11385 11386 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11387 11388 if (mIntentSenderRecords.size() > 0) { 11389 Iterator<WeakReference<PendingIntentRecord>> it 11390 = mIntentSenderRecords.values().iterator(); 11391 while (it.hasNext()) { 11392 WeakReference<PendingIntentRecord> ref = it.next(); 11393 PendingIntentRecord rec = ref != null ? ref.get(): null; 11394 if (dumpPackage != null && (rec == null 11395 || !dumpPackage.equals(rec.key.packageName))) { 11396 continue; 11397 } 11398 printed = true; 11399 if (rec != null) { 11400 pw.print(" * "); pw.println(rec); 11401 if (dumpAll) { 11402 rec.dump(pw, " "); 11403 } 11404 } else { 11405 pw.print(" * "); pw.println(ref); 11406 } 11407 } 11408 } 11409 11410 if (!printed) { 11411 pw.println(" (nothing)"); 11412 } 11413 } 11414 11415 private static final int dumpProcessList(PrintWriter pw, 11416 ActivityManagerService service, List list, 11417 String prefix, String normalLabel, String persistentLabel, 11418 String dumpPackage) { 11419 int numPers = 0; 11420 final int N = list.size()-1; 11421 for (int i=N; i>=0; i--) { 11422 ProcessRecord r = (ProcessRecord)list.get(i); 11423 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11424 continue; 11425 } 11426 pw.println(String.format("%s%s #%2d: %s", 11427 prefix, (r.persistent ? persistentLabel : normalLabel), 11428 i, r.toString())); 11429 if (r.persistent) { 11430 numPers++; 11431 } 11432 } 11433 return numPers; 11434 } 11435 11436 private static final boolean dumpProcessOomList(PrintWriter pw, 11437 ActivityManagerService service, List<ProcessRecord> origList, 11438 String prefix, String normalLabel, String persistentLabel, 11439 boolean inclDetails, String dumpPackage) { 11440 11441 ArrayList<Pair<ProcessRecord, Integer>> list 11442 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11443 for (int i=0; i<origList.size(); i++) { 11444 ProcessRecord r = origList.get(i); 11445 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11446 continue; 11447 } 11448 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11449 } 11450 11451 if (list.size() <= 0) { 11452 return false; 11453 } 11454 11455 Comparator<Pair<ProcessRecord, Integer>> comparator 11456 = new Comparator<Pair<ProcessRecord, Integer>>() { 11457 @Override 11458 public int compare(Pair<ProcessRecord, Integer> object1, 11459 Pair<ProcessRecord, Integer> object2) { 11460 if (object1.first.setAdj != object2.first.setAdj) { 11461 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11462 } 11463 if (object1.second.intValue() != object2.second.intValue()) { 11464 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11465 } 11466 return 0; 11467 } 11468 }; 11469 11470 Collections.sort(list, comparator); 11471 11472 final long curRealtime = SystemClock.elapsedRealtime(); 11473 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11474 final long curUptime = SystemClock.uptimeMillis(); 11475 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11476 11477 for (int i=list.size()-1; i>=0; i--) { 11478 ProcessRecord r = list.get(i).first; 11479 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11480 char schedGroup; 11481 switch (r.setSchedGroup) { 11482 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11483 schedGroup = 'B'; 11484 break; 11485 case Process.THREAD_GROUP_DEFAULT: 11486 schedGroup = 'F'; 11487 break; 11488 default: 11489 schedGroup = '?'; 11490 break; 11491 } 11492 char foreground; 11493 if (r.foregroundActivities) { 11494 foreground = 'A'; 11495 } else if (r.foregroundServices) { 11496 foreground = 'S'; 11497 } else { 11498 foreground = ' '; 11499 } 11500 String procState = ProcessList.makeProcStateString(r.curProcState); 11501 pw.print(prefix); 11502 pw.print(r.persistent ? persistentLabel : normalLabel); 11503 pw.print(" #"); 11504 int num = (origList.size()-1)-list.get(i).second; 11505 if (num < 10) pw.print(' '); 11506 pw.print(num); 11507 pw.print(": "); 11508 pw.print(oomAdj); 11509 pw.print(' '); 11510 pw.print(schedGroup); 11511 pw.print('/'); 11512 pw.print(foreground); 11513 pw.print('/'); 11514 pw.print(procState); 11515 pw.print(" trm:"); 11516 if (r.trimMemoryLevel < 10) pw.print(' '); 11517 pw.print(r.trimMemoryLevel); 11518 pw.print(' '); 11519 pw.print(r.toShortString()); 11520 pw.print(" ("); 11521 pw.print(r.adjType); 11522 pw.println(')'); 11523 if (r.adjSource != null || r.adjTarget != null) { 11524 pw.print(prefix); 11525 pw.print(" "); 11526 if (r.adjTarget instanceof ComponentName) { 11527 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11528 } else if (r.adjTarget != null) { 11529 pw.print(r.adjTarget.toString()); 11530 } else { 11531 pw.print("{null}"); 11532 } 11533 pw.print("<="); 11534 if (r.adjSource instanceof ProcessRecord) { 11535 pw.print("Proc{"); 11536 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11537 pw.println("}"); 11538 } else if (r.adjSource != null) { 11539 pw.println(r.adjSource.toString()); 11540 } else { 11541 pw.println("{null}"); 11542 } 11543 } 11544 if (inclDetails) { 11545 pw.print(prefix); 11546 pw.print(" "); 11547 pw.print("oom: max="); pw.print(r.maxAdj); 11548 pw.print(" curRaw="); pw.print(r.curRawAdj); 11549 pw.print(" setRaw="); pw.print(r.setRawAdj); 11550 pw.print(" cur="); pw.print(r.curAdj); 11551 pw.print(" set="); pw.println(r.setAdj); 11552 pw.print(prefix); 11553 pw.print(" "); 11554 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11555 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11556 pw.print(" lastPss="); pw.print(r.lastPss); 11557 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11558 pw.print(prefix); 11559 pw.print(" "); 11560 pw.print("keeping="); pw.print(r.keeping); 11561 pw.print(" cached="); pw.print(r.cached); 11562 pw.print(" empty="); pw.print(r.empty); 11563 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11564 11565 if (!r.keeping) { 11566 if (r.lastWakeTime != 0) { 11567 long wtime; 11568 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11569 synchronized (stats) { 11570 wtime = stats.getProcessWakeTime(r.info.uid, 11571 r.pid, curRealtime); 11572 } 11573 long timeUsed = wtime - r.lastWakeTime; 11574 pw.print(prefix); 11575 pw.print(" "); 11576 pw.print("keep awake over "); 11577 TimeUtils.formatDuration(realtimeSince, pw); 11578 pw.print(" used "); 11579 TimeUtils.formatDuration(timeUsed, pw); 11580 pw.print(" ("); 11581 pw.print((timeUsed*100)/realtimeSince); 11582 pw.println("%)"); 11583 } 11584 if (r.lastCpuTime != 0) { 11585 long timeUsed = r.curCpuTime - r.lastCpuTime; 11586 pw.print(prefix); 11587 pw.print(" "); 11588 pw.print("run cpu over "); 11589 TimeUtils.formatDuration(uptimeSince, pw); 11590 pw.print(" used "); 11591 TimeUtils.formatDuration(timeUsed, pw); 11592 pw.print(" ("); 11593 pw.print((timeUsed*100)/uptimeSince); 11594 pw.println("%)"); 11595 } 11596 } 11597 } 11598 } 11599 return true; 11600 } 11601 11602 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11603 ArrayList<ProcessRecord> procs; 11604 synchronized (this) { 11605 if (args != null && args.length > start 11606 && args[start].charAt(0) != '-') { 11607 procs = new ArrayList<ProcessRecord>(); 11608 int pid = -1; 11609 try { 11610 pid = Integer.parseInt(args[start]); 11611 } catch (NumberFormatException e) { 11612 } 11613 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11614 ProcessRecord proc = mLruProcesses.get(i); 11615 if (proc.pid == pid) { 11616 procs.add(proc); 11617 } else if (proc.processName.equals(args[start])) { 11618 procs.add(proc); 11619 } 11620 } 11621 if (procs.size() <= 0) { 11622 return null; 11623 } 11624 } else { 11625 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11626 } 11627 } 11628 return procs; 11629 } 11630 11631 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11632 PrintWriter pw, String[] args) { 11633 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11634 if (procs == null) { 11635 pw.println("No process found for: " + args[0]); 11636 return; 11637 } 11638 11639 long uptime = SystemClock.uptimeMillis(); 11640 long realtime = SystemClock.elapsedRealtime(); 11641 pw.println("Applications Graphics Acceleration Info:"); 11642 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11643 11644 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11645 ProcessRecord r = procs.get(i); 11646 if (r.thread != null) { 11647 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11648 pw.flush(); 11649 try { 11650 TransferPipe tp = new TransferPipe(); 11651 try { 11652 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11653 tp.go(fd); 11654 } finally { 11655 tp.kill(); 11656 } 11657 } catch (IOException e) { 11658 pw.println("Failure while dumping the app: " + r); 11659 pw.flush(); 11660 } catch (RemoteException e) { 11661 pw.println("Got a RemoteException while dumping the app " + r); 11662 pw.flush(); 11663 } 11664 } 11665 } 11666 } 11667 11668 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11669 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11670 if (procs == null) { 11671 pw.println("No process found for: " + args[0]); 11672 return; 11673 } 11674 11675 pw.println("Applications Database Info:"); 11676 11677 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11678 ProcessRecord r = procs.get(i); 11679 if (r.thread != null) { 11680 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11681 pw.flush(); 11682 try { 11683 TransferPipe tp = new TransferPipe(); 11684 try { 11685 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11686 tp.go(fd); 11687 } finally { 11688 tp.kill(); 11689 } 11690 } catch (IOException e) { 11691 pw.println("Failure while dumping the app: " + r); 11692 pw.flush(); 11693 } catch (RemoteException e) { 11694 pw.println("Got a RemoteException while dumping the app " + r); 11695 pw.flush(); 11696 } 11697 } 11698 } 11699 } 11700 11701 final static class MemItem { 11702 final boolean isProc; 11703 final String label; 11704 final String shortLabel; 11705 final long pss; 11706 final int id; 11707 final boolean hasActivities; 11708 ArrayList<MemItem> subitems; 11709 11710 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11711 boolean _hasActivities) { 11712 isProc = true; 11713 label = _label; 11714 shortLabel = _shortLabel; 11715 pss = _pss; 11716 id = _id; 11717 hasActivities = _hasActivities; 11718 } 11719 11720 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11721 isProc = false; 11722 label = _label; 11723 shortLabel = _shortLabel; 11724 pss = _pss; 11725 id = _id; 11726 hasActivities = false; 11727 } 11728 } 11729 11730 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11731 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11732 if (sort && !isCompact) { 11733 Collections.sort(items, new Comparator<MemItem>() { 11734 @Override 11735 public int compare(MemItem lhs, MemItem rhs) { 11736 if (lhs.pss < rhs.pss) { 11737 return 1; 11738 } else if (lhs.pss > rhs.pss) { 11739 return -1; 11740 } 11741 return 0; 11742 } 11743 }); 11744 } 11745 11746 for (int i=0; i<items.size(); i++) { 11747 MemItem mi = items.get(i); 11748 if (!isCompact) { 11749 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11750 } else if (mi.isProc) { 11751 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11752 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11753 pw.println(mi.hasActivities ? ",a" : ",e"); 11754 } else { 11755 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11756 pw.println(mi.pss); 11757 } 11758 if (mi.subitems != null) { 11759 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11760 true, isCompact); 11761 } 11762 } 11763 } 11764 11765 // These are in KB. 11766 static final long[] DUMP_MEM_BUCKETS = new long[] { 11767 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11768 120*1024, 160*1024, 200*1024, 11769 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11770 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11771 }; 11772 11773 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11774 boolean stackLike) { 11775 int start = label.lastIndexOf('.'); 11776 if (start >= 0) start++; 11777 else start = 0; 11778 int end = label.length(); 11779 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11780 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11781 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11782 out.append(bucket); 11783 out.append(stackLike ? "MB." : "MB "); 11784 out.append(label, start, end); 11785 return; 11786 } 11787 } 11788 out.append(memKB/1024); 11789 out.append(stackLike ? "MB." : "MB "); 11790 out.append(label, start, end); 11791 } 11792 11793 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11794 ProcessList.NATIVE_ADJ, 11795 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11796 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11797 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11798 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11799 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11800 }; 11801 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11802 "Native", 11803 "System", "Persistent", "Foreground", 11804 "Visible", "Perceptible", 11805 "Heavy Weight", "Backup", 11806 "A Services", "Home", 11807 "Previous", "B Services", "Cached" 11808 }; 11809 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 11810 "native", 11811 "sys", "pers", "fore", 11812 "vis", "percept", 11813 "heavy", "backup", 11814 "servicea", "home", 11815 "prev", "serviceb", "cached" 11816 }; 11817 11818 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 11819 long realtime, boolean isCheckinRequest, boolean isCompact) { 11820 if (isCheckinRequest || isCompact) { 11821 // short checkin version 11822 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 11823 } else { 11824 pw.println("Applications Memory Usage (kB):"); 11825 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11826 } 11827 } 11828 11829 final void dumpApplicationMemoryUsage(FileDescriptor fd, 11830 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 11831 boolean dumpDetails = false; 11832 boolean dumpFullDetails = false; 11833 boolean dumpDalvik = false; 11834 boolean oomOnly = false; 11835 boolean isCompact = false; 11836 boolean localOnly = false; 11837 11838 int opti = 0; 11839 while (opti < args.length) { 11840 String opt = args[opti]; 11841 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11842 break; 11843 } 11844 opti++; 11845 if ("-a".equals(opt)) { 11846 dumpDetails = true; 11847 dumpFullDetails = true; 11848 dumpDalvik = true; 11849 } else if ("-d".equals(opt)) { 11850 dumpDalvik = true; 11851 } else if ("-c".equals(opt)) { 11852 isCompact = true; 11853 } else if ("--oom".equals(opt)) { 11854 oomOnly = true; 11855 } else if ("--local".equals(opt)) { 11856 localOnly = true; 11857 } else if ("-h".equals(opt)) { 11858 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 11859 pw.println(" -a: include all available information for each process."); 11860 pw.println(" -d: include dalvik details when dumping process details."); 11861 pw.println(" -c: dump in a compact machine-parseable representation."); 11862 pw.println(" --oom: only show processes organized by oom adj."); 11863 pw.println(" --local: only collect details locally, don't call process."); 11864 pw.println("If [process] is specified it can be the name or "); 11865 pw.println("pid of a specific process to dump."); 11866 return; 11867 } else { 11868 pw.println("Unknown argument: " + opt + "; use -h for help"); 11869 } 11870 } 11871 11872 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 11873 long uptime = SystemClock.uptimeMillis(); 11874 long realtime = SystemClock.elapsedRealtime(); 11875 final long[] tmpLong = new long[1]; 11876 11877 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 11878 if (procs == null) { 11879 // No Java processes. Maybe they want to print a native process. 11880 if (args != null && args.length > opti 11881 && args[opti].charAt(0) != '-') { 11882 ArrayList<ProcessCpuTracker.Stats> nativeProcs 11883 = new ArrayList<ProcessCpuTracker.Stats>(); 11884 updateCpuStatsNow(); 11885 int findPid = -1; 11886 try { 11887 findPid = Integer.parseInt(args[opti]); 11888 } catch (NumberFormatException e) { 11889 } 11890 synchronized (mProcessCpuThread) { 11891 final int N = mProcessCpuTracker.countStats(); 11892 for (int i=0; i<N; i++) { 11893 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 11894 if (st.pid == findPid || (st.baseName != null 11895 && st.baseName.equals(args[opti]))) { 11896 nativeProcs.add(st); 11897 } 11898 } 11899 } 11900 if (nativeProcs.size() > 0) { 11901 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 11902 isCompact); 11903 Debug.MemoryInfo mi = null; 11904 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 11905 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 11906 final int pid = r.pid; 11907 if (!isCheckinRequest && dumpDetails) { 11908 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 11909 } 11910 if (mi == null) { 11911 mi = new Debug.MemoryInfo(); 11912 } 11913 if (dumpDetails || (!brief && !oomOnly)) { 11914 Debug.getMemoryInfo(pid, mi); 11915 } else { 11916 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11917 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11918 } 11919 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11920 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 11921 if (isCheckinRequest) { 11922 pw.println(); 11923 } 11924 } 11925 return; 11926 } 11927 } 11928 pw.println("No process found for: " + args[opti]); 11929 return; 11930 } 11931 11932 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 11933 dumpDetails = true; 11934 } 11935 11936 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 11937 11938 String[] innerArgs = new String[args.length-opti]; 11939 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 11940 11941 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 11942 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 11943 long nativePss=0, dalvikPss=0, otherPss=0; 11944 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 11945 11946 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 11947 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 11948 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 11949 11950 long totalPss = 0; 11951 long cachedPss = 0; 11952 11953 Debug.MemoryInfo mi = null; 11954 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11955 final ProcessRecord r = procs.get(i); 11956 final IApplicationThread thread; 11957 final int pid; 11958 final int oomAdj; 11959 final boolean hasActivities; 11960 synchronized (this) { 11961 thread = r.thread; 11962 pid = r.pid; 11963 oomAdj = r.getSetAdjWithServices(); 11964 hasActivities = r.activities.size() > 0; 11965 } 11966 if (thread != null) { 11967 if (!isCheckinRequest && dumpDetails) { 11968 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 11969 } 11970 if (mi == null) { 11971 mi = new Debug.MemoryInfo(); 11972 } 11973 if (dumpDetails || (!brief && !oomOnly)) { 11974 Debug.getMemoryInfo(pid, mi); 11975 } else { 11976 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11977 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11978 } 11979 if (dumpDetails) { 11980 if (localOnly) { 11981 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11982 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 11983 if (isCheckinRequest) { 11984 pw.println(); 11985 } 11986 } else { 11987 try { 11988 pw.flush(); 11989 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 11990 dumpDalvik, innerArgs); 11991 } catch (RemoteException e) { 11992 if (!isCheckinRequest) { 11993 pw.println("Got RemoteException!"); 11994 pw.flush(); 11995 } 11996 } 11997 } 11998 } 11999 12000 final long myTotalPss = mi.getTotalPss(); 12001 final long myTotalUss = mi.getTotalUss(); 12002 12003 synchronized (this) { 12004 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12005 // Record this for posterity if the process has been stable. 12006 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12007 } 12008 } 12009 12010 if (!isCheckinRequest && mi != null) { 12011 totalPss += myTotalPss; 12012 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12013 (hasActivities ? " / activities)" : ")"), 12014 r.processName, myTotalPss, pid, hasActivities); 12015 procMems.add(pssItem); 12016 procMemsMap.put(pid, pssItem); 12017 12018 nativePss += mi.nativePss; 12019 dalvikPss += mi.dalvikPss; 12020 otherPss += mi.otherPss; 12021 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12022 long mem = mi.getOtherPss(j); 12023 miscPss[j] += mem; 12024 otherPss -= mem; 12025 } 12026 12027 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12028 cachedPss += myTotalPss; 12029 } 12030 12031 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12032 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12033 || oomIndex == (oomPss.length-1)) { 12034 oomPss[oomIndex] += myTotalPss; 12035 if (oomProcs[oomIndex] == null) { 12036 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12037 } 12038 oomProcs[oomIndex].add(pssItem); 12039 break; 12040 } 12041 } 12042 } 12043 } 12044 } 12045 12046 if (!isCheckinRequest && procs.size() > 1) { 12047 // If we are showing aggregations, also look for native processes to 12048 // include so that our aggregations are more accurate. 12049 updateCpuStatsNow(); 12050 synchronized (mProcessCpuThread) { 12051 final int N = mProcessCpuTracker.countStats(); 12052 for (int i=0; i<N; i++) { 12053 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12054 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12055 if (mi == null) { 12056 mi = new Debug.MemoryInfo(); 12057 } 12058 if (!brief && !oomOnly) { 12059 Debug.getMemoryInfo(st.pid, mi); 12060 } else { 12061 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12062 mi.nativePrivateDirty = (int)tmpLong[0]; 12063 } 12064 12065 final long myTotalPss = mi.getTotalPss(); 12066 totalPss += myTotalPss; 12067 12068 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12069 st.name, myTotalPss, st.pid, false); 12070 procMems.add(pssItem); 12071 12072 nativePss += mi.nativePss; 12073 dalvikPss += mi.dalvikPss; 12074 otherPss += mi.otherPss; 12075 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12076 long mem = mi.getOtherPss(j); 12077 miscPss[j] += mem; 12078 otherPss -= mem; 12079 } 12080 oomPss[0] += myTotalPss; 12081 if (oomProcs[0] == null) { 12082 oomProcs[0] = new ArrayList<MemItem>(); 12083 } 12084 oomProcs[0].add(pssItem); 12085 } 12086 } 12087 } 12088 12089 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12090 12091 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12092 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12093 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12094 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12095 String label = Debug.MemoryInfo.getOtherLabel(j); 12096 catMems.add(new MemItem(label, label, miscPss[j], j)); 12097 } 12098 12099 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12100 for (int j=0; j<oomPss.length; j++) { 12101 if (oomPss[j] != 0) { 12102 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12103 : DUMP_MEM_OOM_LABEL[j]; 12104 MemItem item = new MemItem(label, label, oomPss[j], 12105 DUMP_MEM_OOM_ADJ[j]); 12106 item.subitems = oomProcs[j]; 12107 oomMems.add(item); 12108 } 12109 } 12110 12111 if (!brief && !oomOnly && !isCompact) { 12112 pw.println(); 12113 pw.println("Total PSS by process:"); 12114 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12115 pw.println(); 12116 } 12117 if (!isCompact) { 12118 pw.println("Total PSS by OOM adjustment:"); 12119 } 12120 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12121 if (!brief && !oomOnly) { 12122 PrintWriter out = categoryPw != null ? categoryPw : pw; 12123 if (!isCompact) { 12124 out.println(); 12125 out.println("Total PSS by category:"); 12126 } 12127 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12128 } 12129 if (!isCompact) { 12130 pw.println(); 12131 } 12132 MemInfoReader memInfo = new MemInfoReader(); 12133 memInfo.readMemInfo(); 12134 if (!brief) { 12135 if (!isCompact) { 12136 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12137 pw.print(" kB (status "); 12138 switch (mLastMemoryLevel) { 12139 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12140 pw.println("normal)"); 12141 break; 12142 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12143 pw.println("moderate)"); 12144 break; 12145 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12146 pw.println("low)"); 12147 break; 12148 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12149 pw.println("critical)"); 12150 break; 12151 default: 12152 pw.print(mLastMemoryLevel); 12153 pw.println(")"); 12154 break; 12155 } 12156 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12157 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12158 pw.print(cachedPss); pw.print(" cached pss + "); 12159 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12160 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12161 } else { 12162 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12163 pw.print(cachedPss + memInfo.getCachedSizeKb() 12164 + memInfo.getFreeSizeKb()); pw.print(","); 12165 pw.println(totalPss - cachedPss); 12166 } 12167 } 12168 if (!isCompact) { 12169 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12170 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12171 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12172 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12173 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12174 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12175 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12176 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12177 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12178 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12179 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12180 } 12181 if (!brief) { 12182 if (memInfo.getZramTotalSizeKb() != 0) { 12183 if (!isCompact) { 12184 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12185 pw.print(" kB physical used for "); 12186 pw.print(memInfo.getSwapTotalSizeKb() 12187 - memInfo.getSwapFreeSizeKb()); 12188 pw.print(" kB in swap ("); 12189 pw.print(memInfo.getSwapTotalSizeKb()); 12190 pw.println(" kB total swap)"); 12191 } else { 12192 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12193 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12194 pw.println(memInfo.getSwapFreeSizeKb()); 12195 } 12196 } 12197 final int[] SINGLE_LONG_FORMAT = new int[] { 12198 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12199 }; 12200 long[] longOut = new long[1]; 12201 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12202 SINGLE_LONG_FORMAT, null, longOut, null); 12203 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12204 longOut[0] = 0; 12205 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12206 SINGLE_LONG_FORMAT, null, longOut, null); 12207 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12208 longOut[0] = 0; 12209 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12210 SINGLE_LONG_FORMAT, null, longOut, null); 12211 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12212 longOut[0] = 0; 12213 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12214 SINGLE_LONG_FORMAT, null, longOut, null); 12215 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12216 if (!isCompact) { 12217 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12218 pw.print(" KSM: "); pw.print(sharing); 12219 pw.print(" kB saved from shared "); 12220 pw.print(shared); pw.println(" kB"); 12221 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12222 pw.print(voltile); pw.println(" kB volatile"); 12223 } 12224 pw.print(" Tuning: "); 12225 pw.print(ActivityManager.staticGetMemoryClass()); 12226 pw.print(" (large "); 12227 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12228 pw.print("), oom "); 12229 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12230 pw.print(" kB"); 12231 pw.print(", restore limit "); 12232 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12233 pw.print(" kB"); 12234 if (ActivityManager.isLowRamDeviceStatic()) { 12235 pw.print(" (low-ram)"); 12236 } 12237 if (ActivityManager.isHighEndGfx()) { 12238 pw.print(" (high-end-gfx)"); 12239 } 12240 pw.println(); 12241 } else { 12242 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12243 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12244 pw.println(voltile); 12245 pw.print("tuning,"); 12246 pw.print(ActivityManager.staticGetMemoryClass()); 12247 pw.print(','); 12248 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12249 pw.print(','); 12250 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12251 if (ActivityManager.isLowRamDeviceStatic()) { 12252 pw.print(",low-ram"); 12253 } 12254 if (ActivityManager.isHighEndGfx()) { 12255 pw.print(",high-end-gfx"); 12256 } 12257 pw.println(); 12258 } 12259 } 12260 } 12261 } 12262 12263 /** 12264 * Searches array of arguments for the specified string 12265 * @param args array of argument strings 12266 * @param value value to search for 12267 * @return true if the value is contained in the array 12268 */ 12269 private static boolean scanArgs(String[] args, String value) { 12270 if (args != null) { 12271 for (String arg : args) { 12272 if (value.equals(arg)) { 12273 return true; 12274 } 12275 } 12276 } 12277 return false; 12278 } 12279 12280 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12281 ContentProviderRecord cpr, boolean always) { 12282 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12283 12284 if (!inLaunching || always) { 12285 synchronized (cpr) { 12286 cpr.launchingApp = null; 12287 cpr.notifyAll(); 12288 } 12289 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12290 String names[] = cpr.info.authority.split(";"); 12291 for (int j = 0; j < names.length; j++) { 12292 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12293 } 12294 } 12295 12296 for (int i=0; i<cpr.connections.size(); i++) { 12297 ContentProviderConnection conn = cpr.connections.get(i); 12298 if (conn.waiting) { 12299 // If this connection is waiting for the provider, then we don't 12300 // need to mess with its process unless we are always removing 12301 // or for some reason the provider is not currently launching. 12302 if (inLaunching && !always) { 12303 continue; 12304 } 12305 } 12306 ProcessRecord capp = conn.client; 12307 conn.dead = true; 12308 if (conn.stableCount > 0) { 12309 if (!capp.persistent && capp.thread != null 12310 && capp.pid != 0 12311 && capp.pid != MY_PID) { 12312 killUnneededProcessLocked(capp, "depends on provider " 12313 + cpr.name.flattenToShortString() 12314 + " in dying proc " + (proc != null ? proc.processName : "??")); 12315 } 12316 } else if (capp.thread != null && conn.provider.provider != null) { 12317 try { 12318 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12319 } catch (RemoteException e) { 12320 } 12321 // In the protocol here, we don't expect the client to correctly 12322 // clean up this connection, we'll just remove it. 12323 cpr.connections.remove(i); 12324 conn.client.conProviders.remove(conn); 12325 } 12326 } 12327 12328 if (inLaunching && always) { 12329 mLaunchingProviders.remove(cpr); 12330 } 12331 return inLaunching; 12332 } 12333 12334 /** 12335 * Main code for cleaning up a process when it has gone away. This is 12336 * called both as a result of the process dying, or directly when stopping 12337 * a process when running in single process mode. 12338 */ 12339 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12340 boolean restarting, boolean allowRestart, int index) { 12341 if (index >= 0) { 12342 removeLruProcessLocked(app); 12343 ProcessList.remove(app.pid); 12344 } 12345 12346 mProcessesToGc.remove(app); 12347 mPendingPssProcesses.remove(app); 12348 12349 // Dismiss any open dialogs. 12350 if (app.crashDialog != null && !app.forceCrashReport) { 12351 app.crashDialog.dismiss(); 12352 app.crashDialog = null; 12353 } 12354 if (app.anrDialog != null) { 12355 app.anrDialog.dismiss(); 12356 app.anrDialog = null; 12357 } 12358 if (app.waitDialog != null) { 12359 app.waitDialog.dismiss(); 12360 app.waitDialog = null; 12361 } 12362 12363 app.crashing = false; 12364 app.notResponding = false; 12365 12366 app.resetPackageList(mProcessStats); 12367 app.unlinkDeathRecipient(); 12368 app.makeInactive(mProcessStats); 12369 app.forcingToForeground = null; 12370 updateProcessForegroundLocked(app, false, false); 12371 app.foregroundActivities = false; 12372 app.hasShownUi = false; 12373 app.hasAboveClient = false; 12374 12375 mServices.killServicesLocked(app, allowRestart); 12376 12377 boolean restart = false; 12378 12379 // Remove published content providers. 12380 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12381 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12382 final boolean always = app.bad || !allowRestart; 12383 if (removeDyingProviderLocked(app, cpr, always) || always) { 12384 // We left the provider in the launching list, need to 12385 // restart it. 12386 restart = true; 12387 } 12388 12389 cpr.provider = null; 12390 cpr.proc = null; 12391 } 12392 app.pubProviders.clear(); 12393 12394 // Take care of any launching providers waiting for this process. 12395 if (checkAppInLaunchingProvidersLocked(app, false)) { 12396 restart = true; 12397 } 12398 12399 // Unregister from connected content providers. 12400 if (!app.conProviders.isEmpty()) { 12401 for (int i=0; i<app.conProviders.size(); i++) { 12402 ContentProviderConnection conn = app.conProviders.get(i); 12403 conn.provider.connections.remove(conn); 12404 } 12405 app.conProviders.clear(); 12406 } 12407 12408 // At this point there may be remaining entries in mLaunchingProviders 12409 // where we were the only one waiting, so they are no longer of use. 12410 // Look for these and clean up if found. 12411 // XXX Commented out for now. Trying to figure out a way to reproduce 12412 // the actual situation to identify what is actually going on. 12413 if (false) { 12414 for (int i=0; i<mLaunchingProviders.size(); i++) { 12415 ContentProviderRecord cpr = (ContentProviderRecord) 12416 mLaunchingProviders.get(i); 12417 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12418 synchronized (cpr) { 12419 cpr.launchingApp = null; 12420 cpr.notifyAll(); 12421 } 12422 } 12423 } 12424 } 12425 12426 skipCurrentReceiverLocked(app); 12427 12428 // Unregister any receivers. 12429 for (int i=app.receivers.size()-1; i>=0; i--) { 12430 removeReceiverLocked(app.receivers.valueAt(i)); 12431 } 12432 app.receivers.clear(); 12433 12434 // If the app is undergoing backup, tell the backup manager about it 12435 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12436 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12437 + mBackupTarget.appInfo + " died during backup"); 12438 try { 12439 IBackupManager bm = IBackupManager.Stub.asInterface( 12440 ServiceManager.getService(Context.BACKUP_SERVICE)); 12441 bm.agentDisconnected(app.info.packageName); 12442 } catch (RemoteException e) { 12443 // can't happen; backup manager is local 12444 } 12445 } 12446 12447 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12448 ProcessChangeItem item = mPendingProcessChanges.get(i); 12449 if (item.pid == app.pid) { 12450 mPendingProcessChanges.remove(i); 12451 mAvailProcessChanges.add(item); 12452 } 12453 } 12454 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12455 12456 // If the caller is restarting this app, then leave it in its 12457 // current lists and let the caller take care of it. 12458 if (restarting) { 12459 return; 12460 } 12461 12462 if (!app.persistent || app.isolated) { 12463 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12464 "Removing non-persistent process during cleanup: " + app); 12465 mProcessNames.remove(app.processName, app.uid); 12466 mIsolatedProcesses.remove(app.uid); 12467 if (mHeavyWeightProcess == app) { 12468 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12469 mHeavyWeightProcess.userId, 0)); 12470 mHeavyWeightProcess = null; 12471 } 12472 } else if (!app.removed) { 12473 // This app is persistent, so we need to keep its record around. 12474 // If it is not already on the pending app list, add it there 12475 // and start a new process for it. 12476 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12477 mPersistentStartingProcesses.add(app); 12478 restart = true; 12479 } 12480 } 12481 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12482 "Clean-up removing on hold: " + app); 12483 mProcessesOnHold.remove(app); 12484 12485 if (app == mHomeProcess) { 12486 mHomeProcess = null; 12487 } 12488 if (app == mPreviousProcess) { 12489 mPreviousProcess = null; 12490 } 12491 12492 if (restart && !app.isolated) { 12493 // We have components that still need to be running in the 12494 // process, so re-launch it. 12495 mProcessNames.put(app.processName, app.uid, app); 12496 startProcessLocked(app, "restart", app.processName); 12497 } else if (app.pid > 0 && app.pid != MY_PID) { 12498 // Goodbye! 12499 boolean removed; 12500 synchronized (mPidsSelfLocked) { 12501 mPidsSelfLocked.remove(app.pid); 12502 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12503 } 12504 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12505 app.processName, app.info.uid); 12506 if (app.isolated) { 12507 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12508 } 12509 app.setPid(0); 12510 } 12511 } 12512 12513 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12514 // Look through the content providers we are waiting to have launched, 12515 // and if any run in this process then either schedule a restart of 12516 // the process or kill the client waiting for it if this process has 12517 // gone bad. 12518 int NL = mLaunchingProviders.size(); 12519 boolean restart = false; 12520 for (int i=0; i<NL; i++) { 12521 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12522 if (cpr.launchingApp == app) { 12523 if (!alwaysBad && !app.bad) { 12524 restart = true; 12525 } else { 12526 removeDyingProviderLocked(app, cpr, true); 12527 // cpr should have been removed from mLaunchingProviders 12528 NL = mLaunchingProviders.size(); 12529 i--; 12530 } 12531 } 12532 } 12533 return restart; 12534 } 12535 12536 // ========================================================= 12537 // SERVICES 12538 // ========================================================= 12539 12540 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12541 int flags) { 12542 enforceNotIsolatedCaller("getServices"); 12543 synchronized (this) { 12544 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12545 } 12546 } 12547 12548 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12549 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12550 synchronized (this) { 12551 return mServices.getRunningServiceControlPanelLocked(name); 12552 } 12553 } 12554 12555 public ComponentName startService(IApplicationThread caller, Intent service, 12556 String resolvedType, int userId) { 12557 enforceNotIsolatedCaller("startService"); 12558 // Refuse possible leaked file descriptors 12559 if (service != null && service.hasFileDescriptors() == true) { 12560 throw new IllegalArgumentException("File descriptors passed in Intent"); 12561 } 12562 12563 if (DEBUG_SERVICE) 12564 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12565 synchronized(this) { 12566 final int callingPid = Binder.getCallingPid(); 12567 final int callingUid = Binder.getCallingUid(); 12568 final long origId = Binder.clearCallingIdentity(); 12569 ComponentName res = mServices.startServiceLocked(caller, service, 12570 resolvedType, callingPid, callingUid, userId); 12571 Binder.restoreCallingIdentity(origId); 12572 return res; 12573 } 12574 } 12575 12576 ComponentName startServiceInPackage(int uid, 12577 Intent service, String resolvedType, int userId) { 12578 synchronized(this) { 12579 if (DEBUG_SERVICE) 12580 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12581 final long origId = Binder.clearCallingIdentity(); 12582 ComponentName res = mServices.startServiceLocked(null, service, 12583 resolvedType, -1, uid, userId); 12584 Binder.restoreCallingIdentity(origId); 12585 return res; 12586 } 12587 } 12588 12589 public int stopService(IApplicationThread caller, Intent service, 12590 String resolvedType, int userId) { 12591 enforceNotIsolatedCaller("stopService"); 12592 // Refuse possible leaked file descriptors 12593 if (service != null && service.hasFileDescriptors() == true) { 12594 throw new IllegalArgumentException("File descriptors passed in Intent"); 12595 } 12596 12597 synchronized(this) { 12598 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12599 } 12600 } 12601 12602 public IBinder peekService(Intent service, String resolvedType) { 12603 enforceNotIsolatedCaller("peekService"); 12604 // Refuse possible leaked file descriptors 12605 if (service != null && service.hasFileDescriptors() == true) { 12606 throw new IllegalArgumentException("File descriptors passed in Intent"); 12607 } 12608 synchronized(this) { 12609 return mServices.peekServiceLocked(service, resolvedType); 12610 } 12611 } 12612 12613 public boolean stopServiceToken(ComponentName className, IBinder token, 12614 int startId) { 12615 synchronized(this) { 12616 return mServices.stopServiceTokenLocked(className, token, startId); 12617 } 12618 } 12619 12620 public void setServiceForeground(ComponentName className, IBinder token, 12621 int id, Notification notification, boolean removeNotification) { 12622 synchronized(this) { 12623 mServices.setServiceForegroundLocked(className, token, id, notification, 12624 removeNotification); 12625 } 12626 } 12627 12628 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12629 boolean requireFull, String name, String callerPackage) { 12630 final int callingUserId = UserHandle.getUserId(callingUid); 12631 if (callingUserId != userId) { 12632 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12633 if ((requireFull || checkComponentPermission( 12634 android.Manifest.permission.INTERACT_ACROSS_USERS, 12635 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12636 && checkComponentPermission( 12637 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12638 callingPid, callingUid, -1, true) 12639 != PackageManager.PERMISSION_GRANTED) { 12640 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12641 // In this case, they would like to just execute as their 12642 // owner user instead of failing. 12643 userId = callingUserId; 12644 } else { 12645 StringBuilder builder = new StringBuilder(128); 12646 builder.append("Permission Denial: "); 12647 builder.append(name); 12648 if (callerPackage != null) { 12649 builder.append(" from "); 12650 builder.append(callerPackage); 12651 } 12652 builder.append(" asks to run as user "); 12653 builder.append(userId); 12654 builder.append(" but is calling from user "); 12655 builder.append(UserHandle.getUserId(callingUid)); 12656 builder.append("; this requires "); 12657 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12658 if (!requireFull) { 12659 builder.append(" or "); 12660 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12661 } 12662 String msg = builder.toString(); 12663 Slog.w(TAG, msg); 12664 throw new SecurityException(msg); 12665 } 12666 } 12667 } 12668 if (userId == UserHandle.USER_CURRENT 12669 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12670 // Note that we may be accessing this outside of a lock... 12671 // shouldn't be a big deal, if this is being called outside 12672 // of a locked context there is intrinsically a race with 12673 // the value the caller will receive and someone else changing it. 12674 userId = mCurrentUserId; 12675 } 12676 if (!allowAll && userId < 0) { 12677 throw new IllegalArgumentException( 12678 "Call does not support special user #" + userId); 12679 } 12680 } 12681 return userId; 12682 } 12683 12684 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12685 String className, int flags) { 12686 boolean result = false; 12687 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12688 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12689 if (ActivityManager.checkUidPermission( 12690 android.Manifest.permission.INTERACT_ACROSS_USERS, 12691 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12692 ComponentName comp = new ComponentName(aInfo.packageName, className); 12693 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12694 + " requests FLAG_SINGLE_USER, but app does not hold " 12695 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12696 Slog.w(TAG, msg); 12697 throw new SecurityException(msg); 12698 } 12699 result = true; 12700 } 12701 } else if (componentProcessName == aInfo.packageName) { 12702 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12703 } else if ("system".equals(componentProcessName)) { 12704 result = true; 12705 } 12706 if (DEBUG_MU) { 12707 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12708 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12709 } 12710 return result; 12711 } 12712 12713 public int bindService(IApplicationThread caller, IBinder token, 12714 Intent service, String resolvedType, 12715 IServiceConnection connection, int flags, int userId) { 12716 enforceNotIsolatedCaller("bindService"); 12717 // Refuse possible leaked file descriptors 12718 if (service != null && service.hasFileDescriptors() == true) { 12719 throw new IllegalArgumentException("File descriptors passed in Intent"); 12720 } 12721 12722 synchronized(this) { 12723 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12724 connection, flags, userId); 12725 } 12726 } 12727 12728 public boolean unbindService(IServiceConnection connection) { 12729 synchronized (this) { 12730 return mServices.unbindServiceLocked(connection); 12731 } 12732 } 12733 12734 public void publishService(IBinder token, Intent intent, IBinder service) { 12735 // Refuse possible leaked file descriptors 12736 if (intent != null && intent.hasFileDescriptors() == true) { 12737 throw new IllegalArgumentException("File descriptors passed in Intent"); 12738 } 12739 12740 synchronized(this) { 12741 if (!(token instanceof ServiceRecord)) { 12742 throw new IllegalArgumentException("Invalid service token"); 12743 } 12744 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12745 } 12746 } 12747 12748 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12749 // Refuse possible leaked file descriptors 12750 if (intent != null && intent.hasFileDescriptors() == true) { 12751 throw new IllegalArgumentException("File descriptors passed in Intent"); 12752 } 12753 12754 synchronized(this) { 12755 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12756 } 12757 } 12758 12759 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12760 synchronized(this) { 12761 if (!(token instanceof ServiceRecord)) { 12762 throw new IllegalArgumentException("Invalid service token"); 12763 } 12764 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12765 } 12766 } 12767 12768 // ========================================================= 12769 // BACKUP AND RESTORE 12770 // ========================================================= 12771 12772 // Cause the target app to be launched if necessary and its backup agent 12773 // instantiated. The backup agent will invoke backupAgentCreated() on the 12774 // activity manager to announce its creation. 12775 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12776 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12777 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12778 12779 synchronized(this) { 12780 // !!! TODO: currently no check here that we're already bound 12781 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12782 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12783 synchronized (stats) { 12784 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12785 } 12786 12787 // Backup agent is now in use, its package can't be stopped. 12788 try { 12789 AppGlobals.getPackageManager().setPackageStoppedState( 12790 app.packageName, false, UserHandle.getUserId(app.uid)); 12791 } catch (RemoteException e) { 12792 } catch (IllegalArgumentException e) { 12793 Slog.w(TAG, "Failed trying to unstop package " 12794 + app.packageName + ": " + e); 12795 } 12796 12797 BackupRecord r = new BackupRecord(ss, app, backupMode); 12798 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12799 ? new ComponentName(app.packageName, app.backupAgentName) 12800 : new ComponentName("android", "FullBackupAgent"); 12801 // startProcessLocked() returns existing proc's record if it's already running 12802 ProcessRecord proc = startProcessLocked(app.processName, app, 12803 false, 0, "backup", hostingName, false, false, false); 12804 if (proc == null) { 12805 Slog.e(TAG, "Unable to start backup agent process " + r); 12806 return false; 12807 } 12808 12809 r.app = proc; 12810 mBackupTarget = r; 12811 mBackupAppName = app.packageName; 12812 12813 // Try not to kill the process during backup 12814 updateOomAdjLocked(proc); 12815 12816 // If the process is already attached, schedule the creation of the backup agent now. 12817 // If it is not yet live, this will be done when it attaches to the framework. 12818 if (proc.thread != null) { 12819 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12820 try { 12821 proc.thread.scheduleCreateBackupAgent(app, 12822 compatibilityInfoForPackageLocked(app), backupMode); 12823 } catch (RemoteException e) { 12824 // Will time out on the backup manager side 12825 } 12826 } else { 12827 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12828 } 12829 // Invariants: at this point, the target app process exists and the application 12830 // is either already running or in the process of coming up. mBackupTarget and 12831 // mBackupAppName describe the app, so that when it binds back to the AM we 12832 // know that it's scheduled for a backup-agent operation. 12833 } 12834 12835 return true; 12836 } 12837 12838 @Override 12839 public void clearPendingBackup() { 12840 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 12841 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 12842 12843 synchronized (this) { 12844 mBackupTarget = null; 12845 mBackupAppName = null; 12846 } 12847 } 12848 12849 // A backup agent has just come up 12850 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12851 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12852 + " = " + agent); 12853 12854 synchronized(this) { 12855 if (!agentPackageName.equals(mBackupAppName)) { 12856 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12857 return; 12858 } 12859 } 12860 12861 long oldIdent = Binder.clearCallingIdentity(); 12862 try { 12863 IBackupManager bm = IBackupManager.Stub.asInterface( 12864 ServiceManager.getService(Context.BACKUP_SERVICE)); 12865 bm.agentConnected(agentPackageName, agent); 12866 } catch (RemoteException e) { 12867 // can't happen; the backup manager service is local 12868 } catch (Exception e) { 12869 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12870 e.printStackTrace(); 12871 } finally { 12872 Binder.restoreCallingIdentity(oldIdent); 12873 } 12874 } 12875 12876 // done with this agent 12877 public void unbindBackupAgent(ApplicationInfo appInfo) { 12878 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12879 if (appInfo == null) { 12880 Slog.w(TAG, "unbind backup agent for null app"); 12881 return; 12882 } 12883 12884 synchronized(this) { 12885 try { 12886 if (mBackupAppName == null) { 12887 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12888 return; 12889 } 12890 12891 if (!mBackupAppName.equals(appInfo.packageName)) { 12892 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12893 return; 12894 } 12895 12896 // Not backing this app up any more; reset its OOM adjustment 12897 final ProcessRecord proc = mBackupTarget.app; 12898 updateOomAdjLocked(proc); 12899 12900 // If the app crashed during backup, 'thread' will be null here 12901 if (proc.thread != null) { 12902 try { 12903 proc.thread.scheduleDestroyBackupAgent(appInfo, 12904 compatibilityInfoForPackageLocked(appInfo)); 12905 } catch (Exception e) { 12906 Slog.e(TAG, "Exception when unbinding backup agent:"); 12907 e.printStackTrace(); 12908 } 12909 } 12910 } finally { 12911 mBackupTarget = null; 12912 mBackupAppName = null; 12913 } 12914 } 12915 } 12916 // ========================================================= 12917 // BROADCASTS 12918 // ========================================================= 12919 12920 private final List getStickiesLocked(String action, IntentFilter filter, 12921 List cur, int userId) { 12922 final ContentResolver resolver = mContext.getContentResolver(); 12923 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12924 if (stickies == null) { 12925 return cur; 12926 } 12927 final ArrayList<Intent> list = stickies.get(action); 12928 if (list == null) { 12929 return cur; 12930 } 12931 int N = list.size(); 12932 for (int i=0; i<N; i++) { 12933 Intent intent = list.get(i); 12934 if (filter.match(resolver, intent, true, TAG) >= 0) { 12935 if (cur == null) { 12936 cur = new ArrayList<Intent>(); 12937 } 12938 cur.add(intent); 12939 } 12940 } 12941 return cur; 12942 } 12943 12944 boolean isPendingBroadcastProcessLocked(int pid) { 12945 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12946 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12947 } 12948 12949 void skipPendingBroadcastLocked(int pid) { 12950 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 12951 for (BroadcastQueue queue : mBroadcastQueues) { 12952 queue.skipPendingBroadcastLocked(pid); 12953 } 12954 } 12955 12956 // The app just attached; send any pending broadcasts that it should receive 12957 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 12958 boolean didSomething = false; 12959 for (BroadcastQueue queue : mBroadcastQueues) { 12960 didSomething |= queue.sendPendingBroadcastsLocked(app); 12961 } 12962 return didSomething; 12963 } 12964 12965 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 12966 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 12967 enforceNotIsolatedCaller("registerReceiver"); 12968 int callingUid; 12969 int callingPid; 12970 synchronized(this) { 12971 ProcessRecord callerApp = null; 12972 if (caller != null) { 12973 callerApp = getRecordForAppLocked(caller); 12974 if (callerApp == null) { 12975 throw new SecurityException( 12976 "Unable to find app for caller " + caller 12977 + " (pid=" + Binder.getCallingPid() 12978 + ") when registering receiver " + receiver); 12979 } 12980 if (callerApp.info.uid != Process.SYSTEM_UID && 12981 !callerApp.pkgList.containsKey(callerPackage) && 12982 !"android".equals(callerPackage)) { 12983 throw new SecurityException("Given caller package " + callerPackage 12984 + " is not running in process " + callerApp); 12985 } 12986 callingUid = callerApp.info.uid; 12987 callingPid = callerApp.pid; 12988 } else { 12989 callerPackage = null; 12990 callingUid = Binder.getCallingUid(); 12991 callingPid = Binder.getCallingPid(); 12992 } 12993 12994 userId = this.handleIncomingUser(callingPid, callingUid, userId, 12995 true, true, "registerReceiver", callerPackage); 12996 12997 List allSticky = null; 12998 12999 // Look for any matching sticky broadcasts... 13000 Iterator actions = filter.actionsIterator(); 13001 if (actions != null) { 13002 while (actions.hasNext()) { 13003 String action = (String)actions.next(); 13004 allSticky = getStickiesLocked(action, filter, allSticky, 13005 UserHandle.USER_ALL); 13006 allSticky = getStickiesLocked(action, filter, allSticky, 13007 UserHandle.getUserId(callingUid)); 13008 } 13009 } else { 13010 allSticky = getStickiesLocked(null, filter, allSticky, 13011 UserHandle.USER_ALL); 13012 allSticky = getStickiesLocked(null, filter, allSticky, 13013 UserHandle.getUserId(callingUid)); 13014 } 13015 13016 // The first sticky in the list is returned directly back to 13017 // the client. 13018 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13019 13020 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13021 + ": " + sticky); 13022 13023 if (receiver == null) { 13024 return sticky; 13025 } 13026 13027 ReceiverList rl 13028 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13029 if (rl == null) { 13030 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13031 userId, receiver); 13032 if (rl.app != null) { 13033 rl.app.receivers.add(rl); 13034 } else { 13035 try { 13036 receiver.asBinder().linkToDeath(rl, 0); 13037 } catch (RemoteException e) { 13038 return sticky; 13039 } 13040 rl.linkedToDeath = true; 13041 } 13042 mRegisteredReceivers.put(receiver.asBinder(), rl); 13043 } else if (rl.uid != callingUid) { 13044 throw new IllegalArgumentException( 13045 "Receiver requested to register for uid " + callingUid 13046 + " was previously registered for uid " + rl.uid); 13047 } else if (rl.pid != callingPid) { 13048 throw new IllegalArgumentException( 13049 "Receiver requested to register for pid " + callingPid 13050 + " was previously registered for pid " + rl.pid); 13051 } else if (rl.userId != userId) { 13052 throw new IllegalArgumentException( 13053 "Receiver requested to register for user " + userId 13054 + " was previously registered for user " + rl.userId); 13055 } 13056 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13057 permission, callingUid, userId); 13058 rl.add(bf); 13059 if (!bf.debugCheck()) { 13060 Slog.w(TAG, "==> For Dynamic broadast"); 13061 } 13062 mReceiverResolver.addFilter(bf); 13063 13064 // Enqueue broadcasts for all existing stickies that match 13065 // this filter. 13066 if (allSticky != null) { 13067 ArrayList receivers = new ArrayList(); 13068 receivers.add(bf); 13069 13070 int N = allSticky.size(); 13071 for (int i=0; i<N; i++) { 13072 Intent intent = (Intent)allSticky.get(i); 13073 BroadcastQueue queue = broadcastQueueForIntent(intent); 13074 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13075 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13076 null, null, false, true, true, -1); 13077 queue.enqueueParallelBroadcastLocked(r); 13078 queue.scheduleBroadcastsLocked(); 13079 } 13080 } 13081 13082 return sticky; 13083 } 13084 } 13085 13086 public void unregisterReceiver(IIntentReceiver receiver) { 13087 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13088 13089 final long origId = Binder.clearCallingIdentity(); 13090 try { 13091 boolean doTrim = false; 13092 13093 synchronized(this) { 13094 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13095 if (rl != null) { 13096 if (rl.curBroadcast != null) { 13097 BroadcastRecord r = rl.curBroadcast; 13098 final boolean doNext = finishReceiverLocked( 13099 receiver.asBinder(), r.resultCode, r.resultData, 13100 r.resultExtras, r.resultAbort); 13101 if (doNext) { 13102 doTrim = true; 13103 r.queue.processNextBroadcast(false); 13104 } 13105 } 13106 13107 if (rl.app != null) { 13108 rl.app.receivers.remove(rl); 13109 } 13110 removeReceiverLocked(rl); 13111 if (rl.linkedToDeath) { 13112 rl.linkedToDeath = false; 13113 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13114 } 13115 } 13116 } 13117 13118 // If we actually concluded any broadcasts, we might now be able 13119 // to trim the recipients' apps from our working set 13120 if (doTrim) { 13121 trimApplications(); 13122 return; 13123 } 13124 13125 } finally { 13126 Binder.restoreCallingIdentity(origId); 13127 } 13128 } 13129 13130 void removeReceiverLocked(ReceiverList rl) { 13131 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13132 int N = rl.size(); 13133 for (int i=0; i<N; i++) { 13134 mReceiverResolver.removeFilter(rl.get(i)); 13135 } 13136 } 13137 13138 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13139 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13140 ProcessRecord r = mLruProcesses.get(i); 13141 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13142 try { 13143 r.thread.dispatchPackageBroadcast(cmd, packages); 13144 } catch (RemoteException ex) { 13145 } 13146 } 13147 } 13148 } 13149 13150 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13151 int[] users) { 13152 List<ResolveInfo> receivers = null; 13153 try { 13154 HashSet<ComponentName> singleUserReceivers = null; 13155 boolean scannedFirstReceivers = false; 13156 for (int user : users) { 13157 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13158 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13159 if (user != 0 && newReceivers != null) { 13160 // If this is not the primary user, we need to check for 13161 // any receivers that should be filtered out. 13162 for (int i=0; i<newReceivers.size(); i++) { 13163 ResolveInfo ri = newReceivers.get(i); 13164 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13165 newReceivers.remove(i); 13166 i--; 13167 } 13168 } 13169 } 13170 if (newReceivers != null && newReceivers.size() == 0) { 13171 newReceivers = null; 13172 } 13173 if (receivers == null) { 13174 receivers = newReceivers; 13175 } else if (newReceivers != null) { 13176 // We need to concatenate the additional receivers 13177 // found with what we have do far. This would be easy, 13178 // but we also need to de-dup any receivers that are 13179 // singleUser. 13180 if (!scannedFirstReceivers) { 13181 // Collect any single user receivers we had already retrieved. 13182 scannedFirstReceivers = true; 13183 for (int i=0; i<receivers.size(); i++) { 13184 ResolveInfo ri = receivers.get(i); 13185 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13186 ComponentName cn = new ComponentName( 13187 ri.activityInfo.packageName, ri.activityInfo.name); 13188 if (singleUserReceivers == null) { 13189 singleUserReceivers = new HashSet<ComponentName>(); 13190 } 13191 singleUserReceivers.add(cn); 13192 } 13193 } 13194 } 13195 // Add the new results to the existing results, tracking 13196 // and de-dupping single user receivers. 13197 for (int i=0; i<newReceivers.size(); i++) { 13198 ResolveInfo ri = newReceivers.get(i); 13199 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13200 ComponentName cn = new ComponentName( 13201 ri.activityInfo.packageName, ri.activityInfo.name); 13202 if (singleUserReceivers == null) { 13203 singleUserReceivers = new HashSet<ComponentName>(); 13204 } 13205 if (!singleUserReceivers.contains(cn)) { 13206 singleUserReceivers.add(cn); 13207 receivers.add(ri); 13208 } 13209 } else { 13210 receivers.add(ri); 13211 } 13212 } 13213 } 13214 } 13215 } catch (RemoteException ex) { 13216 // pm is in same process, this will never happen. 13217 } 13218 return receivers; 13219 } 13220 13221 private final int broadcastIntentLocked(ProcessRecord callerApp, 13222 String callerPackage, Intent intent, String resolvedType, 13223 IIntentReceiver resultTo, int resultCode, String resultData, 13224 Bundle map, String requiredPermission, int appOp, 13225 boolean ordered, boolean sticky, int callingPid, int callingUid, 13226 int userId) { 13227 intent = new Intent(intent); 13228 13229 // By default broadcasts do not go to stopped apps. 13230 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13231 13232 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13233 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13234 + " ordered=" + ordered + " userid=" + userId); 13235 if ((resultTo != null) && !ordered) { 13236 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13237 } 13238 13239 userId = handleIncomingUser(callingPid, callingUid, userId, 13240 true, false, "broadcast", callerPackage); 13241 13242 // Make sure that the user who is receiving this broadcast is started. 13243 // If not, we will just skip it. 13244 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13245 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13246 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13247 Slog.w(TAG, "Skipping broadcast of " + intent 13248 + ": user " + userId + " is stopped"); 13249 return ActivityManager.BROADCAST_SUCCESS; 13250 } 13251 } 13252 13253 /* 13254 * Prevent non-system code (defined here to be non-persistent 13255 * processes) from sending protected broadcasts. 13256 */ 13257 int callingAppId = UserHandle.getAppId(callingUid); 13258 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13259 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13260 callingUid == 0) { 13261 // Always okay. 13262 } else if (callerApp == null || !callerApp.persistent) { 13263 try { 13264 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13265 intent.getAction())) { 13266 String msg = "Permission Denial: not allowed to send broadcast " 13267 + intent.getAction() + " from pid=" 13268 + callingPid + ", uid=" + callingUid; 13269 Slog.w(TAG, msg); 13270 throw new SecurityException(msg); 13271 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13272 // Special case for compatibility: we don't want apps to send this, 13273 // but historically it has not been protected and apps may be using it 13274 // to poke their own app widget. So, instead of making it protected, 13275 // just limit it to the caller. 13276 if (callerApp == null) { 13277 String msg = "Permission Denial: not allowed to send broadcast " 13278 + intent.getAction() + " from unknown caller."; 13279 Slog.w(TAG, msg); 13280 throw new SecurityException(msg); 13281 } else if (intent.getComponent() != null) { 13282 // They are good enough to send to an explicit component... verify 13283 // it is being sent to the calling app. 13284 if (!intent.getComponent().getPackageName().equals( 13285 callerApp.info.packageName)) { 13286 String msg = "Permission Denial: not allowed to send broadcast " 13287 + intent.getAction() + " to " 13288 + intent.getComponent().getPackageName() + " from " 13289 + callerApp.info.packageName; 13290 Slog.w(TAG, msg); 13291 throw new SecurityException(msg); 13292 } 13293 } else { 13294 // Limit broadcast to their own package. 13295 intent.setPackage(callerApp.info.packageName); 13296 } 13297 } 13298 } catch (RemoteException e) { 13299 Slog.w(TAG, "Remote exception", e); 13300 return ActivityManager.BROADCAST_SUCCESS; 13301 } 13302 } 13303 13304 // Handle special intents: if this broadcast is from the package 13305 // manager about a package being removed, we need to remove all of 13306 // its activities from the history stack. 13307 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13308 intent.getAction()); 13309 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13310 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13311 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13312 || uidRemoved) { 13313 if (checkComponentPermission( 13314 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13315 callingPid, callingUid, -1, true) 13316 == PackageManager.PERMISSION_GRANTED) { 13317 if (uidRemoved) { 13318 final Bundle intentExtras = intent.getExtras(); 13319 final int uid = intentExtras != null 13320 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13321 if (uid >= 0) { 13322 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13323 synchronized (bs) { 13324 bs.removeUidStatsLocked(uid); 13325 } 13326 mAppOpsService.uidRemoved(uid); 13327 } 13328 } else { 13329 // If resources are unavailable just force stop all 13330 // those packages and flush the attribute cache as well. 13331 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13332 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13333 if (list != null && (list.length > 0)) { 13334 for (String pkg : list) { 13335 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13336 "storage unmount"); 13337 } 13338 sendPackageBroadcastLocked( 13339 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13340 } 13341 } else { 13342 Uri data = intent.getData(); 13343 String ssp; 13344 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13345 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13346 intent.getAction()); 13347 boolean fullUninstall = removed && 13348 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13349 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13350 forceStopPackageLocked(ssp, UserHandle.getAppId( 13351 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13352 false, fullUninstall, userId, 13353 removed ? "pkg removed" : "pkg changed"); 13354 } 13355 if (removed) { 13356 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13357 new String[] {ssp}, userId); 13358 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13359 mAppOpsService.packageRemoved( 13360 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13361 13362 // Remove all permissions granted from/to this package 13363 removeUriPermissionsForPackageLocked(ssp, userId, true); 13364 } 13365 } 13366 } 13367 } 13368 } 13369 } else { 13370 String msg = "Permission Denial: " + intent.getAction() 13371 + " broadcast from " + callerPackage + " (pid=" + callingPid 13372 + ", uid=" + callingUid + ")" 13373 + " requires " 13374 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13375 Slog.w(TAG, msg); 13376 throw new SecurityException(msg); 13377 } 13378 13379 // Special case for adding a package: by default turn on compatibility 13380 // mode. 13381 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13382 Uri data = intent.getData(); 13383 String ssp; 13384 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13385 mCompatModePackages.handlePackageAddedLocked(ssp, 13386 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13387 } 13388 } 13389 13390 /* 13391 * If this is the time zone changed action, queue up a message that will reset the timezone 13392 * of all currently running processes. This message will get queued up before the broadcast 13393 * happens. 13394 */ 13395 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13396 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13397 } 13398 13399 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13400 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13401 } 13402 13403 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13404 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13405 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13406 } 13407 13408 // Add to the sticky list if requested. 13409 if (sticky) { 13410 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13411 callingPid, callingUid) 13412 != PackageManager.PERMISSION_GRANTED) { 13413 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13414 + callingPid + ", uid=" + callingUid 13415 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13416 Slog.w(TAG, msg); 13417 throw new SecurityException(msg); 13418 } 13419 if (requiredPermission != null) { 13420 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13421 + " and enforce permission " + requiredPermission); 13422 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13423 } 13424 if (intent.getComponent() != null) { 13425 throw new SecurityException( 13426 "Sticky broadcasts can't target a specific component"); 13427 } 13428 // We use userId directly here, since the "all" target is maintained 13429 // as a separate set of sticky broadcasts. 13430 if (userId != UserHandle.USER_ALL) { 13431 // But first, if this is not a broadcast to all users, then 13432 // make sure it doesn't conflict with an existing broadcast to 13433 // all users. 13434 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13435 UserHandle.USER_ALL); 13436 if (stickies != null) { 13437 ArrayList<Intent> list = stickies.get(intent.getAction()); 13438 if (list != null) { 13439 int N = list.size(); 13440 int i; 13441 for (i=0; i<N; i++) { 13442 if (intent.filterEquals(list.get(i))) { 13443 throw new IllegalArgumentException( 13444 "Sticky broadcast " + intent + " for user " 13445 + userId + " conflicts with existing global broadcast"); 13446 } 13447 } 13448 } 13449 } 13450 } 13451 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13452 if (stickies == null) { 13453 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13454 mStickyBroadcasts.put(userId, stickies); 13455 } 13456 ArrayList<Intent> list = stickies.get(intent.getAction()); 13457 if (list == null) { 13458 list = new ArrayList<Intent>(); 13459 stickies.put(intent.getAction(), list); 13460 } 13461 int N = list.size(); 13462 int i; 13463 for (i=0; i<N; i++) { 13464 if (intent.filterEquals(list.get(i))) { 13465 // This sticky already exists, replace it. 13466 list.set(i, new Intent(intent)); 13467 break; 13468 } 13469 } 13470 if (i >= N) { 13471 list.add(new Intent(intent)); 13472 } 13473 } 13474 13475 int[] users; 13476 if (userId == UserHandle.USER_ALL) { 13477 // Caller wants broadcast to go to all started users. 13478 users = mStartedUserArray; 13479 } else { 13480 // Caller wants broadcast to go to one specific user. 13481 users = new int[] {userId}; 13482 } 13483 13484 // Figure out who all will receive this broadcast. 13485 List receivers = null; 13486 List<BroadcastFilter> registeredReceivers = null; 13487 // Need to resolve the intent to interested receivers... 13488 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13489 == 0) { 13490 receivers = collectReceiverComponents(intent, resolvedType, users); 13491 } 13492 if (intent.getComponent() == null) { 13493 registeredReceivers = mReceiverResolver.queryIntent(intent, 13494 resolvedType, false, userId); 13495 } 13496 13497 final boolean replacePending = 13498 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13499 13500 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13501 + " replacePending=" + replacePending); 13502 13503 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13504 if (!ordered && NR > 0) { 13505 // If we are not serializing this broadcast, then send the 13506 // registered receivers separately so they don't wait for the 13507 // components to be launched. 13508 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13509 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13510 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13511 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13512 ordered, sticky, false, userId); 13513 if (DEBUG_BROADCAST) Slog.v( 13514 TAG, "Enqueueing parallel broadcast " + r); 13515 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13516 if (!replaced) { 13517 queue.enqueueParallelBroadcastLocked(r); 13518 queue.scheduleBroadcastsLocked(); 13519 } 13520 registeredReceivers = null; 13521 NR = 0; 13522 } 13523 13524 // Merge into one list. 13525 int ir = 0; 13526 if (receivers != null) { 13527 // A special case for PACKAGE_ADDED: do not allow the package 13528 // being added to see this broadcast. This prevents them from 13529 // using this as a back door to get run as soon as they are 13530 // installed. Maybe in the future we want to have a special install 13531 // broadcast or such for apps, but we'd like to deliberately make 13532 // this decision. 13533 String skipPackages[] = null; 13534 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13535 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13536 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13537 Uri data = intent.getData(); 13538 if (data != null) { 13539 String pkgName = data.getSchemeSpecificPart(); 13540 if (pkgName != null) { 13541 skipPackages = new String[] { pkgName }; 13542 } 13543 } 13544 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13545 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13546 } 13547 if (skipPackages != null && (skipPackages.length > 0)) { 13548 for (String skipPackage : skipPackages) { 13549 if (skipPackage != null) { 13550 int NT = receivers.size(); 13551 for (int it=0; it<NT; it++) { 13552 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13553 if (curt.activityInfo.packageName.equals(skipPackage)) { 13554 receivers.remove(it); 13555 it--; 13556 NT--; 13557 } 13558 } 13559 } 13560 } 13561 } 13562 13563 int NT = receivers != null ? receivers.size() : 0; 13564 int it = 0; 13565 ResolveInfo curt = null; 13566 BroadcastFilter curr = null; 13567 while (it < NT && ir < NR) { 13568 if (curt == null) { 13569 curt = (ResolveInfo)receivers.get(it); 13570 } 13571 if (curr == null) { 13572 curr = registeredReceivers.get(ir); 13573 } 13574 if (curr.getPriority() >= curt.priority) { 13575 // Insert this broadcast record into the final list. 13576 receivers.add(it, curr); 13577 ir++; 13578 curr = null; 13579 it++; 13580 NT++; 13581 } else { 13582 // Skip to the next ResolveInfo in the final list. 13583 it++; 13584 curt = null; 13585 } 13586 } 13587 } 13588 while (ir < NR) { 13589 if (receivers == null) { 13590 receivers = new ArrayList(); 13591 } 13592 receivers.add(registeredReceivers.get(ir)); 13593 ir++; 13594 } 13595 13596 if ((receivers != null && receivers.size() > 0) 13597 || resultTo != null) { 13598 BroadcastQueue queue = broadcastQueueForIntent(intent); 13599 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13600 callerPackage, callingPid, callingUid, resolvedType, 13601 requiredPermission, appOp, receivers, resultTo, resultCode, 13602 resultData, map, ordered, sticky, false, userId); 13603 if (DEBUG_BROADCAST) Slog.v( 13604 TAG, "Enqueueing ordered broadcast " + r 13605 + ": prev had " + queue.mOrderedBroadcasts.size()); 13606 if (DEBUG_BROADCAST) { 13607 int seq = r.intent.getIntExtra("seq", -1); 13608 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13609 } 13610 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13611 if (!replaced) { 13612 queue.enqueueOrderedBroadcastLocked(r); 13613 queue.scheduleBroadcastsLocked(); 13614 } 13615 } 13616 13617 return ActivityManager.BROADCAST_SUCCESS; 13618 } 13619 13620 final Intent verifyBroadcastLocked(Intent intent) { 13621 // Refuse possible leaked file descriptors 13622 if (intent != null && intent.hasFileDescriptors() == true) { 13623 throw new IllegalArgumentException("File descriptors passed in Intent"); 13624 } 13625 13626 int flags = intent.getFlags(); 13627 13628 if (!mProcessesReady) { 13629 // if the caller really truly claims to know what they're doing, go 13630 // ahead and allow the broadcast without launching any receivers 13631 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13632 intent = new Intent(intent); 13633 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13634 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13635 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13636 + " before boot completion"); 13637 throw new IllegalStateException("Cannot broadcast before boot completed"); 13638 } 13639 } 13640 13641 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13642 throw new IllegalArgumentException( 13643 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13644 } 13645 13646 return intent; 13647 } 13648 13649 public final int broadcastIntent(IApplicationThread caller, 13650 Intent intent, String resolvedType, IIntentReceiver resultTo, 13651 int resultCode, String resultData, Bundle map, 13652 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13653 enforceNotIsolatedCaller("broadcastIntent"); 13654 synchronized(this) { 13655 intent = verifyBroadcastLocked(intent); 13656 13657 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13658 final int callingPid = Binder.getCallingPid(); 13659 final int callingUid = Binder.getCallingUid(); 13660 final long origId = Binder.clearCallingIdentity(); 13661 int res = broadcastIntentLocked(callerApp, 13662 callerApp != null ? callerApp.info.packageName : null, 13663 intent, resolvedType, resultTo, 13664 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13665 callingPid, callingUid, userId); 13666 Binder.restoreCallingIdentity(origId); 13667 return res; 13668 } 13669 } 13670 13671 int broadcastIntentInPackage(String packageName, int uid, 13672 Intent intent, String resolvedType, IIntentReceiver resultTo, 13673 int resultCode, String resultData, Bundle map, 13674 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13675 synchronized(this) { 13676 intent = verifyBroadcastLocked(intent); 13677 13678 final long origId = Binder.clearCallingIdentity(); 13679 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13680 resultTo, resultCode, resultData, map, requiredPermission, 13681 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13682 Binder.restoreCallingIdentity(origId); 13683 return res; 13684 } 13685 } 13686 13687 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13688 // Refuse possible leaked file descriptors 13689 if (intent != null && intent.hasFileDescriptors() == true) { 13690 throw new IllegalArgumentException("File descriptors passed in Intent"); 13691 } 13692 13693 userId = handleIncomingUser(Binder.getCallingPid(), 13694 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13695 13696 synchronized(this) { 13697 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13698 != PackageManager.PERMISSION_GRANTED) { 13699 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13700 + Binder.getCallingPid() 13701 + ", uid=" + Binder.getCallingUid() 13702 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13703 Slog.w(TAG, msg); 13704 throw new SecurityException(msg); 13705 } 13706 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13707 if (stickies != null) { 13708 ArrayList<Intent> list = stickies.get(intent.getAction()); 13709 if (list != null) { 13710 int N = list.size(); 13711 int i; 13712 for (i=0; i<N; i++) { 13713 if (intent.filterEquals(list.get(i))) { 13714 list.remove(i); 13715 break; 13716 } 13717 } 13718 if (list.size() <= 0) { 13719 stickies.remove(intent.getAction()); 13720 } 13721 } 13722 if (stickies.size() <= 0) { 13723 mStickyBroadcasts.remove(userId); 13724 } 13725 } 13726 } 13727 } 13728 13729 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13730 String resultData, Bundle resultExtras, boolean resultAbort) { 13731 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13732 if (r == null) { 13733 Slog.w(TAG, "finishReceiver called but not found on queue"); 13734 return false; 13735 } 13736 13737 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13738 } 13739 13740 void backgroundServicesFinishedLocked(int userId) { 13741 for (BroadcastQueue queue : mBroadcastQueues) { 13742 queue.backgroundServicesFinishedLocked(userId); 13743 } 13744 } 13745 13746 public void finishReceiver(IBinder who, int resultCode, String resultData, 13747 Bundle resultExtras, boolean resultAbort) { 13748 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13749 13750 // Refuse possible leaked file descriptors 13751 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13752 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13753 } 13754 13755 final long origId = Binder.clearCallingIdentity(); 13756 try { 13757 boolean doNext = false; 13758 BroadcastRecord r; 13759 13760 synchronized(this) { 13761 r = broadcastRecordForReceiverLocked(who); 13762 if (r != null) { 13763 doNext = r.queue.finishReceiverLocked(r, resultCode, 13764 resultData, resultExtras, resultAbort, true); 13765 } 13766 } 13767 13768 if (doNext) { 13769 r.queue.processNextBroadcast(false); 13770 } 13771 trimApplications(); 13772 } finally { 13773 Binder.restoreCallingIdentity(origId); 13774 } 13775 } 13776 13777 // ========================================================= 13778 // INSTRUMENTATION 13779 // ========================================================= 13780 13781 public boolean startInstrumentation(ComponentName className, 13782 String profileFile, int flags, Bundle arguments, 13783 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13784 int userId) { 13785 enforceNotIsolatedCaller("startInstrumentation"); 13786 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13787 userId, false, true, "startInstrumentation", null); 13788 // Refuse possible leaked file descriptors 13789 if (arguments != null && arguments.hasFileDescriptors()) { 13790 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13791 } 13792 13793 synchronized(this) { 13794 InstrumentationInfo ii = null; 13795 ApplicationInfo ai = null; 13796 try { 13797 ii = mContext.getPackageManager().getInstrumentationInfo( 13798 className, STOCK_PM_FLAGS); 13799 ai = AppGlobals.getPackageManager().getApplicationInfo( 13800 ii.targetPackage, STOCK_PM_FLAGS, userId); 13801 } catch (PackageManager.NameNotFoundException e) { 13802 } catch (RemoteException e) { 13803 } 13804 if (ii == null) { 13805 reportStartInstrumentationFailure(watcher, className, 13806 "Unable to find instrumentation info for: " + className); 13807 return false; 13808 } 13809 if (ai == null) { 13810 reportStartInstrumentationFailure(watcher, className, 13811 "Unable to find instrumentation target package: " + ii.targetPackage); 13812 return false; 13813 } 13814 13815 int match = mContext.getPackageManager().checkSignatures( 13816 ii.targetPackage, ii.packageName); 13817 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13818 String msg = "Permission Denial: starting instrumentation " 13819 + className + " from pid=" 13820 + Binder.getCallingPid() 13821 + ", uid=" + Binder.getCallingPid() 13822 + " not allowed because package " + ii.packageName 13823 + " does not have a signature matching the target " 13824 + ii.targetPackage; 13825 reportStartInstrumentationFailure(watcher, className, msg); 13826 throw new SecurityException(msg); 13827 } 13828 13829 final long origId = Binder.clearCallingIdentity(); 13830 // Instrumentation can kill and relaunch even persistent processes 13831 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 13832 "start instr"); 13833 ProcessRecord app = addAppLocked(ai, false); 13834 app.instrumentationClass = className; 13835 app.instrumentationInfo = ai; 13836 app.instrumentationProfileFile = profileFile; 13837 app.instrumentationArguments = arguments; 13838 app.instrumentationWatcher = watcher; 13839 app.instrumentationUiAutomationConnection = uiAutomationConnection; 13840 app.instrumentationResultClass = className; 13841 Binder.restoreCallingIdentity(origId); 13842 } 13843 13844 return true; 13845 } 13846 13847 /** 13848 * Report errors that occur while attempting to start Instrumentation. Always writes the 13849 * error to the logs, but if somebody is watching, send the report there too. This enables 13850 * the "am" command to report errors with more information. 13851 * 13852 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13853 * @param cn The component name of the instrumentation. 13854 * @param report The error report. 13855 */ 13856 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13857 ComponentName cn, String report) { 13858 Slog.w(TAG, report); 13859 try { 13860 if (watcher != null) { 13861 Bundle results = new Bundle(); 13862 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13863 results.putString("Error", report); 13864 watcher.instrumentationStatus(cn, -1, results); 13865 } 13866 } catch (RemoteException e) { 13867 Slog.w(TAG, e); 13868 } 13869 } 13870 13871 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13872 if (app.instrumentationWatcher != null) { 13873 try { 13874 // NOTE: IInstrumentationWatcher *must* be oneway here 13875 app.instrumentationWatcher.instrumentationFinished( 13876 app.instrumentationClass, 13877 resultCode, 13878 results); 13879 } catch (RemoteException e) { 13880 } 13881 } 13882 if (app.instrumentationUiAutomationConnection != null) { 13883 try { 13884 app.instrumentationUiAutomationConnection.shutdown(); 13885 } catch (RemoteException re) { 13886 /* ignore */ 13887 } 13888 // Only a UiAutomation can set this flag and now that 13889 // it is finished we make sure it is reset to its default. 13890 mUserIsMonkey = false; 13891 } 13892 app.instrumentationWatcher = null; 13893 app.instrumentationUiAutomationConnection = null; 13894 app.instrumentationClass = null; 13895 app.instrumentationInfo = null; 13896 app.instrumentationProfileFile = null; 13897 app.instrumentationArguments = null; 13898 13899 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 13900 "finished inst"); 13901 } 13902 13903 public void finishInstrumentation(IApplicationThread target, 13904 int resultCode, Bundle results) { 13905 int userId = UserHandle.getCallingUserId(); 13906 // Refuse possible leaked file descriptors 13907 if (results != null && results.hasFileDescriptors()) { 13908 throw new IllegalArgumentException("File descriptors passed in Intent"); 13909 } 13910 13911 synchronized(this) { 13912 ProcessRecord app = getRecordForAppLocked(target); 13913 if (app == null) { 13914 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13915 return; 13916 } 13917 final long origId = Binder.clearCallingIdentity(); 13918 finishInstrumentationLocked(app, resultCode, results); 13919 Binder.restoreCallingIdentity(origId); 13920 } 13921 } 13922 13923 // ========================================================= 13924 // CONFIGURATION 13925 // ========================================================= 13926 13927 public ConfigurationInfo getDeviceConfigurationInfo() { 13928 ConfigurationInfo config = new ConfigurationInfo(); 13929 synchronized (this) { 13930 config.reqTouchScreen = mConfiguration.touchscreen; 13931 config.reqKeyboardType = mConfiguration.keyboard; 13932 config.reqNavigation = mConfiguration.navigation; 13933 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13934 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13935 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13936 } 13937 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13938 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13939 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13940 } 13941 config.reqGlEsVersion = GL_ES_VERSION; 13942 } 13943 return config; 13944 } 13945 13946 ActivityStack getFocusedStack() { 13947 return mStackSupervisor.getFocusedStack(); 13948 } 13949 13950 public Configuration getConfiguration() { 13951 Configuration ci; 13952 synchronized(this) { 13953 ci = new Configuration(mConfiguration); 13954 } 13955 return ci; 13956 } 13957 13958 public void updatePersistentConfiguration(Configuration values) { 13959 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13960 "updateConfiguration()"); 13961 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 13962 "updateConfiguration()"); 13963 if (values == null) { 13964 throw new NullPointerException("Configuration must not be null"); 13965 } 13966 13967 synchronized(this) { 13968 final long origId = Binder.clearCallingIdentity(); 13969 updateConfigurationLocked(values, null, true, false); 13970 Binder.restoreCallingIdentity(origId); 13971 } 13972 } 13973 13974 public void updateConfiguration(Configuration values) { 13975 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13976 "updateConfiguration()"); 13977 13978 synchronized(this) { 13979 if (values == null && mWindowManager != null) { 13980 // sentinel: fetch the current configuration from the window manager 13981 values = mWindowManager.computeNewConfiguration(); 13982 } 13983 13984 if (mWindowManager != null) { 13985 mProcessList.applyDisplaySize(mWindowManager); 13986 } 13987 13988 final long origId = Binder.clearCallingIdentity(); 13989 if (values != null) { 13990 Settings.System.clearConfiguration(values); 13991 } 13992 updateConfigurationLocked(values, null, false, false); 13993 Binder.restoreCallingIdentity(origId); 13994 } 13995 } 13996 13997 /** 13998 * Do either or both things: (1) change the current configuration, and (2) 13999 * make sure the given activity is running with the (now) current 14000 * configuration. Returns true if the activity has been left running, or 14001 * false if <var>starting</var> is being destroyed to match the new 14002 * configuration. 14003 * @param persistent TODO 14004 */ 14005 boolean updateConfigurationLocked(Configuration values, 14006 ActivityRecord starting, boolean persistent, boolean initLocale) { 14007 int changes = 0; 14008 14009 if (values != null) { 14010 Configuration newConfig = new Configuration(mConfiguration); 14011 changes = newConfig.updateFrom(values); 14012 if (changes != 0) { 14013 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14014 Slog.i(TAG, "Updating configuration to: " + values); 14015 } 14016 14017 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14018 14019 if (values.locale != null && !initLocale) { 14020 saveLocaleLocked(values.locale, 14021 !values.locale.equals(mConfiguration.locale), 14022 values.userSetLocale); 14023 } 14024 14025 mConfigurationSeq++; 14026 if (mConfigurationSeq <= 0) { 14027 mConfigurationSeq = 1; 14028 } 14029 newConfig.seq = mConfigurationSeq; 14030 mConfiguration = newConfig; 14031 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14032 14033 final Configuration configCopy = new Configuration(mConfiguration); 14034 14035 // TODO: If our config changes, should we auto dismiss any currently 14036 // showing dialogs? 14037 mShowDialogs = shouldShowDialogs(newConfig); 14038 14039 AttributeCache ac = AttributeCache.instance(); 14040 if (ac != null) { 14041 ac.updateConfiguration(configCopy); 14042 } 14043 14044 // Make sure all resources in our process are updated 14045 // right now, so that anyone who is going to retrieve 14046 // resource values after we return will be sure to get 14047 // the new ones. This is especially important during 14048 // boot, where the first config change needs to guarantee 14049 // all resources have that config before following boot 14050 // code is executed. 14051 mSystemThread.applyConfigurationToResources(configCopy); 14052 14053 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14054 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14055 msg.obj = new Configuration(configCopy); 14056 mHandler.sendMessage(msg); 14057 } 14058 14059 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14060 ProcessRecord app = mLruProcesses.get(i); 14061 try { 14062 if (app.thread != null) { 14063 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14064 + app.processName + " new config " + mConfiguration); 14065 app.thread.scheduleConfigurationChanged(configCopy); 14066 } 14067 } catch (Exception e) { 14068 } 14069 } 14070 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14071 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14072 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14073 | Intent.FLAG_RECEIVER_FOREGROUND); 14074 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14075 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14076 Process.SYSTEM_UID, UserHandle.USER_ALL); 14077 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14078 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14079 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14080 broadcastIntentLocked(null, null, intent, 14081 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14082 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14083 } 14084 } 14085 } 14086 14087 boolean kept = true; 14088 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14089 // mainStack is null during startup. 14090 if (mainStack != null) { 14091 if (changes != 0 && starting == null) { 14092 // If the configuration changed, and the caller is not already 14093 // in the process of starting an activity, then find the top 14094 // activity to check if its configuration needs to change. 14095 starting = mainStack.topRunningActivityLocked(null); 14096 } 14097 14098 if (starting != null) { 14099 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14100 // And we need to make sure at this point that all other activities 14101 // are made visible with the correct configuration. 14102 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14103 } 14104 } 14105 14106 if (values != null && mWindowManager != null) { 14107 mWindowManager.setNewConfiguration(mConfiguration); 14108 } 14109 14110 return kept; 14111 } 14112 14113 /** 14114 * Decide based on the configuration whether we should shouw the ANR, 14115 * crash, etc dialogs. The idea is that if there is no affordnace to 14116 * press the on-screen buttons, we shouldn't show the dialog. 14117 * 14118 * A thought: SystemUI might also want to get told about this, the Power 14119 * dialog / global actions also might want different behaviors. 14120 */ 14121 private static final boolean shouldShowDialogs(Configuration config) { 14122 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14123 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14124 } 14125 14126 /** 14127 * Save the locale. You must be inside a synchronized (this) block. 14128 */ 14129 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14130 if(isDiff) { 14131 SystemProperties.set("user.language", l.getLanguage()); 14132 SystemProperties.set("user.region", l.getCountry()); 14133 } 14134 14135 if(isPersist) { 14136 SystemProperties.set("persist.sys.language", l.getLanguage()); 14137 SystemProperties.set("persist.sys.country", l.getCountry()); 14138 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14139 } 14140 } 14141 14142 @Override 14143 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14144 ActivityRecord srec = ActivityRecord.forToken(token); 14145 return srec != null && srec.task.affinity != null && 14146 srec.task.affinity.equals(destAffinity); 14147 } 14148 14149 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14150 Intent resultData) { 14151 14152 synchronized (this) { 14153 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14154 if (stack != null) { 14155 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14156 } 14157 return false; 14158 } 14159 } 14160 14161 public int getLaunchedFromUid(IBinder activityToken) { 14162 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14163 if (srec == null) { 14164 return -1; 14165 } 14166 return srec.launchedFromUid; 14167 } 14168 14169 public String getLaunchedFromPackage(IBinder activityToken) { 14170 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14171 if (srec == null) { 14172 return null; 14173 } 14174 return srec.launchedFromPackage; 14175 } 14176 14177 // ========================================================= 14178 // LIFETIME MANAGEMENT 14179 // ========================================================= 14180 14181 // Returns which broadcast queue the app is the current [or imminent] receiver 14182 // on, or 'null' if the app is not an active broadcast recipient. 14183 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14184 BroadcastRecord r = app.curReceiver; 14185 if (r != null) { 14186 return r.queue; 14187 } 14188 14189 // It's not the current receiver, but it might be starting up to become one 14190 synchronized (this) { 14191 for (BroadcastQueue queue : mBroadcastQueues) { 14192 r = queue.mPendingBroadcast; 14193 if (r != null && r.curApp == app) { 14194 // found it; report which queue it's in 14195 return queue; 14196 } 14197 } 14198 } 14199 14200 return null; 14201 } 14202 14203 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14204 boolean doingAll, long now) { 14205 if (mAdjSeq == app.adjSeq) { 14206 // This adjustment has already been computed. 14207 return app.curRawAdj; 14208 } 14209 14210 if (app.thread == null) { 14211 app.adjSeq = mAdjSeq; 14212 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14213 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14214 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14215 } 14216 14217 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14218 app.adjSource = null; 14219 app.adjTarget = null; 14220 app.empty = false; 14221 app.cached = false; 14222 14223 final int activitiesSize = app.activities.size(); 14224 14225 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14226 // The max adjustment doesn't allow this app to be anything 14227 // below foreground, so it is not worth doing work for it. 14228 app.adjType = "fixed"; 14229 app.adjSeq = mAdjSeq; 14230 app.curRawAdj = app.maxAdj; 14231 app.foregroundActivities = false; 14232 app.keeping = true; 14233 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14234 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14235 // System process can do UI, and when they do we want to have 14236 // them trim their memory after the user leaves the UI. To 14237 // facilitate this, here we need to determine whether or not it 14238 // is currently showing UI. 14239 app.systemNoUi = true; 14240 if (app == TOP_APP) { 14241 app.systemNoUi = false; 14242 } else if (activitiesSize > 0) { 14243 for (int j = 0; j < activitiesSize; j++) { 14244 final ActivityRecord r = app.activities.get(j); 14245 if (r.visible) { 14246 app.systemNoUi = false; 14247 } 14248 } 14249 } 14250 if (!app.systemNoUi) { 14251 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14252 } 14253 return (app.curAdj=app.maxAdj); 14254 } 14255 14256 app.keeping = false; 14257 app.systemNoUi = false; 14258 14259 // Determine the importance of the process, starting with most 14260 // important to least, and assign an appropriate OOM adjustment. 14261 int adj; 14262 int schedGroup; 14263 int procState; 14264 boolean foregroundActivities = false; 14265 boolean interesting = false; 14266 BroadcastQueue queue; 14267 if (app == TOP_APP) { 14268 // The last app on the list is the foreground app. 14269 adj = ProcessList.FOREGROUND_APP_ADJ; 14270 schedGroup = Process.THREAD_GROUP_DEFAULT; 14271 app.adjType = "top-activity"; 14272 foregroundActivities = true; 14273 interesting = true; 14274 procState = ActivityManager.PROCESS_STATE_TOP; 14275 } else if (app.instrumentationClass != null) { 14276 // Don't want to kill running instrumentation. 14277 adj = ProcessList.FOREGROUND_APP_ADJ; 14278 schedGroup = Process.THREAD_GROUP_DEFAULT; 14279 app.adjType = "instrumentation"; 14280 interesting = true; 14281 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14282 } else if ((queue = isReceivingBroadcast(app)) != null) { 14283 // An app that is currently receiving a broadcast also 14284 // counts as being in the foreground for OOM killer purposes. 14285 // It's placed in a sched group based on the nature of the 14286 // broadcast as reflected by which queue it's active in. 14287 adj = ProcessList.FOREGROUND_APP_ADJ; 14288 schedGroup = (queue == mFgBroadcastQueue) 14289 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14290 app.adjType = "broadcast"; 14291 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14292 } else if (app.executingServices.size() > 0) { 14293 // An app that is currently executing a service callback also 14294 // counts as being in the foreground. 14295 adj = ProcessList.FOREGROUND_APP_ADJ; 14296 schedGroup = app.execServicesFg ? 14297 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14298 app.adjType = "exec-service"; 14299 procState = ActivityManager.PROCESS_STATE_SERVICE; 14300 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14301 } else { 14302 // As far as we know the process is empty. We may change our mind later. 14303 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14304 // At this point we don't actually know the adjustment. Use the cached adj 14305 // value that the caller wants us to. 14306 adj = cachedAdj; 14307 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14308 app.cached = true; 14309 app.empty = true; 14310 app.adjType = "cch-empty"; 14311 } 14312 14313 // Examine all activities if not already foreground. 14314 if (!foregroundActivities && activitiesSize > 0) { 14315 for (int j = 0; j < activitiesSize; j++) { 14316 final ActivityRecord r = app.activities.get(j); 14317 if (r.app != app) { 14318 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14319 + app + "?!?"); 14320 continue; 14321 } 14322 if (r.visible) { 14323 // App has a visible activity; only upgrade adjustment. 14324 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14325 adj = ProcessList.VISIBLE_APP_ADJ; 14326 app.adjType = "visible"; 14327 } 14328 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14329 procState = ActivityManager.PROCESS_STATE_TOP; 14330 } 14331 schedGroup = Process.THREAD_GROUP_DEFAULT; 14332 app.cached = false; 14333 app.empty = false; 14334 foregroundActivities = true; 14335 break; 14336 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14337 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14338 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14339 app.adjType = "pausing"; 14340 } 14341 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14342 procState = ActivityManager.PROCESS_STATE_TOP; 14343 } 14344 schedGroup = Process.THREAD_GROUP_DEFAULT; 14345 app.cached = false; 14346 app.empty = false; 14347 foregroundActivities = true; 14348 } else if (r.state == ActivityState.STOPPING) { 14349 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14350 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14351 app.adjType = "stopping"; 14352 } 14353 // For the process state, we will at this point consider the 14354 // process to be cached. It will be cached either as an activity 14355 // or empty depending on whether the activity is finishing. We do 14356 // this so that we can treat the process as cached for purposes of 14357 // memory trimming (determing current memory level, trim command to 14358 // send to process) since there can be an arbitrary number of stopping 14359 // processes and they should soon all go into the cached state. 14360 if (!r.finishing) { 14361 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14362 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14363 } 14364 } 14365 app.cached = false; 14366 app.empty = false; 14367 foregroundActivities = true; 14368 } else { 14369 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14370 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14371 app.adjType = "cch-act"; 14372 } 14373 } 14374 } 14375 } 14376 14377 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14378 if (app.foregroundServices) { 14379 // The user is aware of this app, so make it visible. 14380 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14381 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14382 app.cached = false; 14383 app.adjType = "fg-service"; 14384 schedGroup = Process.THREAD_GROUP_DEFAULT; 14385 } else if (app.forcingToForeground != null) { 14386 // The user is aware of this app, so make it visible. 14387 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14388 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14389 app.cached = false; 14390 app.adjType = "force-fg"; 14391 app.adjSource = app.forcingToForeground; 14392 schedGroup = Process.THREAD_GROUP_DEFAULT; 14393 } 14394 } 14395 14396 if (app.foregroundServices) { 14397 interesting = true; 14398 } 14399 14400 if (app == mHeavyWeightProcess) { 14401 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14402 // We don't want to kill the current heavy-weight process. 14403 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14404 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14405 app.cached = false; 14406 app.adjType = "heavy"; 14407 } 14408 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14409 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14410 } 14411 } 14412 14413 if (app == mHomeProcess) { 14414 if (adj > ProcessList.HOME_APP_ADJ) { 14415 // This process is hosting what we currently consider to be the 14416 // home app, so we don't want to let it go into the background. 14417 adj = ProcessList.HOME_APP_ADJ; 14418 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14419 app.cached = false; 14420 app.adjType = "home"; 14421 } 14422 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14423 procState = ActivityManager.PROCESS_STATE_HOME; 14424 } 14425 } 14426 14427 if (app == mPreviousProcess && app.activities.size() > 0) { 14428 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14429 // This was the previous process that showed UI to the user. 14430 // We want to try to keep it around more aggressively, to give 14431 // a good experience around switching between two apps. 14432 adj = ProcessList.PREVIOUS_APP_ADJ; 14433 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14434 app.cached = false; 14435 app.adjType = "previous"; 14436 } 14437 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14438 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14439 } 14440 } 14441 14442 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14443 + " reason=" + app.adjType); 14444 14445 // By default, we use the computed adjustment. It may be changed if 14446 // there are applications dependent on our services or providers, but 14447 // this gives us a baseline and makes sure we don't get into an 14448 // infinite recursion. 14449 app.adjSeq = mAdjSeq; 14450 app.curRawAdj = adj; 14451 app.hasStartedServices = false; 14452 14453 if (mBackupTarget != null && app == mBackupTarget.app) { 14454 // If possible we want to avoid killing apps while they're being backed up 14455 if (adj > ProcessList.BACKUP_APP_ADJ) { 14456 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14457 adj = ProcessList.BACKUP_APP_ADJ; 14458 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14459 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14460 } 14461 app.adjType = "backup"; 14462 app.cached = false; 14463 } 14464 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14465 procState = ActivityManager.PROCESS_STATE_BACKUP; 14466 } 14467 } 14468 14469 boolean mayBeTop = false; 14470 14471 for (int is = app.services.size()-1; 14472 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14473 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14474 || procState > ActivityManager.PROCESS_STATE_TOP); 14475 is--) { 14476 ServiceRecord s = app.services.valueAt(is); 14477 if (s.startRequested) { 14478 app.hasStartedServices = true; 14479 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14480 procState = ActivityManager.PROCESS_STATE_SERVICE; 14481 } 14482 if (app.hasShownUi && app != mHomeProcess) { 14483 // If this process has shown some UI, let it immediately 14484 // go to the LRU list because it may be pretty heavy with 14485 // UI stuff. We'll tag it with a label just to help 14486 // debug and understand what is going on. 14487 if (adj > ProcessList.SERVICE_ADJ) { 14488 app.adjType = "cch-started-ui-services"; 14489 } 14490 } else { 14491 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14492 // This service has seen some activity within 14493 // recent memory, so we will keep its process ahead 14494 // of the background processes. 14495 if (adj > ProcessList.SERVICE_ADJ) { 14496 adj = ProcessList.SERVICE_ADJ; 14497 app.adjType = "started-services"; 14498 app.cached = false; 14499 } 14500 } 14501 // If we have let the service slide into the background 14502 // state, still have some text describing what it is doing 14503 // even though the service no longer has an impact. 14504 if (adj > ProcessList.SERVICE_ADJ) { 14505 app.adjType = "cch-started-services"; 14506 } 14507 } 14508 // Don't kill this process because it is doing work; it 14509 // has said it is doing work. 14510 app.keeping = true; 14511 } 14512 for (int conni = s.connections.size()-1; 14513 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14514 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14515 || procState > ActivityManager.PROCESS_STATE_TOP); 14516 conni--) { 14517 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14518 for (int i = 0; 14519 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14520 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14521 || procState > ActivityManager.PROCESS_STATE_TOP); 14522 i++) { 14523 // XXX should compute this based on the max of 14524 // all connected clients. 14525 ConnectionRecord cr = clist.get(i); 14526 if (cr.binding.client == app) { 14527 // Binding to ourself is not interesting. 14528 continue; 14529 } 14530 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14531 ProcessRecord client = cr.binding.client; 14532 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14533 TOP_APP, doingAll, now); 14534 int clientProcState = client.curProcState; 14535 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14536 // If the other app is cached for any reason, for purposes here 14537 // we are going to consider it empty. The specific cached state 14538 // doesn't propagate except under certain conditions. 14539 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14540 } 14541 String adjType = null; 14542 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14543 // Not doing bind OOM management, so treat 14544 // this guy more like a started service. 14545 if (app.hasShownUi && app != mHomeProcess) { 14546 // If this process has shown some UI, let it immediately 14547 // go to the LRU list because it may be pretty heavy with 14548 // UI stuff. We'll tag it with a label just to help 14549 // debug and understand what is going on. 14550 if (adj > clientAdj) { 14551 adjType = "cch-bound-ui-services"; 14552 } 14553 app.cached = false; 14554 clientAdj = adj; 14555 clientProcState = procState; 14556 } else { 14557 if (now >= (s.lastActivity 14558 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14559 // This service has not seen activity within 14560 // recent memory, so allow it to drop to the 14561 // LRU list if there is no other reason to keep 14562 // it around. We'll also tag it with a label just 14563 // to help debug and undertand what is going on. 14564 if (adj > clientAdj) { 14565 adjType = "cch-bound-services"; 14566 } 14567 clientAdj = adj; 14568 } 14569 } 14570 } 14571 if (adj > clientAdj) { 14572 // If this process has recently shown UI, and 14573 // the process that is binding to it is less 14574 // important than being visible, then we don't 14575 // care about the binding as much as we care 14576 // about letting this process get into the LRU 14577 // list to be killed and restarted if needed for 14578 // memory. 14579 if (app.hasShownUi && app != mHomeProcess 14580 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14581 adjType = "cch-bound-ui-services"; 14582 } else { 14583 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14584 |Context.BIND_IMPORTANT)) != 0) { 14585 adj = clientAdj; 14586 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14587 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14588 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14589 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14590 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14591 adj = clientAdj; 14592 } else { 14593 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14594 adj = ProcessList.VISIBLE_APP_ADJ; 14595 } 14596 } 14597 if (!client.cached) { 14598 app.cached = false; 14599 } 14600 if (client.keeping) { 14601 app.keeping = true; 14602 } 14603 adjType = "service"; 14604 } 14605 } 14606 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14607 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14608 schedGroup = Process.THREAD_GROUP_DEFAULT; 14609 } 14610 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14611 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14612 // Special handling of clients who are in the top state. 14613 // We *may* want to consider this process to be in the 14614 // top state as well, but only if there is not another 14615 // reason for it to be running. Being on the top is a 14616 // special state, meaning you are specifically running 14617 // for the current top app. If the process is already 14618 // running in the background for some other reason, it 14619 // is more important to continue considering it to be 14620 // in the background state. 14621 mayBeTop = true; 14622 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14623 } else { 14624 // Special handling for above-top states (persistent 14625 // processes). These should not bring the current process 14626 // into the top state, since they are not on top. Instead 14627 // give them the best state after that. 14628 clientProcState = 14629 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14630 } 14631 } 14632 } else { 14633 if (clientProcState < 14634 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14635 clientProcState = 14636 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14637 } 14638 } 14639 if (procState > clientProcState) { 14640 procState = clientProcState; 14641 } 14642 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14643 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14644 app.pendingUiClean = true; 14645 } 14646 if (adjType != null) { 14647 app.adjType = adjType; 14648 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14649 .REASON_SERVICE_IN_USE; 14650 app.adjSource = cr.binding.client; 14651 app.adjSourceOom = clientAdj; 14652 app.adjTarget = s.name; 14653 } 14654 } 14655 final ActivityRecord a = cr.activity; 14656 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14657 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14658 (a.visible || a.state == ActivityState.RESUMED 14659 || a.state == ActivityState.PAUSING)) { 14660 adj = ProcessList.FOREGROUND_APP_ADJ; 14661 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14662 schedGroup = Process.THREAD_GROUP_DEFAULT; 14663 } 14664 app.cached = false; 14665 app.adjType = "service"; 14666 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14667 .REASON_SERVICE_IN_USE; 14668 app.adjSource = a; 14669 app.adjSourceOom = adj; 14670 app.adjTarget = s.name; 14671 } 14672 } 14673 } 14674 } 14675 } 14676 14677 for (int provi = app.pubProviders.size()-1; 14678 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14679 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14680 || procState > ActivityManager.PROCESS_STATE_TOP); 14681 provi--) { 14682 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14683 for (int i = cpr.connections.size()-1; 14684 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14685 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14686 || procState > ActivityManager.PROCESS_STATE_TOP); 14687 i--) { 14688 ContentProviderConnection conn = cpr.connections.get(i); 14689 ProcessRecord client = conn.client; 14690 if (client == app) { 14691 // Being our own client is not interesting. 14692 continue; 14693 } 14694 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14695 int clientProcState = client.curProcState; 14696 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14697 // If the other app is cached for any reason, for purposes here 14698 // we are going to consider it empty. 14699 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14700 } 14701 if (adj > clientAdj) { 14702 if (app.hasShownUi && app != mHomeProcess 14703 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14704 app.adjType = "cch-ui-provider"; 14705 } else { 14706 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14707 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14708 app.adjType = "provider"; 14709 } 14710 app.cached &= client.cached; 14711 app.keeping |= client.keeping; 14712 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14713 .REASON_PROVIDER_IN_USE; 14714 app.adjSource = client; 14715 app.adjSourceOom = clientAdj; 14716 app.adjTarget = cpr.name; 14717 } 14718 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14719 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14720 // Special handling of clients who are in the top state. 14721 // We *may* want to consider this process to be in the 14722 // top state as well, but only if there is not another 14723 // reason for it to be running. Being on the top is a 14724 // special state, meaning you are specifically running 14725 // for the current top app. If the process is already 14726 // running in the background for some other reason, it 14727 // is more important to continue considering it to be 14728 // in the background state. 14729 mayBeTop = true; 14730 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14731 } else { 14732 // Special handling for above-top states (persistent 14733 // processes). These should not bring the current process 14734 // into the top state, since they are not on top. Instead 14735 // give them the best state after that. 14736 clientProcState = 14737 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14738 } 14739 } 14740 if (procState > clientProcState) { 14741 procState = clientProcState; 14742 } 14743 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14744 schedGroup = Process.THREAD_GROUP_DEFAULT; 14745 } 14746 } 14747 // If the provider has external (non-framework) process 14748 // dependencies, ensure that its adjustment is at least 14749 // FOREGROUND_APP_ADJ. 14750 if (cpr.hasExternalProcessHandles()) { 14751 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14752 adj = ProcessList.FOREGROUND_APP_ADJ; 14753 schedGroup = Process.THREAD_GROUP_DEFAULT; 14754 app.cached = false; 14755 app.keeping = true; 14756 app.adjType = "provider"; 14757 app.adjTarget = cpr.name; 14758 } 14759 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14760 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14761 } 14762 } 14763 } 14764 14765 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14766 // A client of one of our services or providers is in the top state. We 14767 // *may* want to be in the top state, but not if we are already running in 14768 // the background for some other reason. For the decision here, we are going 14769 // to pick out a few specific states that we want to remain in when a client 14770 // is top (states that tend to be longer-term) and otherwise allow it to go 14771 // to the top state. 14772 switch (procState) { 14773 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14774 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14775 case ActivityManager.PROCESS_STATE_SERVICE: 14776 // These all are longer-term states, so pull them up to the top 14777 // of the background states, but not all the way to the top state. 14778 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14779 break; 14780 default: 14781 // Otherwise, top is a better choice, so take it. 14782 procState = ActivityManager.PROCESS_STATE_TOP; 14783 break; 14784 } 14785 } 14786 14787 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14788 // This is a cached process, but with client activities. Mark it so. 14789 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14790 app.adjType = "cch-client-act"; 14791 } 14792 14793 if (adj == ProcessList.SERVICE_ADJ) { 14794 if (doingAll) { 14795 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14796 mNewNumServiceProcs++; 14797 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14798 if (!app.serviceb) { 14799 // This service isn't far enough down on the LRU list to 14800 // normally be a B service, but if we are low on RAM and it 14801 // is large we want to force it down since we would prefer to 14802 // keep launcher over it. 14803 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 14804 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 14805 app.serviceHighRam = true; 14806 app.serviceb = true; 14807 //Slog.i(TAG, "ADJ " + app + " high ram!"); 14808 } else { 14809 mNewNumAServiceProcs++; 14810 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 14811 } 14812 } else { 14813 app.serviceHighRam = false; 14814 } 14815 } 14816 if (app.serviceb) { 14817 adj = ProcessList.SERVICE_B_ADJ; 14818 } 14819 } 14820 14821 app.curRawAdj = adj; 14822 14823 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14824 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14825 if (adj > app.maxAdj) { 14826 adj = app.maxAdj; 14827 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14828 schedGroup = Process.THREAD_GROUP_DEFAULT; 14829 } 14830 } 14831 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 14832 app.keeping = true; 14833 } 14834 14835 // Do final modification to adj. Everything we do between here and applying 14836 // the final setAdj must be done in this function, because we will also use 14837 // it when computing the final cached adj later. Note that we don't need to 14838 // worry about this for max adj above, since max adj will always be used to 14839 // keep it out of the cached vaues. 14840 adj = app.modifyRawOomAdj(adj); 14841 14842 app.curProcState = procState; 14843 14844 int importance = app.memImportance; 14845 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14846 app.curAdj = adj; 14847 app.curSchedGroup = schedGroup; 14848 if (!interesting) { 14849 // For this reporting, if there is not something explicitly 14850 // interesting in this process then we will push it to the 14851 // background importance. 14852 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14853 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 14854 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14855 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14856 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14857 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14858 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14859 } else if (adj >= ProcessList.SERVICE_ADJ) { 14860 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14861 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14862 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14863 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14864 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14865 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14866 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14867 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14868 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14869 } else { 14870 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14871 } 14872 } 14873 14874 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14875 if (foregroundActivities != app.foregroundActivities) { 14876 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14877 } 14878 if (changes != 0) { 14879 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14880 app.memImportance = importance; 14881 app.foregroundActivities = foregroundActivities; 14882 int i = mPendingProcessChanges.size()-1; 14883 ProcessChangeItem item = null; 14884 while (i >= 0) { 14885 item = mPendingProcessChanges.get(i); 14886 if (item.pid == app.pid) { 14887 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14888 break; 14889 } 14890 i--; 14891 } 14892 if (i < 0) { 14893 // No existing item in pending changes; need a new one. 14894 final int NA = mAvailProcessChanges.size(); 14895 if (NA > 0) { 14896 item = mAvailProcessChanges.remove(NA-1); 14897 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14898 } else { 14899 item = new ProcessChangeItem(); 14900 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14901 } 14902 item.changes = 0; 14903 item.pid = app.pid; 14904 item.uid = app.info.uid; 14905 if (mPendingProcessChanges.size() == 0) { 14906 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14907 "*** Enqueueing dispatch processes changed!"); 14908 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14909 } 14910 mPendingProcessChanges.add(item); 14911 } 14912 item.changes |= changes; 14913 item.importance = importance; 14914 item.foregroundActivities = foregroundActivities; 14915 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14916 + Integer.toHexString(System.identityHashCode(item)) 14917 + " " + app.toShortString() + ": changes=" + item.changes 14918 + " importance=" + item.importance 14919 + " foreground=" + item.foregroundActivities 14920 + " type=" + app.adjType + " source=" + app.adjSource 14921 + " target=" + app.adjTarget); 14922 } 14923 14924 return app.curRawAdj; 14925 } 14926 14927 /** 14928 * Schedule PSS collection of a process. 14929 */ 14930 void requestPssLocked(ProcessRecord proc, int procState) { 14931 if (mPendingPssProcesses.contains(proc)) { 14932 return; 14933 } 14934 if (mPendingPssProcesses.size() == 0) { 14935 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14936 } 14937 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 14938 proc.pssProcState = procState; 14939 mPendingPssProcesses.add(proc); 14940 } 14941 14942 /** 14943 * Schedule PSS collection of all processes. 14944 */ 14945 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 14946 if (!always) { 14947 if (now < (mLastFullPssTime + 14948 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 14949 return; 14950 } 14951 } 14952 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 14953 mLastFullPssTime = now; 14954 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 14955 mPendingPssProcesses.clear(); 14956 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14957 ProcessRecord app = mLruProcesses.get(i); 14958 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 14959 app.pssProcState = app.setProcState; 14960 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 14961 mSleeping, now); 14962 mPendingPssProcesses.add(app); 14963 } 14964 } 14965 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14966 } 14967 14968 /** 14969 * Ask a given process to GC right now. 14970 */ 14971 final void performAppGcLocked(ProcessRecord app) { 14972 try { 14973 app.lastRequestedGc = SystemClock.uptimeMillis(); 14974 if (app.thread != null) { 14975 if (app.reportLowMemory) { 14976 app.reportLowMemory = false; 14977 app.thread.scheduleLowMemory(); 14978 } else { 14979 app.thread.processInBackground(); 14980 } 14981 } 14982 } catch (Exception e) { 14983 // whatever. 14984 } 14985 } 14986 14987 /** 14988 * Returns true if things are idle enough to perform GCs. 14989 */ 14990 private final boolean canGcNowLocked() { 14991 boolean processingBroadcasts = false; 14992 for (BroadcastQueue q : mBroadcastQueues) { 14993 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 14994 processingBroadcasts = true; 14995 } 14996 } 14997 return !processingBroadcasts 14998 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 14999 } 15000 15001 /** 15002 * Perform GCs on all processes that are waiting for it, but only 15003 * if things are idle. 15004 */ 15005 final void performAppGcsLocked() { 15006 final int N = mProcessesToGc.size(); 15007 if (N <= 0) { 15008 return; 15009 } 15010 if (canGcNowLocked()) { 15011 while (mProcessesToGc.size() > 0) { 15012 ProcessRecord proc = mProcessesToGc.remove(0); 15013 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15014 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15015 <= SystemClock.uptimeMillis()) { 15016 // To avoid spamming the system, we will GC processes one 15017 // at a time, waiting a few seconds between each. 15018 performAppGcLocked(proc); 15019 scheduleAppGcsLocked(); 15020 return; 15021 } else { 15022 // It hasn't been long enough since we last GCed this 15023 // process... put it in the list to wait for its time. 15024 addProcessToGcListLocked(proc); 15025 break; 15026 } 15027 } 15028 } 15029 15030 scheduleAppGcsLocked(); 15031 } 15032 } 15033 15034 /** 15035 * If all looks good, perform GCs on all processes waiting for them. 15036 */ 15037 final void performAppGcsIfAppropriateLocked() { 15038 if (canGcNowLocked()) { 15039 performAppGcsLocked(); 15040 return; 15041 } 15042 // Still not idle, wait some more. 15043 scheduleAppGcsLocked(); 15044 } 15045 15046 /** 15047 * Schedule the execution of all pending app GCs. 15048 */ 15049 final void scheduleAppGcsLocked() { 15050 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15051 15052 if (mProcessesToGc.size() > 0) { 15053 // Schedule a GC for the time to the next process. 15054 ProcessRecord proc = mProcessesToGc.get(0); 15055 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15056 15057 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15058 long now = SystemClock.uptimeMillis(); 15059 if (when < (now+GC_TIMEOUT)) { 15060 when = now + GC_TIMEOUT; 15061 } 15062 mHandler.sendMessageAtTime(msg, when); 15063 } 15064 } 15065 15066 /** 15067 * Add a process to the array of processes waiting to be GCed. Keeps the 15068 * list in sorted order by the last GC time. The process can't already be 15069 * on the list. 15070 */ 15071 final void addProcessToGcListLocked(ProcessRecord proc) { 15072 boolean added = false; 15073 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15074 if (mProcessesToGc.get(i).lastRequestedGc < 15075 proc.lastRequestedGc) { 15076 added = true; 15077 mProcessesToGc.add(i+1, proc); 15078 break; 15079 } 15080 } 15081 if (!added) { 15082 mProcessesToGc.add(0, proc); 15083 } 15084 } 15085 15086 /** 15087 * Set up to ask a process to GC itself. This will either do it 15088 * immediately, or put it on the list of processes to gc the next 15089 * time things are idle. 15090 */ 15091 final void scheduleAppGcLocked(ProcessRecord app) { 15092 long now = SystemClock.uptimeMillis(); 15093 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15094 return; 15095 } 15096 if (!mProcessesToGc.contains(app)) { 15097 addProcessToGcListLocked(app); 15098 scheduleAppGcsLocked(); 15099 } 15100 } 15101 15102 final void checkExcessivePowerUsageLocked(boolean doKills) { 15103 updateCpuStatsNow(); 15104 15105 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15106 boolean doWakeKills = doKills; 15107 boolean doCpuKills = doKills; 15108 if (mLastPowerCheckRealtime == 0) { 15109 doWakeKills = false; 15110 } 15111 if (mLastPowerCheckUptime == 0) { 15112 doCpuKills = false; 15113 } 15114 if (stats.isScreenOn()) { 15115 doWakeKills = false; 15116 } 15117 final long curRealtime = SystemClock.elapsedRealtime(); 15118 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15119 final long curUptime = SystemClock.uptimeMillis(); 15120 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15121 mLastPowerCheckRealtime = curRealtime; 15122 mLastPowerCheckUptime = curUptime; 15123 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15124 doWakeKills = false; 15125 } 15126 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15127 doCpuKills = false; 15128 } 15129 int i = mLruProcesses.size(); 15130 while (i > 0) { 15131 i--; 15132 ProcessRecord app = mLruProcesses.get(i); 15133 if (!app.keeping) { 15134 long wtime; 15135 synchronized (stats) { 15136 wtime = stats.getProcessWakeTime(app.info.uid, 15137 app.pid, curRealtime); 15138 } 15139 long wtimeUsed = wtime - app.lastWakeTime; 15140 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15141 if (DEBUG_POWER) { 15142 StringBuilder sb = new StringBuilder(128); 15143 sb.append("Wake for "); 15144 app.toShortString(sb); 15145 sb.append(": over "); 15146 TimeUtils.formatDuration(realtimeSince, sb); 15147 sb.append(" used "); 15148 TimeUtils.formatDuration(wtimeUsed, sb); 15149 sb.append(" ("); 15150 sb.append((wtimeUsed*100)/realtimeSince); 15151 sb.append("%)"); 15152 Slog.i(TAG, sb.toString()); 15153 sb.setLength(0); 15154 sb.append("CPU for "); 15155 app.toShortString(sb); 15156 sb.append(": over "); 15157 TimeUtils.formatDuration(uptimeSince, sb); 15158 sb.append(" used "); 15159 TimeUtils.formatDuration(cputimeUsed, sb); 15160 sb.append(" ("); 15161 sb.append((cputimeUsed*100)/uptimeSince); 15162 sb.append("%)"); 15163 Slog.i(TAG, sb.toString()); 15164 } 15165 // If a process has held a wake lock for more 15166 // than 50% of the time during this period, 15167 // that sounds bad. Kill! 15168 if (doWakeKills && realtimeSince > 0 15169 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15170 synchronized (stats) { 15171 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15172 realtimeSince, wtimeUsed); 15173 } 15174 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15175 + " during " + realtimeSince); 15176 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15177 } else if (doCpuKills && uptimeSince > 0 15178 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15179 synchronized (stats) { 15180 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15181 uptimeSince, cputimeUsed); 15182 } 15183 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15184 + " during " + uptimeSince); 15185 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15186 } else { 15187 app.lastWakeTime = wtime; 15188 app.lastCpuTime = app.curCpuTime; 15189 } 15190 } 15191 } 15192 } 15193 15194 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15195 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15196 boolean success = true; 15197 15198 if (app.curRawAdj != app.setRawAdj) { 15199 if (wasKeeping && !app.keeping) { 15200 // This app is no longer something we want to keep. Note 15201 // its current wake lock time to later know to kill it if 15202 // it is not behaving well. 15203 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15204 synchronized (stats) { 15205 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15206 app.pid, SystemClock.elapsedRealtime()); 15207 } 15208 app.lastCpuTime = app.curCpuTime; 15209 } 15210 15211 app.setRawAdj = app.curRawAdj; 15212 } 15213 15214 if (app.curAdj != app.setAdj) { 15215 ProcessList.setOomAdj(app.pid, app.curAdj); 15216 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15217 TAG, "Set " + app.pid + " " + app.processName + 15218 " adj " + app.curAdj + ": " + app.adjType); 15219 app.setAdj = app.curAdj; 15220 } 15221 15222 if (app.setSchedGroup != app.curSchedGroup) { 15223 app.setSchedGroup = app.curSchedGroup; 15224 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15225 "Setting process group of " + app.processName 15226 + " to " + app.curSchedGroup); 15227 if (app.waitingToKill != null && 15228 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15229 killUnneededProcessLocked(app, app.waitingToKill); 15230 success = false; 15231 } else { 15232 if (true) { 15233 long oldId = Binder.clearCallingIdentity(); 15234 try { 15235 Process.setProcessGroup(app.pid, app.curSchedGroup); 15236 } catch (Exception e) { 15237 Slog.w(TAG, "Failed setting process group of " + app.pid 15238 + " to " + app.curSchedGroup); 15239 e.printStackTrace(); 15240 } finally { 15241 Binder.restoreCallingIdentity(oldId); 15242 } 15243 } else { 15244 if (app.thread != null) { 15245 try { 15246 app.thread.setSchedulingGroup(app.curSchedGroup); 15247 } catch (RemoteException e) { 15248 } 15249 } 15250 } 15251 Process.setSwappiness(app.pid, 15252 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15253 } 15254 } 15255 if (app.repProcState != app.curProcState) { 15256 app.repProcState = app.curProcState; 15257 if (!reportingProcessState && app.thread != null) { 15258 try { 15259 if (false) { 15260 //RuntimeException h = new RuntimeException("here"); 15261 Slog.i(TAG, "Sending new process state " + app.repProcState 15262 + " to " + app /*, h*/); 15263 } 15264 app.thread.setProcessState(app.repProcState); 15265 } catch (RemoteException e) { 15266 } 15267 } 15268 } 15269 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15270 app.setProcState)) { 15271 app.lastStateTime = now; 15272 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15273 mSleeping, now); 15274 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15275 + ProcessList.makeProcStateString(app.setProcState) + " to " 15276 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15277 + (app.nextPssTime-now) + ": " + app); 15278 } else { 15279 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15280 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15281 requestPssLocked(app, app.setProcState); 15282 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15283 mSleeping, now); 15284 } else if (false && DEBUG_PSS) { 15285 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15286 } 15287 } 15288 if (app.setProcState != app.curProcState) { 15289 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15290 "Proc state change of " + app.processName 15291 + " to " + app.curProcState); 15292 app.setProcState = app.curProcState; 15293 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15294 app.notCachedSinceIdle = false; 15295 } 15296 if (!doingAll) { 15297 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15298 } else { 15299 app.procStateChanged = true; 15300 } 15301 } 15302 return success; 15303 } 15304 15305 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15306 if (proc.thread != null && proc.baseProcessTracker != null) { 15307 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15308 } 15309 } 15310 15311 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15312 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15313 if (app.thread == null) { 15314 return false; 15315 } 15316 15317 final boolean wasKeeping = app.keeping; 15318 15319 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15320 15321 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15322 reportingProcessState, now); 15323 } 15324 15325 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15326 boolean oomAdj) { 15327 if (isForeground != proc.foregroundServices) { 15328 proc.foregroundServices = isForeground; 15329 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15330 proc.info.uid); 15331 if (isForeground) { 15332 if (curProcs == null) { 15333 curProcs = new ArrayList<ProcessRecord>(); 15334 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15335 } 15336 if (!curProcs.contains(proc)) { 15337 curProcs.add(proc); 15338 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15339 proc.info.packageName, proc.info.uid); 15340 } 15341 } else { 15342 if (curProcs != null) { 15343 if (curProcs.remove(proc)) { 15344 mBatteryStatsService.noteEvent( 15345 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15346 proc.info.packageName, proc.info.uid); 15347 if (curProcs.size() <= 0) { 15348 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15349 } 15350 } 15351 } 15352 } 15353 if (oomAdj) { 15354 updateOomAdjLocked(); 15355 } 15356 } 15357 } 15358 15359 private final ActivityRecord resumedAppLocked() { 15360 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15361 String pkg; 15362 int uid; 15363 if (act != null) { 15364 pkg = act.packageName; 15365 uid = act.info.applicationInfo.uid; 15366 } else { 15367 pkg = null; 15368 uid = -1; 15369 } 15370 // Has the UID or resumed package name changed? 15371 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15372 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15373 if (mCurResumedPackage != null) { 15374 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15375 mCurResumedPackage, mCurResumedUid); 15376 } 15377 mCurResumedPackage = pkg; 15378 mCurResumedUid = uid; 15379 if (mCurResumedPackage != null) { 15380 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15381 mCurResumedPackage, mCurResumedUid); 15382 } 15383 } 15384 return act; 15385 } 15386 15387 final boolean updateOomAdjLocked(ProcessRecord app) { 15388 return updateOomAdjLocked(app, false); 15389 } 15390 15391 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15392 final ActivityRecord TOP_ACT = resumedAppLocked(); 15393 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15394 final boolean wasCached = app.cached; 15395 15396 mAdjSeq++; 15397 15398 // This is the desired cached adjusment we want to tell it to use. 15399 // If our app is currently cached, we know it, and that is it. Otherwise, 15400 // we don't know it yet, and it needs to now be cached we will then 15401 // need to do a complete oom adj. 15402 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15403 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15404 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15405 SystemClock.uptimeMillis()); 15406 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15407 // Changed to/from cached state, so apps after it in the LRU 15408 // list may also be changed. 15409 updateOomAdjLocked(); 15410 } 15411 return success; 15412 } 15413 15414 final void updateOomAdjLocked() { 15415 final ActivityRecord TOP_ACT = resumedAppLocked(); 15416 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15417 final long now = SystemClock.uptimeMillis(); 15418 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15419 final int N = mLruProcesses.size(); 15420 15421 if (false) { 15422 RuntimeException e = new RuntimeException(); 15423 e.fillInStackTrace(); 15424 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15425 } 15426 15427 mAdjSeq++; 15428 mNewNumServiceProcs = 0; 15429 mNewNumAServiceProcs = 0; 15430 15431 final int emptyProcessLimit; 15432 final int cachedProcessLimit; 15433 if (mProcessLimit <= 0) { 15434 emptyProcessLimit = cachedProcessLimit = 0; 15435 } else if (mProcessLimit == 1) { 15436 emptyProcessLimit = 1; 15437 cachedProcessLimit = 0; 15438 } else { 15439 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15440 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15441 } 15442 15443 // Let's determine how many processes we have running vs. 15444 // how many slots we have for background processes; we may want 15445 // to put multiple processes in a slot of there are enough of 15446 // them. 15447 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15448 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15449 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15450 if (numEmptyProcs > cachedProcessLimit) { 15451 // If there are more empty processes than our limit on cached 15452 // processes, then use the cached process limit for the factor. 15453 // This ensures that the really old empty processes get pushed 15454 // down to the bottom, so if we are running low on memory we will 15455 // have a better chance at keeping around more cached processes 15456 // instead of a gazillion empty processes. 15457 numEmptyProcs = cachedProcessLimit; 15458 } 15459 int emptyFactor = numEmptyProcs/numSlots; 15460 if (emptyFactor < 1) emptyFactor = 1; 15461 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15462 if (cachedFactor < 1) cachedFactor = 1; 15463 int stepCached = 0; 15464 int stepEmpty = 0; 15465 int numCached = 0; 15466 int numEmpty = 0; 15467 int numTrimming = 0; 15468 15469 mNumNonCachedProcs = 0; 15470 mNumCachedHiddenProcs = 0; 15471 15472 // First update the OOM adjustment for each of the 15473 // application processes based on their current state. 15474 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15475 int nextCachedAdj = curCachedAdj+1; 15476 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15477 int nextEmptyAdj = curEmptyAdj+2; 15478 for (int i=N-1; i>=0; i--) { 15479 ProcessRecord app = mLruProcesses.get(i); 15480 if (!app.killedByAm && app.thread != null) { 15481 app.procStateChanged = false; 15482 final boolean wasKeeping = app.keeping; 15483 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15484 15485 // If we haven't yet assigned the final cached adj 15486 // to the process, do that now. 15487 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15488 switch (app.curProcState) { 15489 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15490 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15491 // This process is a cached process holding activities... 15492 // assign it the next cached value for that type, and then 15493 // step that cached level. 15494 app.curRawAdj = curCachedAdj; 15495 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15496 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15497 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15498 + ")"); 15499 if (curCachedAdj != nextCachedAdj) { 15500 stepCached++; 15501 if (stepCached >= cachedFactor) { 15502 stepCached = 0; 15503 curCachedAdj = nextCachedAdj; 15504 nextCachedAdj += 2; 15505 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15506 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15507 } 15508 } 15509 } 15510 break; 15511 default: 15512 // For everything else, assign next empty cached process 15513 // level and bump that up. Note that this means that 15514 // long-running services that have dropped down to the 15515 // cached level will be treated as empty (since their process 15516 // state is still as a service), which is what we want. 15517 app.curRawAdj = curEmptyAdj; 15518 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15519 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15520 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15521 + ")"); 15522 if (curEmptyAdj != nextEmptyAdj) { 15523 stepEmpty++; 15524 if (stepEmpty >= emptyFactor) { 15525 stepEmpty = 0; 15526 curEmptyAdj = nextEmptyAdj; 15527 nextEmptyAdj += 2; 15528 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15529 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15530 } 15531 } 15532 } 15533 break; 15534 } 15535 } 15536 15537 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15538 15539 // Count the number of process types. 15540 switch (app.curProcState) { 15541 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15542 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15543 mNumCachedHiddenProcs++; 15544 numCached++; 15545 if (numCached > cachedProcessLimit) { 15546 killUnneededProcessLocked(app, "cached #" + numCached); 15547 } 15548 break; 15549 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15550 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15551 && app.lastActivityTime < oldTime) { 15552 killUnneededProcessLocked(app, "empty for " 15553 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15554 / 1000) + "s"); 15555 } else { 15556 numEmpty++; 15557 if (numEmpty > emptyProcessLimit) { 15558 killUnneededProcessLocked(app, "empty #" + numEmpty); 15559 } 15560 } 15561 break; 15562 default: 15563 mNumNonCachedProcs++; 15564 break; 15565 } 15566 15567 if (app.isolated && app.services.size() <= 0) { 15568 // If this is an isolated process, and there are no 15569 // services running in it, then the process is no longer 15570 // needed. We agressively kill these because we can by 15571 // definition not re-use the same process again, and it is 15572 // good to avoid having whatever code was running in them 15573 // left sitting around after no longer needed. 15574 killUnneededProcessLocked(app, "isolated not needed"); 15575 } 15576 15577 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15578 && !app.killedByAm) { 15579 numTrimming++; 15580 } 15581 } 15582 } 15583 15584 mNumServiceProcs = mNewNumServiceProcs; 15585 15586 // Now determine the memory trimming level of background processes. 15587 // Unfortunately we need to start at the back of the list to do this 15588 // properly. We only do this if the number of background apps we 15589 // are managing to keep around is less than half the maximum we desire; 15590 // if we are keeping a good number around, we'll let them use whatever 15591 // memory they want. 15592 final int numCachedAndEmpty = numCached + numEmpty; 15593 int memFactor; 15594 if (numCached <= ProcessList.TRIM_CACHED_APPS 15595 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15596 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15597 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15598 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15599 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15600 } else { 15601 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15602 } 15603 } else { 15604 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15605 } 15606 // We always allow the memory level to go up (better). We only allow it to go 15607 // down if we are in a state where that is allowed, *and* the total number of processes 15608 // has gone down since last time. 15609 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15610 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15611 + " last=" + mLastNumProcesses); 15612 if (memFactor > mLastMemoryLevel) { 15613 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15614 memFactor = mLastMemoryLevel; 15615 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15616 } 15617 } 15618 mLastMemoryLevel = memFactor; 15619 mLastNumProcesses = mLruProcesses.size(); 15620 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15621 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15622 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15623 if (mLowRamStartTime == 0) { 15624 mLowRamStartTime = now; 15625 } 15626 int step = 0; 15627 int fgTrimLevel; 15628 switch (memFactor) { 15629 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15630 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15631 break; 15632 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15633 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15634 break; 15635 default: 15636 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15637 break; 15638 } 15639 int factor = numTrimming/3; 15640 int minFactor = 2; 15641 if (mHomeProcess != null) minFactor++; 15642 if (mPreviousProcess != null) minFactor++; 15643 if (factor < minFactor) factor = minFactor; 15644 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15645 for (int i=N-1; i>=0; i--) { 15646 ProcessRecord app = mLruProcesses.get(i); 15647 if (allChanged || app.procStateChanged) { 15648 setProcessTrackerState(app, trackerMemFactor, now); 15649 app.procStateChanged = false; 15650 } 15651 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15652 && !app.killedByAm) { 15653 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15654 try { 15655 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15656 "Trimming memory of " + app.processName 15657 + " to " + curLevel); 15658 app.thread.scheduleTrimMemory(curLevel); 15659 } catch (RemoteException e) { 15660 } 15661 if (false) { 15662 // For now we won't do this; our memory trimming seems 15663 // to be good enough at this point that destroying 15664 // activities causes more harm than good. 15665 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15666 && app != mHomeProcess && app != mPreviousProcess) { 15667 // Need to do this on its own message because the stack may not 15668 // be in a consistent state at this point. 15669 // For these apps we will also finish their activities 15670 // to help them free memory. 15671 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15672 } 15673 } 15674 } 15675 app.trimMemoryLevel = curLevel; 15676 step++; 15677 if (step >= factor) { 15678 step = 0; 15679 switch (curLevel) { 15680 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15681 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15682 break; 15683 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15684 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15685 break; 15686 } 15687 } 15688 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15689 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15690 && app.thread != null) { 15691 try { 15692 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15693 "Trimming memory of heavy-weight " + app.processName 15694 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15695 app.thread.scheduleTrimMemory( 15696 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15697 } catch (RemoteException e) { 15698 } 15699 } 15700 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15701 } else { 15702 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15703 || app.systemNoUi) && app.pendingUiClean) { 15704 // If this application is now in the background and it 15705 // had done UI, then give it the special trim level to 15706 // have it free UI resources. 15707 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15708 if (app.trimMemoryLevel < level && app.thread != null) { 15709 try { 15710 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15711 "Trimming memory of bg-ui " + app.processName 15712 + " to " + level); 15713 app.thread.scheduleTrimMemory(level); 15714 } catch (RemoteException e) { 15715 } 15716 } 15717 app.pendingUiClean = false; 15718 } 15719 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15720 try { 15721 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15722 "Trimming memory of fg " + app.processName 15723 + " to " + fgTrimLevel); 15724 app.thread.scheduleTrimMemory(fgTrimLevel); 15725 } catch (RemoteException e) { 15726 } 15727 } 15728 app.trimMemoryLevel = fgTrimLevel; 15729 } 15730 } 15731 } else { 15732 if (mLowRamStartTime != 0) { 15733 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15734 mLowRamStartTime = 0; 15735 } 15736 for (int i=N-1; i>=0; i--) { 15737 ProcessRecord app = mLruProcesses.get(i); 15738 if (allChanged || app.procStateChanged) { 15739 setProcessTrackerState(app, trackerMemFactor, now); 15740 app.procStateChanged = false; 15741 } 15742 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15743 || app.systemNoUi) && app.pendingUiClean) { 15744 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15745 && app.thread != null) { 15746 try { 15747 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15748 "Trimming memory of ui hidden " + app.processName 15749 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15750 app.thread.scheduleTrimMemory( 15751 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15752 } catch (RemoteException e) { 15753 } 15754 } 15755 app.pendingUiClean = false; 15756 } 15757 app.trimMemoryLevel = 0; 15758 } 15759 } 15760 15761 if (mAlwaysFinishActivities) { 15762 // Need to do this on its own message because the stack may not 15763 // be in a consistent state at this point. 15764 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15765 } 15766 15767 if (allChanged) { 15768 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15769 } 15770 15771 if (mProcessStats.shouldWriteNowLocked(now)) { 15772 mHandler.post(new Runnable() { 15773 @Override public void run() { 15774 synchronized (ActivityManagerService.this) { 15775 mProcessStats.writeStateAsyncLocked(); 15776 } 15777 } 15778 }); 15779 } 15780 15781 if (DEBUG_OOM_ADJ) { 15782 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15783 } 15784 } 15785 15786 final void trimApplications() { 15787 synchronized (this) { 15788 int i; 15789 15790 // First remove any unused application processes whose package 15791 // has been removed. 15792 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15793 final ProcessRecord app = mRemovedProcesses.get(i); 15794 if (app.activities.size() == 0 15795 && app.curReceiver == null && app.services.size() == 0) { 15796 Slog.i( 15797 TAG, "Exiting empty application process " 15798 + app.processName + " (" 15799 + (app.thread != null ? app.thread.asBinder() : null) 15800 + ")\n"); 15801 if (app.pid > 0 && app.pid != MY_PID) { 15802 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 15803 app.processName, app.setAdj, "empty"); 15804 app.killedByAm = true; 15805 Process.killProcessQuiet(app.pid); 15806 } else { 15807 try { 15808 app.thread.scheduleExit(); 15809 } catch (Exception e) { 15810 // Ignore exceptions. 15811 } 15812 } 15813 cleanUpApplicationRecordLocked(app, false, true, -1); 15814 mRemovedProcesses.remove(i); 15815 15816 if (app.persistent) { 15817 if (app.persistent) { 15818 addAppLocked(app.info, false); 15819 } 15820 } 15821 } 15822 } 15823 15824 // Now update the oom adj for all processes. 15825 updateOomAdjLocked(); 15826 } 15827 } 15828 15829 /** This method sends the specified signal to each of the persistent apps */ 15830 public void signalPersistentProcesses(int sig) throws RemoteException { 15831 if (sig != Process.SIGNAL_USR1) { 15832 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 15833 } 15834 15835 synchronized (this) { 15836 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 15837 != PackageManager.PERMISSION_GRANTED) { 15838 throw new SecurityException("Requires permission " 15839 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 15840 } 15841 15842 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15843 ProcessRecord r = mLruProcesses.get(i); 15844 if (r.thread != null && r.persistent) { 15845 Process.sendSignal(r.pid, sig); 15846 } 15847 } 15848 } 15849 } 15850 15851 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 15852 if (proc == null || proc == mProfileProc) { 15853 proc = mProfileProc; 15854 path = mProfileFile; 15855 profileType = mProfileType; 15856 clearProfilerLocked(); 15857 } 15858 if (proc == null) { 15859 return; 15860 } 15861 try { 15862 proc.thread.profilerControl(false, path, null, profileType); 15863 } catch (RemoteException e) { 15864 throw new IllegalStateException("Process disappeared"); 15865 } 15866 } 15867 15868 private void clearProfilerLocked() { 15869 if (mProfileFd != null) { 15870 try { 15871 mProfileFd.close(); 15872 } catch (IOException e) { 15873 } 15874 } 15875 mProfileApp = null; 15876 mProfileProc = null; 15877 mProfileFile = null; 15878 mProfileType = 0; 15879 mAutoStopProfiler = false; 15880 } 15881 15882 public boolean profileControl(String process, int userId, boolean start, 15883 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 15884 15885 try { 15886 synchronized (this) { 15887 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15888 // its own permission. 15889 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15890 != PackageManager.PERMISSION_GRANTED) { 15891 throw new SecurityException("Requires permission " 15892 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15893 } 15894 15895 if (start && fd == null) { 15896 throw new IllegalArgumentException("null fd"); 15897 } 15898 15899 ProcessRecord proc = null; 15900 if (process != null) { 15901 proc = findProcessLocked(process, userId, "profileControl"); 15902 } 15903 15904 if (start && (proc == null || proc.thread == null)) { 15905 throw new IllegalArgumentException("Unknown process: " + process); 15906 } 15907 15908 if (start) { 15909 stopProfilerLocked(null, null, 0); 15910 setProfileApp(proc.info, proc.processName, path, fd, false); 15911 mProfileProc = proc; 15912 mProfileType = profileType; 15913 try { 15914 fd = fd.dup(); 15915 } catch (IOException e) { 15916 fd = null; 15917 } 15918 proc.thread.profilerControl(start, path, fd, profileType); 15919 fd = null; 15920 mProfileFd = null; 15921 } else { 15922 stopProfilerLocked(proc, path, profileType); 15923 if (fd != null) { 15924 try { 15925 fd.close(); 15926 } catch (IOException e) { 15927 } 15928 } 15929 } 15930 15931 return true; 15932 } 15933 } catch (RemoteException e) { 15934 throw new IllegalStateException("Process disappeared"); 15935 } finally { 15936 if (fd != null) { 15937 try { 15938 fd.close(); 15939 } catch (IOException e) { 15940 } 15941 } 15942 } 15943 } 15944 15945 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 15946 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15947 userId, true, true, callName, null); 15948 ProcessRecord proc = null; 15949 try { 15950 int pid = Integer.parseInt(process); 15951 synchronized (mPidsSelfLocked) { 15952 proc = mPidsSelfLocked.get(pid); 15953 } 15954 } catch (NumberFormatException e) { 15955 } 15956 15957 if (proc == null) { 15958 ArrayMap<String, SparseArray<ProcessRecord>> all 15959 = mProcessNames.getMap(); 15960 SparseArray<ProcessRecord> procs = all.get(process); 15961 if (procs != null && procs.size() > 0) { 15962 proc = procs.valueAt(0); 15963 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 15964 for (int i=1; i<procs.size(); i++) { 15965 ProcessRecord thisProc = procs.valueAt(i); 15966 if (thisProc.userId == userId) { 15967 proc = thisProc; 15968 break; 15969 } 15970 } 15971 } 15972 } 15973 } 15974 15975 return proc; 15976 } 15977 15978 public boolean dumpHeap(String process, int userId, boolean managed, 15979 String path, ParcelFileDescriptor fd) throws RemoteException { 15980 15981 try { 15982 synchronized (this) { 15983 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15984 // its own permission (same as profileControl). 15985 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15986 != PackageManager.PERMISSION_GRANTED) { 15987 throw new SecurityException("Requires permission " 15988 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15989 } 15990 15991 if (fd == null) { 15992 throw new IllegalArgumentException("null fd"); 15993 } 15994 15995 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 15996 if (proc == null || proc.thread == null) { 15997 throw new IllegalArgumentException("Unknown process: " + process); 15998 } 15999 16000 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16001 if (!isDebuggable) { 16002 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16003 throw new SecurityException("Process not debuggable: " + proc); 16004 } 16005 } 16006 16007 proc.thread.dumpHeap(managed, path, fd); 16008 fd = null; 16009 return true; 16010 } 16011 } catch (RemoteException e) { 16012 throw new IllegalStateException("Process disappeared"); 16013 } finally { 16014 if (fd != null) { 16015 try { 16016 fd.close(); 16017 } catch (IOException e) { 16018 } 16019 } 16020 } 16021 } 16022 16023 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16024 public void monitor() { 16025 synchronized (this) { } 16026 } 16027 16028 void onCoreSettingsChange(Bundle settings) { 16029 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16030 ProcessRecord processRecord = mLruProcesses.get(i); 16031 try { 16032 if (processRecord.thread != null) { 16033 processRecord.thread.setCoreSettings(settings); 16034 } 16035 } catch (RemoteException re) { 16036 /* ignore */ 16037 } 16038 } 16039 } 16040 16041 // Multi-user methods 16042 16043 @Override 16044 public boolean switchUser(final int userId) { 16045 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16046 != PackageManager.PERMISSION_GRANTED) { 16047 String msg = "Permission Denial: switchUser() from pid=" 16048 + Binder.getCallingPid() 16049 + ", uid=" + Binder.getCallingUid() 16050 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16051 Slog.w(TAG, msg); 16052 throw new SecurityException(msg); 16053 } 16054 16055 final long ident = Binder.clearCallingIdentity(); 16056 try { 16057 synchronized (this) { 16058 final int oldUserId = mCurrentUserId; 16059 if (oldUserId == userId) { 16060 return true; 16061 } 16062 16063 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16064 if (userInfo == null) { 16065 Slog.w(TAG, "No user info for user #" + userId); 16066 return false; 16067 } 16068 16069 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16070 R.anim.screen_user_enter); 16071 16072 boolean needStart = false; 16073 16074 // If the user we are switching to is not currently started, then 16075 // we need to start it now. 16076 if (mStartedUsers.get(userId) == null) { 16077 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16078 updateStartedUserArrayLocked(); 16079 needStart = true; 16080 } 16081 16082 mCurrentUserId = userId; 16083 final Integer userIdInt = Integer.valueOf(userId); 16084 mUserLru.remove(userIdInt); 16085 mUserLru.add(userIdInt); 16086 16087 mWindowManager.setCurrentUser(userId); 16088 16089 // Once the internal notion of the active user has switched, we lock the device 16090 // with the option to show the user switcher on the keyguard. 16091 mWindowManager.lockNow(null); 16092 16093 final UserStartedState uss = mStartedUsers.get(userId); 16094 16095 // Make sure user is in the started state. If it is currently 16096 // stopping, we need to knock that off. 16097 if (uss.mState == UserStartedState.STATE_STOPPING) { 16098 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16099 // so we can just fairly silently bring the user back from 16100 // the almost-dead. 16101 uss.mState = UserStartedState.STATE_RUNNING; 16102 updateStartedUserArrayLocked(); 16103 needStart = true; 16104 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16105 // This means ACTION_SHUTDOWN has been sent, so we will 16106 // need to treat this as a new boot of the user. 16107 uss.mState = UserStartedState.STATE_BOOTING; 16108 updateStartedUserArrayLocked(); 16109 needStart = true; 16110 } 16111 16112 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16113 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16114 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16115 oldUserId, userId, uss)); 16116 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16117 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16118 if (needStart) { 16119 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16120 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16121 | Intent.FLAG_RECEIVER_FOREGROUND); 16122 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16123 broadcastIntentLocked(null, null, intent, 16124 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16125 false, false, MY_PID, Process.SYSTEM_UID, userId); 16126 } 16127 16128 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16129 if (userId != 0) { 16130 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16131 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16132 broadcastIntentLocked(null, null, intent, null, 16133 new IIntentReceiver.Stub() { 16134 public void performReceive(Intent intent, int resultCode, 16135 String data, Bundle extras, boolean ordered, 16136 boolean sticky, int sendingUser) { 16137 userInitialized(uss, userId); 16138 } 16139 }, 0, null, null, null, AppOpsManager.OP_NONE, 16140 true, false, MY_PID, Process.SYSTEM_UID, 16141 userId); 16142 uss.initializing = true; 16143 } else { 16144 getUserManagerLocked().makeInitialized(userInfo.id); 16145 } 16146 } 16147 16148 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16149 if (homeInFront) { 16150 startHomeActivityLocked(userId); 16151 } else { 16152 mStackSupervisor.resumeTopActivitiesLocked(); 16153 } 16154 16155 EventLogTags.writeAmSwitchUser(userId); 16156 getUserManagerLocked().userForeground(userId); 16157 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16158 if (needStart) { 16159 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16160 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16161 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16162 broadcastIntentLocked(null, null, intent, 16163 null, new IIntentReceiver.Stub() { 16164 @Override 16165 public void performReceive(Intent intent, int resultCode, String data, 16166 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16167 throws RemoteException { 16168 } 16169 }, 0, null, null, 16170 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16171 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16172 } 16173 } 16174 } finally { 16175 Binder.restoreCallingIdentity(ident); 16176 } 16177 16178 return true; 16179 } 16180 16181 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16182 long ident = Binder.clearCallingIdentity(); 16183 try { 16184 Intent intent; 16185 if (oldUserId >= 0) { 16186 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16187 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16188 | Intent.FLAG_RECEIVER_FOREGROUND); 16189 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16190 broadcastIntentLocked(null, null, intent, 16191 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16192 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16193 } 16194 if (newUserId >= 0) { 16195 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16196 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16197 | Intent.FLAG_RECEIVER_FOREGROUND); 16198 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16199 broadcastIntentLocked(null, null, intent, 16200 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16201 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16202 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16203 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16204 | Intent.FLAG_RECEIVER_FOREGROUND); 16205 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16206 broadcastIntentLocked(null, null, intent, 16207 null, null, 0, null, null, 16208 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16209 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16210 } 16211 } finally { 16212 Binder.restoreCallingIdentity(ident); 16213 } 16214 } 16215 16216 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16217 final int newUserId) { 16218 final int N = mUserSwitchObservers.beginBroadcast(); 16219 if (N > 0) { 16220 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16221 int mCount = 0; 16222 @Override 16223 public void sendResult(Bundle data) throws RemoteException { 16224 synchronized (ActivityManagerService.this) { 16225 if (mCurUserSwitchCallback == this) { 16226 mCount++; 16227 if (mCount == N) { 16228 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16229 } 16230 } 16231 } 16232 } 16233 }; 16234 synchronized (this) { 16235 uss.switching = true; 16236 mCurUserSwitchCallback = callback; 16237 } 16238 for (int i=0; i<N; i++) { 16239 try { 16240 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16241 newUserId, callback); 16242 } catch (RemoteException e) { 16243 } 16244 } 16245 } else { 16246 synchronized (this) { 16247 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16248 } 16249 } 16250 mUserSwitchObservers.finishBroadcast(); 16251 } 16252 16253 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16254 synchronized (this) { 16255 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16256 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16257 } 16258 } 16259 16260 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16261 mCurUserSwitchCallback = null; 16262 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16263 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16264 oldUserId, newUserId, uss)); 16265 } 16266 16267 void userInitialized(UserStartedState uss, int newUserId) { 16268 completeSwitchAndInitalize(uss, newUserId, true, false); 16269 } 16270 16271 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16272 completeSwitchAndInitalize(uss, newUserId, false, true); 16273 } 16274 16275 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16276 boolean clearInitializing, boolean clearSwitching) { 16277 boolean unfrozen = false; 16278 synchronized (this) { 16279 if (clearInitializing) { 16280 uss.initializing = false; 16281 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16282 } 16283 if (clearSwitching) { 16284 uss.switching = false; 16285 } 16286 if (!uss.switching && !uss.initializing) { 16287 mWindowManager.stopFreezingScreen(); 16288 unfrozen = true; 16289 } 16290 } 16291 if (unfrozen) { 16292 final int N = mUserSwitchObservers.beginBroadcast(); 16293 for (int i=0; i<N; i++) { 16294 try { 16295 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16296 } catch (RemoteException e) { 16297 } 16298 } 16299 mUserSwitchObservers.finishBroadcast(); 16300 } 16301 } 16302 16303 void finishUserSwitch(UserStartedState uss) { 16304 synchronized (this) { 16305 if (uss.mState == UserStartedState.STATE_BOOTING 16306 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16307 uss.mState = UserStartedState.STATE_RUNNING; 16308 final int userId = uss.mHandle.getIdentifier(); 16309 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16310 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16311 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16312 broadcastIntentLocked(null, null, intent, 16313 null, null, 0, null, null, 16314 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16315 true, false, MY_PID, Process.SYSTEM_UID, userId); 16316 } 16317 int num = mUserLru.size(); 16318 int i = 0; 16319 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16320 Integer oldUserId = mUserLru.get(i); 16321 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16322 if (oldUss == null) { 16323 // Shouldn't happen, but be sane if it does. 16324 mUserLru.remove(i); 16325 num--; 16326 continue; 16327 } 16328 if (oldUss.mState == UserStartedState.STATE_STOPPING 16329 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16330 // This user is already stopping, doesn't count. 16331 num--; 16332 i++; 16333 continue; 16334 } 16335 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16336 // Owner and current can't be stopped, but count as running. 16337 i++; 16338 continue; 16339 } 16340 // This is a user to be stopped. 16341 stopUserLocked(oldUserId, null); 16342 num--; 16343 i++; 16344 } 16345 } 16346 } 16347 16348 @Override 16349 public int stopUser(final int userId, final IStopUserCallback callback) { 16350 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16351 != PackageManager.PERMISSION_GRANTED) { 16352 String msg = "Permission Denial: switchUser() from pid=" 16353 + Binder.getCallingPid() 16354 + ", uid=" + Binder.getCallingUid() 16355 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16356 Slog.w(TAG, msg); 16357 throw new SecurityException(msg); 16358 } 16359 if (userId <= 0) { 16360 throw new IllegalArgumentException("Can't stop primary user " + userId); 16361 } 16362 synchronized (this) { 16363 return stopUserLocked(userId, callback); 16364 } 16365 } 16366 16367 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16368 if (mCurrentUserId == userId) { 16369 return ActivityManager.USER_OP_IS_CURRENT; 16370 } 16371 16372 final UserStartedState uss = mStartedUsers.get(userId); 16373 if (uss == null) { 16374 // User is not started, nothing to do... but we do need to 16375 // callback if requested. 16376 if (callback != null) { 16377 mHandler.post(new Runnable() { 16378 @Override 16379 public void run() { 16380 try { 16381 callback.userStopped(userId); 16382 } catch (RemoteException e) { 16383 } 16384 } 16385 }); 16386 } 16387 return ActivityManager.USER_OP_SUCCESS; 16388 } 16389 16390 if (callback != null) { 16391 uss.mStopCallbacks.add(callback); 16392 } 16393 16394 if (uss.mState != UserStartedState.STATE_STOPPING 16395 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16396 uss.mState = UserStartedState.STATE_STOPPING; 16397 updateStartedUserArrayLocked(); 16398 16399 long ident = Binder.clearCallingIdentity(); 16400 try { 16401 // We are going to broadcast ACTION_USER_STOPPING and then 16402 // once that is done send a final ACTION_SHUTDOWN and then 16403 // stop the user. 16404 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16405 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16406 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16407 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16408 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16409 // This is the result receiver for the final shutdown broadcast. 16410 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16411 @Override 16412 public void performReceive(Intent intent, int resultCode, String data, 16413 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16414 finishUserStop(uss); 16415 } 16416 }; 16417 // This is the result receiver for the initial stopping broadcast. 16418 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16419 @Override 16420 public void performReceive(Intent intent, int resultCode, String data, 16421 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16422 // On to the next. 16423 synchronized (ActivityManagerService.this) { 16424 if (uss.mState != UserStartedState.STATE_STOPPING) { 16425 // Whoops, we are being started back up. Abort, abort! 16426 return; 16427 } 16428 uss.mState = UserStartedState.STATE_SHUTDOWN; 16429 } 16430 broadcastIntentLocked(null, null, shutdownIntent, 16431 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16432 true, false, MY_PID, Process.SYSTEM_UID, userId); 16433 } 16434 }; 16435 // Kick things off. 16436 broadcastIntentLocked(null, null, stoppingIntent, 16437 null, stoppingReceiver, 0, null, null, 16438 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16439 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16440 } finally { 16441 Binder.restoreCallingIdentity(ident); 16442 } 16443 } 16444 16445 return ActivityManager.USER_OP_SUCCESS; 16446 } 16447 16448 void finishUserStop(UserStartedState uss) { 16449 final int userId = uss.mHandle.getIdentifier(); 16450 boolean stopped; 16451 ArrayList<IStopUserCallback> callbacks; 16452 synchronized (this) { 16453 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16454 if (mStartedUsers.get(userId) != uss) { 16455 stopped = false; 16456 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16457 stopped = false; 16458 } else { 16459 stopped = true; 16460 // User can no longer run. 16461 mStartedUsers.remove(userId); 16462 mUserLru.remove(Integer.valueOf(userId)); 16463 updateStartedUserArrayLocked(); 16464 16465 // Clean up all state and processes associated with the user. 16466 // Kill all the processes for the user. 16467 forceStopUserLocked(userId, "finish user"); 16468 } 16469 } 16470 16471 for (int i=0; i<callbacks.size(); i++) { 16472 try { 16473 if (stopped) callbacks.get(i).userStopped(userId); 16474 else callbacks.get(i).userStopAborted(userId); 16475 } catch (RemoteException e) { 16476 } 16477 } 16478 16479 mStackSupervisor.removeUserLocked(userId); 16480 } 16481 16482 @Override 16483 public UserInfo getCurrentUser() { 16484 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16485 != PackageManager.PERMISSION_GRANTED) && ( 16486 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16487 != PackageManager.PERMISSION_GRANTED)) { 16488 String msg = "Permission Denial: getCurrentUser() from pid=" 16489 + Binder.getCallingPid() 16490 + ", uid=" + Binder.getCallingUid() 16491 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16492 Slog.w(TAG, msg); 16493 throw new SecurityException(msg); 16494 } 16495 synchronized (this) { 16496 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16497 } 16498 } 16499 16500 int getCurrentUserIdLocked() { 16501 return mCurrentUserId; 16502 } 16503 16504 @Override 16505 public boolean isUserRunning(int userId, boolean orStopped) { 16506 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16507 != PackageManager.PERMISSION_GRANTED) { 16508 String msg = "Permission Denial: isUserRunning() from pid=" 16509 + Binder.getCallingPid() 16510 + ", uid=" + Binder.getCallingUid() 16511 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16512 Slog.w(TAG, msg); 16513 throw new SecurityException(msg); 16514 } 16515 synchronized (this) { 16516 return isUserRunningLocked(userId, orStopped); 16517 } 16518 } 16519 16520 boolean isUserRunningLocked(int userId, boolean orStopped) { 16521 UserStartedState state = mStartedUsers.get(userId); 16522 if (state == null) { 16523 return false; 16524 } 16525 if (orStopped) { 16526 return true; 16527 } 16528 return state.mState != UserStartedState.STATE_STOPPING 16529 && state.mState != UserStartedState.STATE_SHUTDOWN; 16530 } 16531 16532 @Override 16533 public int[] getRunningUserIds() { 16534 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16535 != PackageManager.PERMISSION_GRANTED) { 16536 String msg = "Permission Denial: isUserRunning() from pid=" 16537 + Binder.getCallingPid() 16538 + ", uid=" + Binder.getCallingUid() 16539 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16540 Slog.w(TAG, msg); 16541 throw new SecurityException(msg); 16542 } 16543 synchronized (this) { 16544 return mStartedUserArray; 16545 } 16546 } 16547 16548 private void updateStartedUserArrayLocked() { 16549 int num = 0; 16550 for (int i=0; i<mStartedUsers.size(); i++) { 16551 UserStartedState uss = mStartedUsers.valueAt(i); 16552 // This list does not include stopping users. 16553 if (uss.mState != UserStartedState.STATE_STOPPING 16554 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16555 num++; 16556 } 16557 } 16558 mStartedUserArray = new int[num]; 16559 num = 0; 16560 for (int i=0; i<mStartedUsers.size(); i++) { 16561 UserStartedState uss = mStartedUsers.valueAt(i); 16562 if (uss.mState != UserStartedState.STATE_STOPPING 16563 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16564 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16565 num++; 16566 } 16567 } 16568 } 16569 16570 @Override 16571 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16572 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16573 != PackageManager.PERMISSION_GRANTED) { 16574 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16575 + Binder.getCallingPid() 16576 + ", uid=" + Binder.getCallingUid() 16577 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16578 Slog.w(TAG, msg); 16579 throw new SecurityException(msg); 16580 } 16581 16582 mUserSwitchObservers.register(observer); 16583 } 16584 16585 @Override 16586 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16587 mUserSwitchObservers.unregister(observer); 16588 } 16589 16590 private boolean userExists(int userId) { 16591 if (userId == 0) { 16592 return true; 16593 } 16594 UserManagerService ums = getUserManagerLocked(); 16595 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16596 } 16597 16598 int[] getUsersLocked() { 16599 UserManagerService ums = getUserManagerLocked(); 16600 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16601 } 16602 16603 UserManagerService getUserManagerLocked() { 16604 if (mUserManager == null) { 16605 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16606 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16607 } 16608 return mUserManager; 16609 } 16610 16611 private int applyUserId(int uid, int userId) { 16612 return UserHandle.getUid(userId, uid); 16613 } 16614 16615 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16616 if (info == null) return null; 16617 ApplicationInfo newInfo = new ApplicationInfo(info); 16618 newInfo.uid = applyUserId(info.uid, userId); 16619 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16620 + info.packageName; 16621 return newInfo; 16622 } 16623 16624 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16625 if (aInfo == null 16626 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16627 return aInfo; 16628 } 16629 16630 ActivityInfo info = new ActivityInfo(aInfo); 16631 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16632 return info; 16633 } 16634} 16635