ActivityManagerService.java revision 9158825f9c41869689d6b1786d7c7aa8bdd524ce
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20import static com.android.internal.util.XmlUtils.readIntAttribute; 21import static com.android.internal.util.XmlUtils.readLongAttribute; 22import static com.android.internal.util.XmlUtils.writeIntAttribute; 23import static com.android.internal.util.XmlUtils.writeLongAttribute; 24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 26import static org.xmlpull.v1.XmlPullParser.START_TAG; 27 28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 29 30import android.app.AppOpsManager; 31import android.app.IActivityContainer; 32import android.app.IActivityContainerCallback; 33import android.appwidget.AppWidgetManager; 34import android.graphics.Rect; 35import android.util.ArrayMap; 36import com.android.internal.R; 37import com.android.internal.annotations.GuardedBy; 38import com.android.internal.app.IAppOpsService; 39import com.android.internal.app.ProcessMap; 40import com.android.internal.app.ProcessStats; 41import com.android.internal.os.BackgroundThread; 42import com.android.internal.os.BatteryStatsImpl; 43import com.android.internal.os.ProcessCpuTracker; 44import com.android.internal.os.TransferPipe; 45import com.android.internal.util.FastPrintWriter; 46import com.android.internal.util.FastXmlSerializer; 47import com.android.internal.util.MemInfoReader; 48import com.android.internal.util.Preconditions; 49import com.android.server.AppOpsService; 50import com.android.server.AttributeCache; 51import com.android.server.IntentResolver; 52import com.android.server.SystemServer; 53import com.android.server.Watchdog; 54import com.android.server.am.ActivityStack.ActivityState; 55import com.android.server.firewall.IntentFirewall; 56import com.android.server.pm.UserManagerService; 57import com.android.server.wm.AppTransition; 58import com.android.server.wm.WindowManagerService; 59import com.google.android.collect.Lists; 60import com.google.android.collect.Maps; 61 62import dalvik.system.Zygote; 63 64import libcore.io.IoUtils; 65 66import org.xmlpull.v1.XmlPullParser; 67import org.xmlpull.v1.XmlPullParserException; 68import org.xmlpull.v1.XmlSerializer; 69 70import android.app.Activity; 71import android.app.ActivityManager; 72import android.app.ActivityManager.RunningTaskInfo; 73import android.app.ActivityManager.StackInfo; 74import android.app.ActivityManagerNative; 75import android.app.ActivityOptions; 76import android.app.ActivityThread; 77import android.app.AlertDialog; 78import android.app.AppGlobals; 79import android.app.ApplicationErrorReport; 80import android.app.Dialog; 81import android.app.IActivityController; 82import android.app.IApplicationThread; 83import android.app.IInstrumentationWatcher; 84import android.app.INotificationManager; 85import android.app.IProcessObserver; 86import android.app.IServiceConnection; 87import android.app.IStopUserCallback; 88import android.app.IThumbnailReceiver; 89import android.app.IUiAutomationConnection; 90import android.app.IUserSwitchObserver; 91import android.app.Instrumentation; 92import android.app.Notification; 93import android.app.NotificationManager; 94import android.app.PendingIntent; 95import android.app.backup.IBackupManager; 96import android.content.ActivityNotFoundException; 97import android.content.BroadcastReceiver; 98import android.content.ClipData; 99import android.content.ComponentCallbacks2; 100import android.content.ComponentName; 101import android.content.ContentProvider; 102import android.content.ContentResolver; 103import android.content.Context; 104import android.content.DialogInterface; 105import android.content.IContentProvider; 106import android.content.IIntentReceiver; 107import android.content.IIntentSender; 108import android.content.Intent; 109import android.content.IntentFilter; 110import android.content.IntentSender; 111import android.content.pm.ActivityInfo; 112import android.content.pm.ApplicationInfo; 113import android.content.pm.ConfigurationInfo; 114import android.content.pm.IPackageDataObserver; 115import android.content.pm.IPackageManager; 116import android.content.pm.InstrumentationInfo; 117import android.content.pm.PackageInfo; 118import android.content.pm.PackageManager; 119import android.content.pm.ParceledListSlice; 120import android.content.pm.UserInfo; 121import android.content.pm.PackageManager.NameNotFoundException; 122import android.content.pm.PathPermission; 123import android.content.pm.ProviderInfo; 124import android.content.pm.ResolveInfo; 125import android.content.pm.ServiceInfo; 126import android.content.res.CompatibilityInfo; 127import android.content.res.Configuration; 128import android.graphics.Bitmap; 129import android.net.Proxy; 130import android.net.ProxyProperties; 131import android.net.Uri; 132import android.os.Binder; 133import android.os.Build; 134import android.os.Bundle; 135import android.os.Debug; 136import android.os.DropBoxManager; 137import android.os.Environment; 138import android.os.FileObserver; 139import android.os.FileUtils; 140import android.os.Handler; 141import android.os.IBinder; 142import android.os.IPermissionController; 143import android.os.IRemoteCallback; 144import android.os.IUserManager; 145import android.os.Looper; 146import android.os.Message; 147import android.os.Parcel; 148import android.os.ParcelFileDescriptor; 149import android.os.Process; 150import android.os.RemoteCallbackList; 151import android.os.RemoteException; 152import android.os.SELinux; 153import android.os.ServiceManager; 154import android.os.StrictMode; 155import android.os.SystemClock; 156import android.os.SystemProperties; 157import android.os.UpdateLock; 158import android.os.UserHandle; 159import android.provider.Settings; 160import android.text.format.DateUtils; 161import android.text.format.Time; 162import android.util.AtomicFile; 163import android.util.EventLog; 164import android.util.Log; 165import android.util.Pair; 166import android.util.PrintWriterPrinter; 167import android.util.Slog; 168import android.util.SparseArray; 169import android.util.TimeUtils; 170import android.util.Xml; 171import android.view.Gravity; 172import android.view.LayoutInflater; 173import android.view.View; 174import android.view.WindowManager; 175 176import java.io.BufferedInputStream; 177import java.io.BufferedOutputStream; 178import java.io.DataInputStream; 179import java.io.DataOutputStream; 180import java.io.File; 181import java.io.FileDescriptor; 182import java.io.FileInputStream; 183import java.io.FileNotFoundException; 184import java.io.FileOutputStream; 185import java.io.IOException; 186import java.io.InputStreamReader; 187import java.io.PrintWriter; 188import java.io.StringWriter; 189import java.lang.ref.WeakReference; 190import java.util.ArrayList; 191import java.util.Arrays; 192import java.util.Collections; 193import java.util.Comparator; 194import java.util.HashMap; 195import java.util.HashSet; 196import java.util.Iterator; 197import java.util.List; 198import java.util.Locale; 199import java.util.Map; 200import java.util.Set; 201import java.util.concurrent.atomic.AtomicBoolean; 202import java.util.concurrent.atomic.AtomicLong; 203 204public final class ActivityManagerService extends ActivityManagerNative 205 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 206 private static final String USER_DATA_DIR = "/data/user/"; 207 static final String TAG = "ActivityManager"; 208 static final String TAG_MU = "ActivityManagerServiceMU"; 209 static final boolean DEBUG = false; 210 static final boolean localLOGV = DEBUG; 211 static final boolean DEBUG_BACKUP = localLOGV || false; 212 static final boolean DEBUG_BROADCAST = localLOGV || false; 213 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 214 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 215 static final boolean DEBUG_CLEANUP = localLOGV || false; 216 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 217 static final boolean DEBUG_FOCUS = false; 218 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 219 static final boolean DEBUG_MU = localLOGV || false; 220 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 221 static final boolean DEBUG_LRU = localLOGV || false; 222 static final boolean DEBUG_PAUSE = localLOGV || false; 223 static final boolean DEBUG_POWER = localLOGV || false; 224 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 225 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 226 static final boolean DEBUG_PROCESSES = localLOGV || false; 227 static final boolean DEBUG_PROVIDER = localLOGV || false; 228 static final boolean DEBUG_RESULTS = localLOGV || false; 229 static final boolean DEBUG_SERVICE = localLOGV || false; 230 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 231 static final boolean DEBUG_STACK = localLOGV || false; 232 static final boolean DEBUG_SWITCH = localLOGV || false; 233 static final boolean DEBUG_TASKS = localLOGV || false; 234 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 235 static final boolean DEBUG_TRANSITION = localLOGV || false; 236 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 237 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 238 static final boolean DEBUG_VISBILITY = localLOGV || false; 239 static final boolean DEBUG_PSS = localLOGV || false; 240 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 241 static final boolean VALIDATE_TOKENS = false; 242 static final boolean SHOW_ACTIVITY_START_TIME = true; 243 244 // Control over CPU and battery monitoring. 245 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 246 static final boolean MONITOR_CPU_USAGE = true; 247 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 248 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 249 static final boolean MONITOR_THREAD_CPU_USAGE = false; 250 251 // The flags that are set for all calls we make to the package manager. 252 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 253 254 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 255 256 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 257 258 // Maximum number of recent tasks that we can remember. 259 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 260 261 // Amount of time after a call to stopAppSwitches() during which we will 262 // prevent further untrusted switches from happening. 263 static final long APP_SWITCH_DELAY_TIME = 5*1000; 264 265 // How long we wait for a launched process to attach to the activity manager 266 // before we decide it's never going to come up for real. 267 static final int PROC_START_TIMEOUT = 10*1000; 268 269 // How long we wait for a launched process to attach to the activity manager 270 // before we decide it's never going to come up for real, when the process was 271 // started with a wrapper for instrumentation (such as Valgrind) because it 272 // could take much longer than usual. 273 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 274 275 // How long to wait after going idle before forcing apps to GC. 276 static final int GC_TIMEOUT = 5*1000; 277 278 // The minimum amount of time between successive GC requests for a process. 279 static final int GC_MIN_INTERVAL = 60*1000; 280 281 // The minimum amount of time between successive PSS requests for a process. 282 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 283 284 // The minimum amount of time between successive PSS requests for a process 285 // when the request is due to the memory state being lowered. 286 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 287 288 // The rate at which we check for apps using excessive power -- 15 mins. 289 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 290 291 // The minimum sample duration we will allow before deciding we have 292 // enough data on wake locks to start killing things. 293 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 294 295 // The minimum sample duration we will allow before deciding we have 296 // enough data on CPU usage to start killing things. 297 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 298 299 // How long we allow a receiver to run before giving up on it. 300 static final int BROADCAST_FG_TIMEOUT = 10*1000; 301 static final int BROADCAST_BG_TIMEOUT = 60*1000; 302 303 // How long we wait until we timeout on key dispatching. 304 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 305 306 // How long we wait until we timeout on key dispatching during instrumentation. 307 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 308 309 // Amount of time we wait for observers to handle a user switch before 310 // giving up on them and unfreezing the screen. 311 static final int USER_SWITCH_TIMEOUT = 2*1000; 312 313 // Maximum number of users we allow to be running at a time. 314 static final int MAX_RUNNING_USERS = 3; 315 316 // How long to wait in getAssistContextExtras for the activity and foreground services 317 // to respond with the result. 318 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 319 320 // Maximum number of persisted Uri grants a package is allowed 321 static final int MAX_PERSISTED_URI_GRANTS = 128; 322 323 static final int MY_PID = Process.myPid(); 324 325 static final String[] EMPTY_STRING_ARRAY = new String[0]; 326 327 // How many bytes to write into the dropbox log before truncating 328 static final int DROPBOX_MAX_SIZE = 256 * 1024; 329 330 /** Run all ActivityStacks through this */ 331 ActivityStackSupervisor mStackSupervisor; 332 333 public IntentFirewall mIntentFirewall; 334 335 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 336 // default actuion automatically. Important for devices without direct input 337 // devices. 338 private boolean mShowDialogs = true; 339 340 /** 341 * Description of a request to start a new activity, which has been held 342 * due to app switches being disabled. 343 */ 344 static class PendingActivityLaunch { 345 final ActivityRecord r; 346 final ActivityRecord sourceRecord; 347 final int startFlags; 348 final ActivityStack stack; 349 350 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 351 int _startFlags, ActivityStack _stack) { 352 r = _r; 353 sourceRecord = _sourceRecord; 354 startFlags = _startFlags; 355 stack = _stack; 356 } 357 } 358 359 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 360 = new ArrayList<PendingActivityLaunch>(); 361 362 BroadcastQueue mFgBroadcastQueue; 363 BroadcastQueue mBgBroadcastQueue; 364 // Convenient for easy iteration over the queues. Foreground is first 365 // so that dispatch of foreground broadcasts gets precedence. 366 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 367 368 BroadcastQueue broadcastQueueForIntent(Intent intent) { 369 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 370 if (DEBUG_BACKGROUND_BROADCAST) { 371 Slog.i(TAG, "Broadcast intent " + intent + " on " 372 + (isFg ? "foreground" : "background") 373 + " queue"); 374 } 375 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 376 } 377 378 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 379 for (BroadcastQueue queue : mBroadcastQueues) { 380 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 381 if (r != null) { 382 return r; 383 } 384 } 385 return null; 386 } 387 388 /** 389 * Activity we have told the window manager to have key focus. 390 */ 391 ActivityRecord mFocusedActivity = null; 392 393 /** 394 * List of intents that were used to start the most recent tasks. 395 */ 396 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 397 398 public class PendingAssistExtras extends Binder implements Runnable { 399 public final ActivityRecord activity; 400 public boolean haveResult = false; 401 public Bundle result = null; 402 public PendingAssistExtras(ActivityRecord _activity) { 403 activity = _activity; 404 } 405 @Override 406 public void run() { 407 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 408 synchronized (this) { 409 haveResult = true; 410 notifyAll(); 411 } 412 } 413 } 414 415 final ArrayList<PendingAssistExtras> mPendingAssistExtras 416 = new ArrayList<PendingAssistExtras>(); 417 418 /** 419 * Process management. 420 */ 421 final ProcessList mProcessList = new ProcessList(); 422 423 /** 424 * All of the applications we currently have running organized by name. 425 * The keys are strings of the application package name (as 426 * returned by the package manager), and the keys are ApplicationRecord 427 * objects. 428 */ 429 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 430 431 /** 432 * Tracking long-term execution of processes to look for abuse and other 433 * bad app behavior. 434 */ 435 final ProcessStatsService mProcessStats; 436 437 /** 438 * The currently running isolated processes. 439 */ 440 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 441 442 /** 443 * Counter for assigning isolated process uids, to avoid frequently reusing the 444 * same ones. 445 */ 446 int mNextIsolatedProcessUid = 0; 447 448 /** 449 * The currently running heavy-weight process, if any. 450 */ 451 ProcessRecord mHeavyWeightProcess = null; 452 453 /** 454 * The last time that various processes have crashed. 455 */ 456 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 457 458 /** 459 * Information about a process that is currently marked as bad. 460 */ 461 static final class BadProcessInfo { 462 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 463 this.time = time; 464 this.shortMsg = shortMsg; 465 this.longMsg = longMsg; 466 this.stack = stack; 467 } 468 469 final long time; 470 final String shortMsg; 471 final String longMsg; 472 final String stack; 473 } 474 475 /** 476 * Set of applications that we consider to be bad, and will reject 477 * incoming broadcasts from (which the user has no control over). 478 * Processes are added to this set when they have crashed twice within 479 * a minimum amount of time; they are removed from it when they are 480 * later restarted (hopefully due to some user action). The value is the 481 * time it was added to the list. 482 */ 483 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 484 485 /** 486 * All of the processes we currently have running organized by pid. 487 * The keys are the pid running the application. 488 * 489 * <p>NOTE: This object is protected by its own lock, NOT the global 490 * activity manager lock! 491 */ 492 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 493 494 /** 495 * All of the processes that have been forced to be foreground. The key 496 * is the pid of the caller who requested it (we hold a death 497 * link on it). 498 */ 499 abstract class ForegroundToken implements IBinder.DeathRecipient { 500 int pid; 501 IBinder token; 502 } 503 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 504 505 /** 506 * List of records for processes that someone had tried to start before the 507 * system was ready. We don't start them at that point, but ensure they 508 * are started by the time booting is complete. 509 */ 510 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 511 512 /** 513 * List of persistent applications that are in the process 514 * of being started. 515 */ 516 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 517 518 /** 519 * Processes that are being forcibly torn down. 520 */ 521 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 522 523 /** 524 * List of running applications, sorted by recent usage. 525 * The first entry in the list is the least recently used. 526 */ 527 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 528 529 /** 530 * Where in mLruProcesses that the processes hosting activities start. 531 */ 532 int mLruProcessActivityStart = 0; 533 534 /** 535 * Where in mLruProcesses that the processes hosting services start. 536 * This is after (lower index) than mLruProcessesActivityStart. 537 */ 538 int mLruProcessServiceStart = 0; 539 540 /** 541 * List of processes that should gc as soon as things are idle. 542 */ 543 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 544 545 /** 546 * Processes we want to collect PSS data from. 547 */ 548 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 549 550 /** 551 * Last time we requested PSS data of all processes. 552 */ 553 long mLastFullPssTime = SystemClock.uptimeMillis(); 554 555 /** 556 * This is the process holding what we currently consider to be 557 * the "home" activity. 558 */ 559 ProcessRecord mHomeProcess; 560 561 /** 562 * This is the process holding the activity the user last visited that 563 * is in a different process from the one they are currently in. 564 */ 565 ProcessRecord mPreviousProcess; 566 567 /** 568 * The time at which the previous process was last visible. 569 */ 570 long mPreviousProcessVisibleTime; 571 572 /** 573 * Which uses have been started, so are allowed to run code. 574 */ 575 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 576 577 /** 578 * LRU list of history of current users. Most recently current is at the end. 579 */ 580 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 581 582 /** 583 * Constant array of the users that are currently started. 584 */ 585 int[] mStartedUserArray = new int[] { 0 }; 586 587 /** 588 * Registered observers of the user switching mechanics. 589 */ 590 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 591 = new RemoteCallbackList<IUserSwitchObserver>(); 592 593 /** 594 * Currently active user switch. 595 */ 596 Object mCurUserSwitchCallback; 597 598 /** 599 * Packages that the user has asked to have run in screen size 600 * compatibility mode instead of filling the screen. 601 */ 602 final CompatModePackages mCompatModePackages; 603 604 /** 605 * Set of IntentSenderRecord objects that are currently active. 606 */ 607 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 608 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 609 610 /** 611 * Fingerprints (hashCode()) of stack traces that we've 612 * already logged DropBox entries for. Guarded by itself. If 613 * something (rogue user app) forces this over 614 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 615 */ 616 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 617 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 618 619 /** 620 * Strict Mode background batched logging state. 621 * 622 * The string buffer is guarded by itself, and its lock is also 623 * used to determine if another batched write is already 624 * in-flight. 625 */ 626 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 627 628 /** 629 * Keeps track of all IIntentReceivers that have been registered for 630 * broadcasts. Hash keys are the receiver IBinder, hash value is 631 * a ReceiverList. 632 */ 633 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 634 new HashMap<IBinder, ReceiverList>(); 635 636 /** 637 * Resolver for broadcast intents to registered receivers. 638 * Holds BroadcastFilter (subclass of IntentFilter). 639 */ 640 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 641 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 642 @Override 643 protected boolean allowFilterResult( 644 BroadcastFilter filter, List<BroadcastFilter> dest) { 645 IBinder target = filter.receiverList.receiver.asBinder(); 646 for (int i=dest.size()-1; i>=0; i--) { 647 if (dest.get(i).receiverList.receiver.asBinder() == target) { 648 return false; 649 } 650 } 651 return true; 652 } 653 654 @Override 655 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 656 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 657 || userId == filter.owningUserId) { 658 return super.newResult(filter, match, userId); 659 } 660 return null; 661 } 662 663 @Override 664 protected BroadcastFilter[] newArray(int size) { 665 return new BroadcastFilter[size]; 666 } 667 668 @Override 669 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 670 return packageName.equals(filter.packageName); 671 } 672 }; 673 674 /** 675 * State of all active sticky broadcasts per user. Keys are the action of the 676 * sticky Intent, values are an ArrayList of all broadcasted intents with 677 * that action (which should usually be one). The SparseArray is keyed 678 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 679 * for stickies that are sent to all users. 680 */ 681 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 682 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 683 684 final ActiveServices mServices; 685 686 /** 687 * Backup/restore process management 688 */ 689 String mBackupAppName = null; 690 BackupRecord mBackupTarget = null; 691 692 /** 693 * List of PendingThumbnailsRecord objects of clients who are still 694 * waiting to receive all of the thumbnails for a task. 695 */ 696 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 697 new ArrayList<PendingThumbnailsRecord>(); 698 699 final ProviderMap mProviderMap; 700 701 /** 702 * List of content providers who have clients waiting for them. The 703 * application is currently being launched and the provider will be 704 * removed from this list once it is published. 705 */ 706 final ArrayList<ContentProviderRecord> mLaunchingProviders 707 = new ArrayList<ContentProviderRecord>(); 708 709 /** 710 * File storing persisted {@link #mGrantedUriPermissions}. 711 */ 712 private final AtomicFile mGrantFile; 713 714 /** XML constants used in {@link #mGrantFile} */ 715 private static final String TAG_URI_GRANTS = "uri-grants"; 716 private static final String TAG_URI_GRANT = "uri-grant"; 717 private static final String ATTR_USER_HANDLE = "userHandle"; 718 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 719 private static final String ATTR_TARGET_PKG = "targetPkg"; 720 private static final String ATTR_URI = "uri"; 721 private static final String ATTR_MODE_FLAGS = "modeFlags"; 722 private static final String ATTR_CREATED_TIME = "createdTime"; 723 724 /** 725 * Global set of specific {@link Uri} permissions that have been granted. 726 * This optimized lookup structure maps from {@link UriPermission#targetUid} 727 * to {@link UriPermission#uri} to {@link UriPermission}. 728 */ 729 @GuardedBy("this") 730 private final SparseArray<ArrayMap<Uri, UriPermission>> 731 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 732 733 CoreSettingsObserver mCoreSettingsObserver; 734 735 /** 736 * Thread-local storage used to carry caller permissions over through 737 * indirect content-provider access. 738 */ 739 private class Identity { 740 public int pid; 741 public int uid; 742 743 Identity(int _pid, int _uid) { 744 pid = _pid; 745 uid = _uid; 746 } 747 } 748 749 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 750 751 /** 752 * All information we have collected about the runtime performance of 753 * any user id that can impact battery performance. 754 */ 755 final BatteryStatsService mBatteryStatsService; 756 757 /** 758 * Information about component usage 759 */ 760 final UsageStatsService mUsageStatsService; 761 762 /** 763 * Information about and control over application operations 764 */ 765 final AppOpsService mAppOpsService; 766 767 /** 768 * Current configuration information. HistoryRecord objects are given 769 * a reference to this object to indicate which configuration they are 770 * currently running in, so this object must be kept immutable. 771 */ 772 Configuration mConfiguration = new Configuration(); 773 774 /** 775 * Current sequencing integer of the configuration, for skipping old 776 * configurations. 777 */ 778 int mConfigurationSeq = 0; 779 780 /** 781 * Hardware-reported OpenGLES version. 782 */ 783 final int GL_ES_VERSION; 784 785 /** 786 * List of initialization arguments to pass to all processes when binding applications to them. 787 * For example, references to the commonly used services. 788 */ 789 HashMap<String, IBinder> mAppBindArgs; 790 791 /** 792 * Temporary to avoid allocations. Protected by main lock. 793 */ 794 final StringBuilder mStringBuilder = new StringBuilder(256); 795 796 /** 797 * Used to control how we initialize the service. 798 */ 799 boolean mStartRunning = false; 800 ComponentName mTopComponent; 801 String mTopAction; 802 String mTopData; 803 boolean mProcessesReady = false; 804 boolean mSystemReady = false; 805 boolean mBooting = false; 806 boolean mWaitingUpdate = false; 807 boolean mDidUpdate = false; 808 boolean mOnBattery = false; 809 boolean mLaunchWarningShown = false; 810 811 Context mContext; 812 813 int mFactoryTest; 814 815 boolean mCheckedForSetup; 816 817 /** 818 * The time at which we will allow normal application switches again, 819 * after a call to {@link #stopAppSwitches()}. 820 */ 821 long mAppSwitchesAllowedTime; 822 823 /** 824 * This is set to true after the first switch after mAppSwitchesAllowedTime 825 * is set; any switches after that will clear the time. 826 */ 827 boolean mDidAppSwitch; 828 829 /** 830 * Last time (in realtime) at which we checked for power usage. 831 */ 832 long mLastPowerCheckRealtime; 833 834 /** 835 * Last time (in uptime) at which we checked for power usage. 836 */ 837 long mLastPowerCheckUptime; 838 839 /** 840 * Set while we are wanting to sleep, to prevent any 841 * activities from being started/resumed. 842 */ 843 boolean mSleeping = false; 844 845 /** 846 * State of external calls telling us if the device is asleep. 847 */ 848 boolean mWentToSleep = false; 849 850 /** 851 * State of external call telling us if the lock screen is shown. 852 */ 853 boolean mLockScreenShown = false; 854 855 /** 856 * Set if we are shutting down the system, similar to sleeping. 857 */ 858 boolean mShuttingDown = false; 859 860 /** 861 * Current sequence id for oom_adj computation traversal. 862 */ 863 int mAdjSeq = 0; 864 865 /** 866 * Current sequence id for process LRU updating. 867 */ 868 int mLruSeq = 0; 869 870 /** 871 * Keep track of the non-cached/empty process we last found, to help 872 * determine how to distribute cached/empty processes next time. 873 */ 874 int mNumNonCachedProcs = 0; 875 876 /** 877 * Keep track of the number of cached hidden procs, to balance oom adj 878 * distribution between those and empty procs. 879 */ 880 int mNumCachedHiddenProcs = 0; 881 882 /** 883 * Keep track of the number of service processes we last found, to 884 * determine on the next iteration which should be B services. 885 */ 886 int mNumServiceProcs = 0; 887 int mNewNumAServiceProcs = 0; 888 int mNewNumServiceProcs = 0; 889 890 /** 891 * Allow the current computed overall memory level of the system to go down? 892 * This is set to false when we are killing processes for reasons other than 893 * memory management, so that the now smaller process list will not be taken as 894 * an indication that memory is tighter. 895 */ 896 boolean mAllowLowerMemLevel = false; 897 898 /** 899 * The last computed memory level, for holding when we are in a state that 900 * processes are going away for other reasons. 901 */ 902 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 903 904 /** 905 * The last total number of process we have, to determine if changes actually look 906 * like a shrinking number of process due to lower RAM. 907 */ 908 int mLastNumProcesses; 909 910 /** 911 * The uptime of the last time we performed idle maintenance. 912 */ 913 long mLastIdleTime = SystemClock.uptimeMillis(); 914 915 /** 916 * Total time spent with RAM that has been added in the past since the last idle time. 917 */ 918 long mLowRamTimeSinceLastIdle = 0; 919 920 /** 921 * If RAM is currently low, when that horrible situatin started. 922 */ 923 long mLowRamStartTime = 0; 924 925 /** 926 * This is set if we had to do a delayed dexopt of an app before launching 927 * it, to increasing the ANR timeouts in that case. 928 */ 929 boolean mDidDexOpt; 930 931 String mDebugApp = null; 932 boolean mWaitForDebugger = false; 933 boolean mDebugTransient = false; 934 String mOrigDebugApp = null; 935 boolean mOrigWaitForDebugger = false; 936 boolean mAlwaysFinishActivities = false; 937 IActivityController mController = null; 938 String mProfileApp = null; 939 ProcessRecord mProfileProc = null; 940 String mProfileFile; 941 ParcelFileDescriptor mProfileFd; 942 int mProfileType = 0; 943 boolean mAutoStopProfiler = false; 944 String mOpenGlTraceApp = null; 945 946 static class ProcessChangeItem { 947 static final int CHANGE_ACTIVITIES = 1<<0; 948 static final int CHANGE_IMPORTANCE= 1<<1; 949 int changes; 950 int uid; 951 int pid; 952 int importance; 953 boolean foregroundActivities; 954 } 955 956 final RemoteCallbackList<IProcessObserver> mProcessObservers 957 = new RemoteCallbackList<IProcessObserver>(); 958 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 959 960 final ArrayList<ProcessChangeItem> mPendingProcessChanges 961 = new ArrayList<ProcessChangeItem>(); 962 final ArrayList<ProcessChangeItem> mAvailProcessChanges 963 = new ArrayList<ProcessChangeItem>(); 964 965 /** 966 * Runtime CPU use collection thread. This object's lock is used to 967 * protect all related state. 968 */ 969 final Thread mProcessCpuThread; 970 971 /** 972 * Used to collect process stats when showing not responding dialog. 973 * Protected by mProcessCpuThread. 974 */ 975 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 976 MONITOR_THREAD_CPU_USAGE); 977 final AtomicLong mLastCpuTime = new AtomicLong(0); 978 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 979 980 long mLastWriteTime = 0; 981 982 /** 983 * Used to retain an update lock when the foreground activity is in 984 * immersive mode. 985 */ 986 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 987 988 /** 989 * Set to true after the system has finished booting. 990 */ 991 boolean mBooted = false; 992 993 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 994 int mProcessLimitOverride = -1; 995 996 WindowManagerService mWindowManager; 997 998 static ActivityManagerService mSelf; 999 static ActivityThread mSystemThread; 1000 1001 int mCurrentUserId = 0; 1002 private UserManagerService mUserManager; 1003 1004 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1005 final ProcessRecord mApp; 1006 final int mPid; 1007 final IApplicationThread mAppThread; 1008 1009 AppDeathRecipient(ProcessRecord app, int pid, 1010 IApplicationThread thread) { 1011 if (localLOGV) Slog.v( 1012 TAG, "New death recipient " + this 1013 + " for thread " + thread.asBinder()); 1014 mApp = app; 1015 mPid = pid; 1016 mAppThread = thread; 1017 } 1018 1019 @Override 1020 public void binderDied() { 1021 if (localLOGV) Slog.v( 1022 TAG, "Death received in " + this 1023 + " for thread " + mAppThread.asBinder()); 1024 synchronized(ActivityManagerService.this) { 1025 appDiedLocked(mApp, mPid, mAppThread); 1026 } 1027 } 1028 } 1029 1030 static final int SHOW_ERROR_MSG = 1; 1031 static final int SHOW_NOT_RESPONDING_MSG = 2; 1032 static final int SHOW_FACTORY_ERROR_MSG = 3; 1033 static final int UPDATE_CONFIGURATION_MSG = 4; 1034 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1035 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1036 static final int SERVICE_TIMEOUT_MSG = 12; 1037 static final int UPDATE_TIME_ZONE = 13; 1038 static final int SHOW_UID_ERROR_MSG = 14; 1039 static final int IM_FEELING_LUCKY_MSG = 15; 1040 static final int PROC_START_TIMEOUT_MSG = 20; 1041 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1042 static final int KILL_APPLICATION_MSG = 22; 1043 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1044 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1045 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1046 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1047 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1048 static final int CLEAR_DNS_CACHE_MSG = 28; 1049 static final int UPDATE_HTTP_PROXY_MSG = 29; 1050 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1051 static final int DISPATCH_PROCESSES_CHANGED = 31; 1052 static final int DISPATCH_PROCESS_DIED = 32; 1053 static final int REPORT_MEM_USAGE_MSG = 33; 1054 static final int REPORT_USER_SWITCH_MSG = 34; 1055 static final int CONTINUE_USER_SWITCH_MSG = 35; 1056 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1057 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1058 static final int PERSIST_URI_GRANTS_MSG = 38; 1059 static final int REQUEST_ALL_PSS_MSG = 39; 1060 1061 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1062 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1063 static final int FIRST_COMPAT_MODE_MSG = 300; 1064 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1065 1066 AlertDialog mUidAlert; 1067 CompatModeDialog mCompatModeDialog; 1068 long mLastMemUsageReportTime = 0; 1069 1070 /** 1071 * Flag whether the current user is a "monkey", i.e. whether 1072 * the UI is driven by a UI automation tool. 1073 */ 1074 private boolean mUserIsMonkey; 1075 1076 final Handler mHandler = new Handler() { 1077 //public Handler() { 1078 // if (localLOGV) Slog.v(TAG, "Handler started!"); 1079 //} 1080 1081 @Override 1082 public void handleMessage(Message msg) { 1083 switch (msg.what) { 1084 case SHOW_ERROR_MSG: { 1085 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1086 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1087 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1088 synchronized (ActivityManagerService.this) { 1089 ProcessRecord proc = (ProcessRecord)data.get("app"); 1090 AppErrorResult res = (AppErrorResult) data.get("result"); 1091 if (proc != null && proc.crashDialog != null) { 1092 Slog.e(TAG, "App already has crash dialog: " + proc); 1093 if (res != null) { 1094 res.set(0); 1095 } 1096 return; 1097 } 1098 if (!showBackground && UserHandle.getAppId(proc.uid) 1099 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1100 && proc.pid != MY_PID) { 1101 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1102 if (res != null) { 1103 res.set(0); 1104 } 1105 return; 1106 } 1107 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1108 Dialog d = new AppErrorDialog(mContext, 1109 ActivityManagerService.this, res, proc); 1110 d.show(); 1111 proc.crashDialog = d; 1112 } else { 1113 // The device is asleep, so just pretend that the user 1114 // saw a crash dialog and hit "force quit". 1115 if (res != null) { 1116 res.set(0); 1117 } 1118 } 1119 } 1120 1121 ensureBootCompleted(); 1122 } break; 1123 case SHOW_NOT_RESPONDING_MSG: { 1124 synchronized (ActivityManagerService.this) { 1125 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1126 ProcessRecord proc = (ProcessRecord)data.get("app"); 1127 if (proc != null && proc.anrDialog != null) { 1128 Slog.e(TAG, "App already has anr dialog: " + proc); 1129 return; 1130 } 1131 1132 Intent intent = new Intent("android.intent.action.ANR"); 1133 if (!mProcessesReady) { 1134 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1135 | Intent.FLAG_RECEIVER_FOREGROUND); 1136 } 1137 broadcastIntentLocked(null, null, intent, 1138 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1139 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1140 1141 if (mShowDialogs) { 1142 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1143 mContext, proc, (ActivityRecord)data.get("activity"), 1144 msg.arg1 != 0); 1145 d.show(); 1146 proc.anrDialog = d; 1147 } else { 1148 // Just kill the app if there is no dialog to be shown. 1149 killAppAtUsersRequest(proc, null); 1150 } 1151 } 1152 1153 ensureBootCompleted(); 1154 } break; 1155 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1156 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1157 synchronized (ActivityManagerService.this) { 1158 ProcessRecord proc = (ProcessRecord) data.get("app"); 1159 if (proc == null) { 1160 Slog.e(TAG, "App not found when showing strict mode dialog."); 1161 break; 1162 } 1163 if (proc.crashDialog != null) { 1164 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1165 return; 1166 } 1167 AppErrorResult res = (AppErrorResult) data.get("result"); 1168 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1169 Dialog d = new StrictModeViolationDialog(mContext, 1170 ActivityManagerService.this, res, proc); 1171 d.show(); 1172 proc.crashDialog = d; 1173 } else { 1174 // The device is asleep, so just pretend that the user 1175 // saw a crash dialog and hit "force quit". 1176 res.set(0); 1177 } 1178 } 1179 ensureBootCompleted(); 1180 } break; 1181 case SHOW_FACTORY_ERROR_MSG: { 1182 Dialog d = new FactoryErrorDialog( 1183 mContext, msg.getData().getCharSequence("msg")); 1184 d.show(); 1185 ensureBootCompleted(); 1186 } break; 1187 case UPDATE_CONFIGURATION_MSG: { 1188 final ContentResolver resolver = mContext.getContentResolver(); 1189 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1190 } break; 1191 case GC_BACKGROUND_PROCESSES_MSG: { 1192 synchronized (ActivityManagerService.this) { 1193 performAppGcsIfAppropriateLocked(); 1194 } 1195 } break; 1196 case WAIT_FOR_DEBUGGER_MSG: { 1197 synchronized (ActivityManagerService.this) { 1198 ProcessRecord app = (ProcessRecord)msg.obj; 1199 if (msg.arg1 != 0) { 1200 if (!app.waitedForDebugger) { 1201 Dialog d = new AppWaitingForDebuggerDialog( 1202 ActivityManagerService.this, 1203 mContext, app); 1204 app.waitDialog = d; 1205 app.waitedForDebugger = true; 1206 d.show(); 1207 } 1208 } else { 1209 if (app.waitDialog != null) { 1210 app.waitDialog.dismiss(); 1211 app.waitDialog = null; 1212 } 1213 } 1214 } 1215 } break; 1216 case SERVICE_TIMEOUT_MSG: { 1217 if (mDidDexOpt) { 1218 mDidDexOpt = false; 1219 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1220 nmsg.obj = msg.obj; 1221 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1222 return; 1223 } 1224 mServices.serviceTimeout((ProcessRecord)msg.obj); 1225 } break; 1226 case UPDATE_TIME_ZONE: { 1227 synchronized (ActivityManagerService.this) { 1228 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1229 ProcessRecord r = mLruProcesses.get(i); 1230 if (r.thread != null) { 1231 try { 1232 r.thread.updateTimeZone(); 1233 } catch (RemoteException ex) { 1234 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1235 } 1236 } 1237 } 1238 } 1239 } break; 1240 case CLEAR_DNS_CACHE_MSG: { 1241 synchronized (ActivityManagerService.this) { 1242 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1243 ProcessRecord r = mLruProcesses.get(i); 1244 if (r.thread != null) { 1245 try { 1246 r.thread.clearDnsCache(); 1247 } catch (RemoteException ex) { 1248 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1249 } 1250 } 1251 } 1252 } 1253 } break; 1254 case UPDATE_HTTP_PROXY_MSG: { 1255 ProxyProperties proxy = (ProxyProperties)msg.obj; 1256 String host = ""; 1257 String port = ""; 1258 String exclList = ""; 1259 String pacFileUrl = null; 1260 if (proxy != null) { 1261 host = proxy.getHost(); 1262 port = Integer.toString(proxy.getPort()); 1263 exclList = proxy.getExclusionList(); 1264 pacFileUrl = proxy.getPacFileUrl(); 1265 } 1266 synchronized (ActivityManagerService.this) { 1267 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1268 ProcessRecord r = mLruProcesses.get(i); 1269 if (r.thread != null) { 1270 try { 1271 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1272 } catch (RemoteException ex) { 1273 Slog.w(TAG, "Failed to update http proxy for: " + 1274 r.info.processName); 1275 } 1276 } 1277 } 1278 } 1279 } break; 1280 case SHOW_UID_ERROR_MSG: { 1281 String title = "System UIDs Inconsistent"; 1282 String text = "UIDs on the system are inconsistent, you need to wipe your" 1283 + " data partition or your device will be unstable."; 1284 Log.e(TAG, title + ": " + text); 1285 if (mShowDialogs) { 1286 // XXX This is a temporary dialog, no need to localize. 1287 AlertDialog d = new BaseErrorDialog(mContext); 1288 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1289 d.setCancelable(false); 1290 d.setTitle(title); 1291 d.setMessage(text); 1292 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1293 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1294 mUidAlert = d; 1295 d.show(); 1296 } 1297 } break; 1298 case IM_FEELING_LUCKY_MSG: { 1299 if (mUidAlert != null) { 1300 mUidAlert.dismiss(); 1301 mUidAlert = null; 1302 } 1303 } break; 1304 case PROC_START_TIMEOUT_MSG: { 1305 if (mDidDexOpt) { 1306 mDidDexOpt = false; 1307 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1308 nmsg.obj = msg.obj; 1309 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1310 return; 1311 } 1312 ProcessRecord app = (ProcessRecord)msg.obj; 1313 synchronized (ActivityManagerService.this) { 1314 processStartTimedOutLocked(app); 1315 } 1316 } break; 1317 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1318 synchronized (ActivityManagerService.this) { 1319 doPendingActivityLaunchesLocked(true); 1320 } 1321 } break; 1322 case KILL_APPLICATION_MSG: { 1323 synchronized (ActivityManagerService.this) { 1324 int appid = msg.arg1; 1325 boolean restart = (msg.arg2 == 1); 1326 Bundle bundle = (Bundle)msg.obj; 1327 String pkg = bundle.getString("pkg"); 1328 String reason = bundle.getString("reason"); 1329 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1330 UserHandle.USER_ALL, reason); 1331 } 1332 } break; 1333 case FINALIZE_PENDING_INTENT_MSG: { 1334 ((PendingIntentRecord)msg.obj).completeFinalize(); 1335 } break; 1336 case POST_HEAVY_NOTIFICATION_MSG: { 1337 INotificationManager inm = NotificationManager.getService(); 1338 if (inm == null) { 1339 return; 1340 } 1341 1342 ActivityRecord root = (ActivityRecord)msg.obj; 1343 ProcessRecord process = root.app; 1344 if (process == null) { 1345 return; 1346 } 1347 1348 try { 1349 Context context = mContext.createPackageContext(process.info.packageName, 0); 1350 String text = mContext.getString(R.string.heavy_weight_notification, 1351 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1352 Notification notification = new Notification(); 1353 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1354 notification.when = 0; 1355 notification.flags = Notification.FLAG_ONGOING_EVENT; 1356 notification.tickerText = text; 1357 notification.defaults = 0; // please be quiet 1358 notification.sound = null; 1359 notification.vibrate = null; 1360 notification.setLatestEventInfo(context, text, 1361 mContext.getText(R.string.heavy_weight_notification_detail), 1362 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1363 PendingIntent.FLAG_CANCEL_CURRENT, null, 1364 new UserHandle(root.userId))); 1365 1366 try { 1367 int[] outId = new int[1]; 1368 inm.enqueueNotificationWithTag("android", "android", null, 1369 R.string.heavy_weight_notification, 1370 notification, outId, root.userId); 1371 } catch (RuntimeException e) { 1372 Slog.w(ActivityManagerService.TAG, 1373 "Error showing notification for heavy-weight app", e); 1374 } catch (RemoteException e) { 1375 } 1376 } catch (NameNotFoundException e) { 1377 Slog.w(TAG, "Unable to create context for heavy notification", e); 1378 } 1379 } break; 1380 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1381 INotificationManager inm = NotificationManager.getService(); 1382 if (inm == null) { 1383 return; 1384 } 1385 try { 1386 inm.cancelNotificationWithTag("android", null, 1387 R.string.heavy_weight_notification, msg.arg1); 1388 } catch (RuntimeException e) { 1389 Slog.w(ActivityManagerService.TAG, 1390 "Error canceling notification for service", e); 1391 } catch (RemoteException e) { 1392 } 1393 } break; 1394 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1395 synchronized (ActivityManagerService.this) { 1396 checkExcessivePowerUsageLocked(true); 1397 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1398 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1399 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1400 } 1401 } break; 1402 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1403 synchronized (ActivityManagerService.this) { 1404 ActivityRecord ar = (ActivityRecord)msg.obj; 1405 if (mCompatModeDialog != null) { 1406 if (mCompatModeDialog.mAppInfo.packageName.equals( 1407 ar.info.applicationInfo.packageName)) { 1408 return; 1409 } 1410 mCompatModeDialog.dismiss(); 1411 mCompatModeDialog = null; 1412 } 1413 if (ar != null && false) { 1414 if (mCompatModePackages.getPackageAskCompatModeLocked( 1415 ar.packageName)) { 1416 int mode = mCompatModePackages.computeCompatModeLocked( 1417 ar.info.applicationInfo); 1418 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1419 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1420 mCompatModeDialog = new CompatModeDialog( 1421 ActivityManagerService.this, mContext, 1422 ar.info.applicationInfo); 1423 mCompatModeDialog.show(); 1424 } 1425 } 1426 } 1427 } 1428 break; 1429 } 1430 case DISPATCH_PROCESSES_CHANGED: { 1431 dispatchProcessesChanged(); 1432 break; 1433 } 1434 case DISPATCH_PROCESS_DIED: { 1435 final int pid = msg.arg1; 1436 final int uid = msg.arg2; 1437 dispatchProcessDied(pid, uid); 1438 break; 1439 } 1440 case REPORT_MEM_USAGE_MSG: { 1441 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1442 Thread thread = new Thread() { 1443 @Override public void run() { 1444 final SparseArray<ProcessMemInfo> infoMap 1445 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1446 for (int i=0, N=memInfos.size(); i<N; i++) { 1447 ProcessMemInfo mi = memInfos.get(i); 1448 infoMap.put(mi.pid, mi); 1449 } 1450 updateCpuStatsNow(); 1451 synchronized (mProcessCpuThread) { 1452 final int N = mProcessCpuTracker.countStats(); 1453 for (int i=0; i<N; i++) { 1454 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1455 if (st.vsize > 0) { 1456 long pss = Debug.getPss(st.pid, null); 1457 if (pss > 0) { 1458 if (infoMap.indexOfKey(st.pid) < 0) { 1459 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1460 ProcessList.NATIVE_ADJ, -1, "native", null); 1461 mi.pss = pss; 1462 memInfos.add(mi); 1463 } 1464 } 1465 } 1466 } 1467 } 1468 1469 long totalPss = 0; 1470 for (int i=0, N=memInfos.size(); i<N; i++) { 1471 ProcessMemInfo mi = memInfos.get(i); 1472 if (mi.pss == 0) { 1473 mi.pss = Debug.getPss(mi.pid, null); 1474 } 1475 totalPss += mi.pss; 1476 } 1477 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1478 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1479 if (lhs.oomAdj != rhs.oomAdj) { 1480 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1481 } 1482 if (lhs.pss != rhs.pss) { 1483 return lhs.pss < rhs.pss ? 1 : -1; 1484 } 1485 return 0; 1486 } 1487 }); 1488 1489 StringBuilder tag = new StringBuilder(128); 1490 StringBuilder stack = new StringBuilder(128); 1491 tag.append("Low on memory -- "); 1492 appendMemBucket(tag, totalPss, "total", false); 1493 appendMemBucket(stack, totalPss, "total", true); 1494 1495 StringBuilder logBuilder = new StringBuilder(1024); 1496 logBuilder.append("Low on memory:\n"); 1497 1498 boolean firstLine = true; 1499 int lastOomAdj = Integer.MIN_VALUE; 1500 for (int i=0, N=memInfos.size(); i<N; i++) { 1501 ProcessMemInfo mi = memInfos.get(i); 1502 1503 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1504 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1505 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1506 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1507 if (lastOomAdj != mi.oomAdj) { 1508 lastOomAdj = mi.oomAdj; 1509 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1510 tag.append(" / "); 1511 } 1512 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1513 if (firstLine) { 1514 stack.append(":"); 1515 firstLine = false; 1516 } 1517 stack.append("\n\t at "); 1518 } else { 1519 stack.append("$"); 1520 } 1521 } else { 1522 tag.append(" "); 1523 stack.append("$"); 1524 } 1525 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1526 appendMemBucket(tag, mi.pss, mi.name, false); 1527 } 1528 appendMemBucket(stack, mi.pss, mi.name, true); 1529 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1530 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1531 stack.append("("); 1532 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1533 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1534 stack.append(DUMP_MEM_OOM_LABEL[k]); 1535 stack.append(":"); 1536 stack.append(DUMP_MEM_OOM_ADJ[k]); 1537 } 1538 } 1539 stack.append(")"); 1540 } 1541 } 1542 1543 logBuilder.append(" "); 1544 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1545 logBuilder.append(' '); 1546 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1547 logBuilder.append(' '); 1548 ProcessList.appendRamKb(logBuilder, mi.pss); 1549 logBuilder.append(" kB: "); 1550 logBuilder.append(mi.name); 1551 logBuilder.append(" ("); 1552 logBuilder.append(mi.pid); 1553 logBuilder.append(") "); 1554 logBuilder.append(mi.adjType); 1555 logBuilder.append('\n'); 1556 if (mi.adjReason != null) { 1557 logBuilder.append(" "); 1558 logBuilder.append(mi.adjReason); 1559 logBuilder.append('\n'); 1560 } 1561 } 1562 1563 logBuilder.append(" "); 1564 ProcessList.appendRamKb(logBuilder, totalPss); 1565 logBuilder.append(" kB: TOTAL\n"); 1566 1567 long[] infos = new long[Debug.MEMINFO_COUNT]; 1568 Debug.getMemInfo(infos); 1569 logBuilder.append(" MemInfo: "); 1570 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1571 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1572 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1573 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1574 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1575 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1576 logBuilder.append(" ZRAM: "); 1577 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1578 logBuilder.append(" kB RAM, "); 1579 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1580 logBuilder.append(" kB swap total, "); 1581 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1582 logBuilder.append(" kB swap free\n"); 1583 } 1584 Slog.i(TAG, logBuilder.toString()); 1585 1586 StringBuilder dropBuilder = new StringBuilder(1024); 1587 /* 1588 StringWriter oomSw = new StringWriter(); 1589 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1590 StringWriter catSw = new StringWriter(); 1591 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1592 String[] emptyArgs = new String[] { }; 1593 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1594 oomPw.flush(); 1595 String oomString = oomSw.toString(); 1596 */ 1597 dropBuilder.append(stack); 1598 dropBuilder.append('\n'); 1599 dropBuilder.append('\n'); 1600 dropBuilder.append(logBuilder); 1601 dropBuilder.append('\n'); 1602 /* 1603 dropBuilder.append(oomString); 1604 dropBuilder.append('\n'); 1605 */ 1606 StringWriter catSw = new StringWriter(); 1607 synchronized (ActivityManagerService.this) { 1608 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1609 String[] emptyArgs = new String[] { }; 1610 catPw.println(); 1611 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1612 catPw.println(); 1613 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1614 false, false, null); 1615 catPw.println(); 1616 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1617 catPw.flush(); 1618 } 1619 dropBuilder.append(catSw.toString()); 1620 addErrorToDropBox("lowmem", null, "system_server", null, 1621 null, tag.toString(), dropBuilder.toString(), null, null); 1622 //Slog.i(TAG, "Sent to dropbox:"); 1623 //Slog.i(TAG, dropBuilder.toString()); 1624 synchronized (ActivityManagerService.this) { 1625 long now = SystemClock.uptimeMillis(); 1626 if (mLastMemUsageReportTime < now) { 1627 mLastMemUsageReportTime = now; 1628 } 1629 } 1630 } 1631 }; 1632 thread.start(); 1633 break; 1634 } 1635 case REPORT_USER_SWITCH_MSG: { 1636 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1637 break; 1638 } 1639 case CONTINUE_USER_SWITCH_MSG: { 1640 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1641 break; 1642 } 1643 case USER_SWITCH_TIMEOUT_MSG: { 1644 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1645 break; 1646 } 1647 case IMMERSIVE_MODE_LOCK_MSG: { 1648 final boolean nextState = (msg.arg1 != 0); 1649 if (mUpdateLock.isHeld() != nextState) { 1650 if (DEBUG_IMMERSIVE) { 1651 final ActivityRecord r = (ActivityRecord) msg.obj; 1652 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1653 } 1654 if (nextState) { 1655 mUpdateLock.acquire(); 1656 } else { 1657 mUpdateLock.release(); 1658 } 1659 } 1660 break; 1661 } 1662 case PERSIST_URI_GRANTS_MSG: { 1663 writeGrantedUriPermissions(); 1664 break; 1665 } 1666 case REQUEST_ALL_PSS_MSG: { 1667 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1668 break; 1669 } 1670 } 1671 } 1672 }; 1673 1674 static final int COLLECT_PSS_BG_MSG = 1; 1675 1676 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1677 @Override 1678 public void handleMessage(Message msg) { 1679 switch (msg.what) { 1680 case COLLECT_PSS_BG_MSG: { 1681 int i=0, num=0; 1682 long start = SystemClock.uptimeMillis(); 1683 long[] tmp = new long[1]; 1684 do { 1685 ProcessRecord proc; 1686 int procState; 1687 int pid; 1688 synchronized (ActivityManagerService.this) { 1689 if (i >= mPendingPssProcesses.size()) { 1690 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1691 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1692 mPendingPssProcesses.clear(); 1693 return; 1694 } 1695 proc = mPendingPssProcesses.get(i); 1696 procState = proc.pssProcState; 1697 if (proc.thread != null && procState == proc.setProcState) { 1698 pid = proc.pid; 1699 } else { 1700 proc = null; 1701 pid = 0; 1702 } 1703 i++; 1704 } 1705 if (proc != null) { 1706 long pss = Debug.getPss(pid, tmp); 1707 synchronized (ActivityManagerService.this) { 1708 if (proc.thread != null && proc.setProcState == procState 1709 && proc.pid == pid) { 1710 num++; 1711 proc.lastPssTime = SystemClock.uptimeMillis(); 1712 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1713 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1714 + ": " + pss + " lastPss=" + proc.lastPss 1715 + " state=" + ProcessList.makeProcStateString(procState)); 1716 if (proc.initialIdlePss == 0) { 1717 proc.initialIdlePss = pss; 1718 } 1719 proc.lastPss = pss; 1720 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1721 proc.lastCachedPss = pss; 1722 } 1723 } 1724 } 1725 } 1726 } while (true); 1727 } 1728 } 1729 } 1730 }; 1731 1732 public static void setSystemProcess() { 1733 try { 1734 ActivityManagerService m = mSelf; 1735 1736 ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true); 1737 ServiceManager.addService(ProcessStats.SERVICE_NAME, m.mProcessStats); 1738 ServiceManager.addService("meminfo", new MemBinder(m)); 1739 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1740 ServiceManager.addService("dbinfo", new DbBinder(m)); 1741 if (MONITOR_CPU_USAGE) { 1742 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1743 } 1744 ServiceManager.addService("permission", new PermissionController(m)); 1745 1746 ApplicationInfo info = 1747 mSelf.mContext.getPackageManager().getApplicationInfo( 1748 "android", STOCK_PM_FLAGS); 1749 mSystemThread.installSystemApplicationInfo(info); 1750 1751 synchronized (mSelf) { 1752 ProcessRecord app = mSelf.newProcessRecordLocked(info, 1753 info.processName, false); 1754 app.persistent = true; 1755 app.pid = MY_PID; 1756 app.maxAdj = ProcessList.SYSTEM_ADJ; 1757 app.makeActive(mSystemThread.getApplicationThread(), mSelf.mProcessStats); 1758 mSelf.mProcessNames.put(app.processName, app.uid, app); 1759 synchronized (mSelf.mPidsSelfLocked) { 1760 mSelf.mPidsSelfLocked.put(app.pid, app); 1761 } 1762 mSelf.updateLruProcessLocked(app, false, null); 1763 mSelf.updateOomAdjLocked(); 1764 } 1765 } catch (PackageManager.NameNotFoundException e) { 1766 throw new RuntimeException( 1767 "Unable to find android system package", e); 1768 } 1769 } 1770 1771 public void setWindowManager(WindowManagerService wm) { 1772 mWindowManager = wm; 1773 mStackSupervisor.setWindowManager(wm); 1774 } 1775 1776 public void startObservingNativeCrashes() { 1777 final NativeCrashListener ncl = new NativeCrashListener(); 1778 ncl.start(); 1779 } 1780 1781 public static final Context main(int factoryTest) { 1782 AThread thr = new AThread(); 1783 thr.start(); 1784 1785 synchronized (thr) { 1786 while (thr.mService == null) { 1787 try { 1788 thr.wait(); 1789 } catch (InterruptedException e) { 1790 } 1791 } 1792 } 1793 1794 ActivityManagerService m = thr.mService; 1795 mSelf = m; 1796 ActivityThread at = ActivityThread.systemMain(); 1797 mSystemThread = at; 1798 Context context = at.getSystemContext(); 1799 context.setTheme(android.R.style.Theme_Holo); 1800 m.mContext = context; 1801 m.mFactoryTest = factoryTest; 1802 m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface()); 1803 1804 m.mStackSupervisor = new ActivityStackSupervisor(m); 1805 1806 m.mBatteryStatsService.publish(context); 1807 m.mUsageStatsService.publish(context); 1808 m.mAppOpsService.publish(context); 1809 1810 synchronized (thr) { 1811 thr.mReady = true; 1812 thr.notifyAll(); 1813 } 1814 1815 m.startRunning(null, null, null, null); 1816 1817 return context; 1818 } 1819 1820 public static ActivityManagerService self() { 1821 return mSelf; 1822 } 1823 1824 public IAppOpsService getAppOpsService() { 1825 return mAppOpsService; 1826 } 1827 1828 static class AThread extends Thread { 1829 ActivityManagerService mService; 1830 Looper mLooper; 1831 boolean mReady = false; 1832 1833 public AThread() { 1834 super("ActivityManager"); 1835 } 1836 1837 @Override 1838 public void run() { 1839 Looper.prepare(); 1840 1841 android.os.Process.setThreadPriority( 1842 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1843 android.os.Process.setCanSelfBackground(false); 1844 1845 ActivityManagerService m = new ActivityManagerService(); 1846 1847 synchronized (this) { 1848 mService = m; 1849 mLooper = Looper.myLooper(); 1850 Watchdog.getInstance().addThread(new Handler(mLooper), getName()); 1851 notifyAll(); 1852 } 1853 1854 synchronized (this) { 1855 while (!mReady) { 1856 try { 1857 wait(); 1858 } catch (InterruptedException e) { 1859 } 1860 } 1861 } 1862 1863 // For debug builds, log event loop stalls to dropbox for analysis. 1864 if (StrictMode.conditionallyEnableDebugLogging()) { 1865 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1866 } 1867 1868 Looper.loop(); 1869 } 1870 } 1871 1872 static class MemBinder extends Binder { 1873 ActivityManagerService mActivityManagerService; 1874 MemBinder(ActivityManagerService activityManagerService) { 1875 mActivityManagerService = activityManagerService; 1876 } 1877 1878 @Override 1879 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1880 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1881 != PackageManager.PERMISSION_GRANTED) { 1882 pw.println("Permission Denial: can't dump meminfo from from pid=" 1883 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1884 + " without permission " + android.Manifest.permission.DUMP); 1885 return; 1886 } 1887 1888 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1889 } 1890 } 1891 1892 static class GraphicsBinder extends Binder { 1893 ActivityManagerService mActivityManagerService; 1894 GraphicsBinder(ActivityManagerService activityManagerService) { 1895 mActivityManagerService = activityManagerService; 1896 } 1897 1898 @Override 1899 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1900 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1901 != PackageManager.PERMISSION_GRANTED) { 1902 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1903 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1904 + " without permission " + android.Manifest.permission.DUMP); 1905 return; 1906 } 1907 1908 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1909 } 1910 } 1911 1912 static class DbBinder extends Binder { 1913 ActivityManagerService mActivityManagerService; 1914 DbBinder(ActivityManagerService activityManagerService) { 1915 mActivityManagerService = activityManagerService; 1916 } 1917 1918 @Override 1919 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1920 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1921 != PackageManager.PERMISSION_GRANTED) { 1922 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1923 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1924 + " without permission " + android.Manifest.permission.DUMP); 1925 return; 1926 } 1927 1928 mActivityManagerService.dumpDbInfo(fd, pw, args); 1929 } 1930 } 1931 1932 static class CpuBinder extends Binder { 1933 ActivityManagerService mActivityManagerService; 1934 CpuBinder(ActivityManagerService activityManagerService) { 1935 mActivityManagerService = activityManagerService; 1936 } 1937 1938 @Override 1939 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1940 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1941 != PackageManager.PERMISSION_GRANTED) { 1942 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1943 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1944 + " without permission " + android.Manifest.permission.DUMP); 1945 return; 1946 } 1947 1948 synchronized (mActivityManagerService.mProcessCpuThread) { 1949 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1950 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1951 SystemClock.uptimeMillis())); 1952 } 1953 } 1954 } 1955 1956 private ActivityManagerService() { 1957 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1958 1959 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT, false); 1960 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT, true); 1961 mBroadcastQueues[0] = mFgBroadcastQueue; 1962 mBroadcastQueues[1] = mBgBroadcastQueue; 1963 1964 mServices = new ActiveServices(this); 1965 mProviderMap = new ProviderMap(this); 1966 1967 File dataDir = Environment.getDataDirectory(); 1968 File systemDir = new File(dataDir, "system"); 1969 systemDir.mkdirs(); 1970 mBatteryStatsService = new BatteryStatsService(new File( 1971 systemDir, "batterystats.bin").toString()); 1972 mBatteryStatsService.getActiveStatistics().readLocked(); 1973 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1974 mOnBattery = DEBUG_POWER ? true 1975 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1976 mBatteryStatsService.getActiveStatistics().setCallback(this); 1977 1978 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1979 1980 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1981 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml")); 1982 1983 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1984 1985 // User 0 is the first and only user that runs at boot. 1986 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1987 mUserLru.add(Integer.valueOf(0)); 1988 updateStartedUserArrayLocked(); 1989 1990 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1991 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1992 1993 mConfiguration.setToDefaults(); 1994 mConfiguration.setLocale(Locale.getDefault()); 1995 1996 mConfigurationSeq = mConfiguration.seq = 1; 1997 mProcessCpuTracker.init(); 1998 1999 mCompatModePackages = new CompatModePackages(this, systemDir); 2000 2001 // Add ourself to the Watchdog monitors. 2002 Watchdog.getInstance().addMonitor(this); 2003 2004 mProcessCpuThread = new Thread("CpuTracker") { 2005 @Override 2006 public void run() { 2007 while (true) { 2008 try { 2009 try { 2010 synchronized(this) { 2011 final long now = SystemClock.uptimeMillis(); 2012 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2013 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2014 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2015 // + ", write delay=" + nextWriteDelay); 2016 if (nextWriteDelay < nextCpuDelay) { 2017 nextCpuDelay = nextWriteDelay; 2018 } 2019 if (nextCpuDelay > 0) { 2020 mProcessCpuMutexFree.set(true); 2021 this.wait(nextCpuDelay); 2022 } 2023 } 2024 } catch (InterruptedException e) { 2025 } 2026 updateCpuStatsNow(); 2027 } catch (Exception e) { 2028 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2029 } 2030 } 2031 } 2032 }; 2033 mProcessCpuThread.start(); 2034 } 2035 2036 @Override 2037 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2038 throws RemoteException { 2039 if (code == SYSPROPS_TRANSACTION) { 2040 // We need to tell all apps about the system property change. 2041 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2042 synchronized(this) { 2043 final int NP = mProcessNames.getMap().size(); 2044 for (int ip=0; ip<NP; ip++) { 2045 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2046 final int NA = apps.size(); 2047 for (int ia=0; ia<NA; ia++) { 2048 ProcessRecord app = apps.valueAt(ia); 2049 if (app.thread != null) { 2050 procs.add(app.thread.asBinder()); 2051 } 2052 } 2053 } 2054 } 2055 2056 int N = procs.size(); 2057 for (int i=0; i<N; i++) { 2058 Parcel data2 = Parcel.obtain(); 2059 try { 2060 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2061 } catch (RemoteException e) { 2062 } 2063 data2.recycle(); 2064 } 2065 } 2066 try { 2067 return super.onTransact(code, data, reply, flags); 2068 } catch (RuntimeException e) { 2069 // The activity manager only throws security exceptions, so let's 2070 // log all others. 2071 if (!(e instanceof SecurityException)) { 2072 Slog.wtf(TAG, "Activity Manager Crash", e); 2073 } 2074 throw e; 2075 } 2076 } 2077 2078 void updateCpuStats() { 2079 final long now = SystemClock.uptimeMillis(); 2080 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2081 return; 2082 } 2083 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2084 synchronized (mProcessCpuThread) { 2085 mProcessCpuThread.notify(); 2086 } 2087 } 2088 } 2089 2090 void updateCpuStatsNow() { 2091 synchronized (mProcessCpuThread) { 2092 mProcessCpuMutexFree.set(false); 2093 final long now = SystemClock.uptimeMillis(); 2094 boolean haveNewCpuStats = false; 2095 2096 if (MONITOR_CPU_USAGE && 2097 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2098 mLastCpuTime.set(now); 2099 haveNewCpuStats = true; 2100 mProcessCpuTracker.update(); 2101 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2102 //Slog.i(TAG, "Total CPU usage: " 2103 // + mProcessCpu.getTotalCpuPercent() + "%"); 2104 2105 // Slog the cpu usage if the property is set. 2106 if ("true".equals(SystemProperties.get("events.cpu"))) { 2107 int user = mProcessCpuTracker.getLastUserTime(); 2108 int system = mProcessCpuTracker.getLastSystemTime(); 2109 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2110 int irq = mProcessCpuTracker.getLastIrqTime(); 2111 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2112 int idle = mProcessCpuTracker.getLastIdleTime(); 2113 2114 int total = user + system + iowait + irq + softIrq + idle; 2115 if (total == 0) total = 1; 2116 2117 EventLog.writeEvent(EventLogTags.CPU, 2118 ((user+system+iowait+irq+softIrq) * 100) / total, 2119 (user * 100) / total, 2120 (system * 100) / total, 2121 (iowait * 100) / total, 2122 (irq * 100) / total, 2123 (softIrq * 100) / total); 2124 } 2125 } 2126 2127 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2128 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2129 synchronized(bstats) { 2130 synchronized(mPidsSelfLocked) { 2131 if (haveNewCpuStats) { 2132 if (mOnBattery) { 2133 int perc = bstats.startAddingCpuLocked(); 2134 int totalUTime = 0; 2135 int totalSTime = 0; 2136 final int N = mProcessCpuTracker.countStats(); 2137 for (int i=0; i<N; i++) { 2138 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2139 if (!st.working) { 2140 continue; 2141 } 2142 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2143 int otherUTime = (st.rel_utime*perc)/100; 2144 int otherSTime = (st.rel_stime*perc)/100; 2145 totalUTime += otherUTime; 2146 totalSTime += otherSTime; 2147 if (pr != null) { 2148 BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked( 2149 st.name, st.pid); 2150 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2151 st.rel_stime-otherSTime); 2152 ps.addSpeedStepTimes(cpuSpeedTimes); 2153 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2154 } else if (st.uid >= Process.FIRST_APPLICATION_UID) { 2155 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2156 if (ps == null) { 2157 st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid, 2158 "(Unknown)"); 2159 } 2160 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2161 st.rel_stime-otherSTime); 2162 ps.addSpeedStepTimes(cpuSpeedTimes); 2163 } else { 2164 BatteryStatsImpl.Uid.Proc ps = 2165 bstats.getProcessStatsLocked(st.name, st.pid); 2166 if (ps != null) { 2167 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2168 st.rel_stime-otherSTime); 2169 ps.addSpeedStepTimes(cpuSpeedTimes); 2170 } 2171 } 2172 } 2173 bstats.finishAddingCpuLocked(perc, totalUTime, 2174 totalSTime, cpuSpeedTimes); 2175 } 2176 } 2177 } 2178 2179 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2180 mLastWriteTime = now; 2181 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2182 } 2183 } 2184 } 2185 } 2186 2187 @Override 2188 public void batteryNeedsCpuUpdate() { 2189 updateCpuStatsNow(); 2190 } 2191 2192 @Override 2193 public void batteryPowerChanged(boolean onBattery) { 2194 // When plugging in, update the CPU stats first before changing 2195 // the plug state. 2196 updateCpuStatsNow(); 2197 synchronized (this) { 2198 synchronized(mPidsSelfLocked) { 2199 mOnBattery = DEBUG_POWER ? true : onBattery; 2200 } 2201 } 2202 } 2203 2204 /** 2205 * Initialize the application bind args. These are passed to each 2206 * process when the bindApplication() IPC is sent to the process. They're 2207 * lazily setup to make sure the services are running when they're asked for. 2208 */ 2209 private HashMap<String, IBinder> getCommonServicesLocked() { 2210 if (mAppBindArgs == null) { 2211 mAppBindArgs = new HashMap<String, IBinder>(); 2212 2213 // Setup the application init args 2214 mAppBindArgs.put("package", ServiceManager.getService("package")); 2215 mAppBindArgs.put("window", ServiceManager.getService("window")); 2216 mAppBindArgs.put(Context.ALARM_SERVICE, 2217 ServiceManager.getService(Context.ALARM_SERVICE)); 2218 } 2219 return mAppBindArgs; 2220 } 2221 2222 final void setFocusedActivityLocked(ActivityRecord r) { 2223 if (mFocusedActivity != r) { 2224 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2225 mFocusedActivity = r; 2226 mStackSupervisor.setFocusedStack(r); 2227 if (r != null) { 2228 mWindowManager.setFocusedApp(r.appToken, true); 2229 } 2230 applyUpdateLockStateLocked(r); 2231 } 2232 } 2233 2234 @Override 2235 public void setFocusedStack(int stackId) { 2236 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2237 synchronized (ActivityManagerService.this) { 2238 ActivityStack stack = mStackSupervisor.getStack(stackId); 2239 if (stack != null) { 2240 ActivityRecord r = stack.topRunningActivityLocked(null); 2241 if (r != null) { 2242 setFocusedActivityLocked(r); 2243 } 2244 } 2245 } 2246 } 2247 2248 @Override 2249 public void notifyActivityDrawn(IBinder token) { 2250 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2251 synchronized (this) { 2252 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2253 if (r != null) { 2254 r.task.stack.notifyActivityDrawnLocked(r); 2255 } 2256 } 2257 } 2258 2259 final void applyUpdateLockStateLocked(ActivityRecord r) { 2260 // Modifications to the UpdateLock state are done on our handler, outside 2261 // the activity manager's locks. The new state is determined based on the 2262 // state *now* of the relevant activity record. The object is passed to 2263 // the handler solely for logging detail, not to be consulted/modified. 2264 final boolean nextState = r != null && r.immersive; 2265 mHandler.sendMessage( 2266 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2267 } 2268 2269 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2270 Message msg = Message.obtain(); 2271 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2272 msg.obj = r.task.askedCompatMode ? null : r; 2273 mHandler.sendMessage(msg); 2274 } 2275 2276 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2277 String what, Object obj, ProcessRecord srcApp) { 2278 app.lastActivityTime = now; 2279 2280 if (app.activities.size() > 0) { 2281 // Don't want to touch dependent processes that are hosting activities. 2282 return index; 2283 } 2284 2285 int lrui = mLruProcesses.lastIndexOf(app); 2286 if (lrui < 0) { 2287 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2288 + what + " " + obj + " from " + srcApp); 2289 return index; 2290 } 2291 2292 if (lrui >= index) { 2293 // Don't want to cause this to move dependent processes *back* in the 2294 // list as if they were less frequently used. 2295 return index; 2296 } 2297 2298 if (lrui >= mLruProcessActivityStart) { 2299 // Don't want to touch dependent processes that are hosting activities. 2300 return index; 2301 } 2302 2303 mLruProcesses.remove(lrui); 2304 if (index > 0) { 2305 index--; 2306 } 2307 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2308 + " in LRU list: " + app); 2309 mLruProcesses.add(index, app); 2310 return index; 2311 } 2312 2313 final void removeLruProcessLocked(ProcessRecord app) { 2314 int lrui = mLruProcesses.lastIndexOf(app); 2315 if (lrui >= 0) { 2316 if (lrui <= mLruProcessActivityStart) { 2317 mLruProcessActivityStart--; 2318 } 2319 if (lrui <= mLruProcessServiceStart) { 2320 mLruProcessServiceStart--; 2321 } 2322 mLruProcesses.remove(lrui); 2323 } 2324 } 2325 2326 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2327 ProcessRecord client) { 2328 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities; 2329 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2330 if (!activityChange && hasActivity) { 2331 // The process has activties, so we are only going to allow activity-based 2332 // adjustments move it. It should be kept in the front of the list with other 2333 // processes that have activities, and we don't want those to change their 2334 // order except due to activity operations. 2335 return; 2336 } 2337 2338 mLruSeq++; 2339 final long now = SystemClock.uptimeMillis(); 2340 app.lastActivityTime = now; 2341 2342 // First a quick reject: if the app is already at the position we will 2343 // put it, then there is nothing to do. 2344 if (hasActivity) { 2345 final int N = mLruProcesses.size(); 2346 if (N > 0 && mLruProcesses.get(N-1) == app) { 2347 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2348 return; 2349 } 2350 } else { 2351 if (mLruProcessServiceStart > 0 2352 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2353 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2354 return; 2355 } 2356 } 2357 2358 int lrui = mLruProcesses.lastIndexOf(app); 2359 2360 if (app.persistent && lrui >= 0) { 2361 // We don't care about the position of persistent processes, as long as 2362 // they are in the list. 2363 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2364 return; 2365 } 2366 2367 /* In progress: compute new position first, so we can avoid doing work 2368 if the process is not actually going to move. Not yet working. 2369 int addIndex; 2370 int nextIndex; 2371 boolean inActivity = false, inService = false; 2372 if (hasActivity) { 2373 // Process has activities, put it at the very tipsy-top. 2374 addIndex = mLruProcesses.size(); 2375 nextIndex = mLruProcessServiceStart; 2376 inActivity = true; 2377 } else if (hasService) { 2378 // Process has services, put it at the top of the service list. 2379 addIndex = mLruProcessActivityStart; 2380 nextIndex = mLruProcessServiceStart; 2381 inActivity = true; 2382 inService = true; 2383 } else { 2384 // Process not otherwise of interest, it goes to the top of the non-service area. 2385 addIndex = mLruProcessServiceStart; 2386 if (client != null) { 2387 int clientIndex = mLruProcesses.lastIndexOf(client); 2388 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2389 + app); 2390 if (clientIndex >= 0 && addIndex > clientIndex) { 2391 addIndex = clientIndex; 2392 } 2393 } 2394 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2395 } 2396 2397 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2398 + mLruProcessActivityStart + "): " + app); 2399 */ 2400 2401 if (lrui >= 0) { 2402 if (lrui < mLruProcessActivityStart) { 2403 mLruProcessActivityStart--; 2404 } 2405 if (lrui < mLruProcessServiceStart) { 2406 mLruProcessServiceStart--; 2407 } 2408 /* 2409 if (addIndex > lrui) { 2410 addIndex--; 2411 } 2412 if (nextIndex > lrui) { 2413 nextIndex--; 2414 } 2415 */ 2416 mLruProcesses.remove(lrui); 2417 } 2418 2419 /* 2420 mLruProcesses.add(addIndex, app); 2421 if (inActivity) { 2422 mLruProcessActivityStart++; 2423 } 2424 if (inService) { 2425 mLruProcessActivityStart++; 2426 } 2427 */ 2428 2429 int nextIndex; 2430 if (hasActivity) { 2431 final int N = mLruProcesses.size(); 2432 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2433 // Process doesn't have activities, but has clients with 2434 // activities... move it up, but one below the top (the top 2435 // should always have a real activity). 2436 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2437 mLruProcesses.add(N-1, app); 2438 // To keep it from spamming the LRU list (by making a bunch of clients), 2439 // we will push down any other entries owned by the app. 2440 final int uid = app.info.uid; 2441 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2442 ProcessRecord subProc = mLruProcesses.get(i); 2443 if (subProc.info.uid == uid) { 2444 // We want to push this one down the list. If the process after 2445 // it is for the same uid, however, don't do so, because we don't 2446 // want them internally to be re-ordered. 2447 if (mLruProcesses.get(i-1).info.uid != uid) { 2448 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2449 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2450 ProcessRecord tmp = mLruProcesses.get(i); 2451 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2452 mLruProcesses.set(i-1, tmp); 2453 i--; 2454 } 2455 } else { 2456 // A gap, we can stop here. 2457 break; 2458 } 2459 } 2460 } else { 2461 // Process has activities, put it at the very tipsy-top. 2462 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2463 mLruProcesses.add(app); 2464 } 2465 nextIndex = mLruProcessServiceStart; 2466 } else if (hasService) { 2467 // Process has services, put it at the top of the service list. 2468 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2469 mLruProcesses.add(mLruProcessActivityStart, app); 2470 nextIndex = mLruProcessServiceStart; 2471 mLruProcessActivityStart++; 2472 } else { 2473 // Process not otherwise of interest, it goes to the top of the non-service area. 2474 int index = mLruProcessServiceStart; 2475 if (client != null) { 2476 // If there is a client, don't allow the process to be moved up higher 2477 // in the list than that client. 2478 int clientIndex = mLruProcesses.lastIndexOf(client); 2479 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2480 + " when updating " + app); 2481 if (clientIndex <= lrui) { 2482 // Don't allow the client index restriction to push it down farther in the 2483 // list than it already is. 2484 clientIndex = lrui; 2485 } 2486 if (clientIndex >= 0 && index > clientIndex) { 2487 index = clientIndex; 2488 } 2489 } 2490 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2491 mLruProcesses.add(index, app); 2492 nextIndex = index-1; 2493 mLruProcessActivityStart++; 2494 mLruProcessServiceStart++; 2495 } 2496 2497 // If the app is currently using a content provider or service, 2498 // bump those processes as well. 2499 for (int j=app.connections.size()-1; j>=0; j--) { 2500 ConnectionRecord cr = app.connections.valueAt(j); 2501 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2502 && cr.binding.service.app != null 2503 && cr.binding.service.app.lruSeq != mLruSeq 2504 && !cr.binding.service.app.persistent) { 2505 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2506 "service connection", cr, app); 2507 } 2508 } 2509 for (int j=app.conProviders.size()-1; j>=0; j--) { 2510 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2511 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2512 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2513 "provider reference", cpr, app); 2514 } 2515 } 2516 } 2517 2518 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2519 if (uid == Process.SYSTEM_UID) { 2520 // The system gets to run in any process. If there are multiple 2521 // processes with the same uid, just pick the first (this 2522 // should never happen). 2523 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2524 if (procs == null) return null; 2525 final int N = procs.size(); 2526 for (int i = 0; i < N; i++) { 2527 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2528 } 2529 } 2530 ProcessRecord proc = mProcessNames.get(processName, uid); 2531 if (false && proc != null && !keepIfLarge 2532 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2533 && proc.lastCachedPss >= 4000) { 2534 // Turn this condition on to cause killing to happen regularly, for testing. 2535 if (proc.baseProcessTracker != null) { 2536 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2537 } 2538 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2539 + "k from cached"); 2540 } else if (proc != null && !keepIfLarge 2541 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2542 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2543 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2544 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2545 if (proc.baseProcessTracker != null) { 2546 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2547 } 2548 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2549 + "k from cached"); 2550 } 2551 } 2552 return proc; 2553 } 2554 2555 void ensurePackageDexOpt(String packageName) { 2556 IPackageManager pm = AppGlobals.getPackageManager(); 2557 try { 2558 if (pm.performDexOpt(packageName)) { 2559 mDidDexOpt = true; 2560 } 2561 } catch (RemoteException e) { 2562 } 2563 } 2564 2565 boolean isNextTransitionForward() { 2566 int transit = mWindowManager.getPendingAppTransition(); 2567 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2568 || transit == AppTransition.TRANSIT_TASK_OPEN 2569 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2570 } 2571 2572 final ProcessRecord startProcessLocked(String processName, 2573 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2574 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2575 boolean isolated, boolean keepIfLarge) { 2576 ProcessRecord app; 2577 if (!isolated) { 2578 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2579 } else { 2580 // If this is an isolated process, it can't re-use an existing process. 2581 app = null; 2582 } 2583 // We don't have to do anything more if: 2584 // (1) There is an existing application record; and 2585 // (2) The caller doesn't think it is dead, OR there is no thread 2586 // object attached to it so we know it couldn't have crashed; and 2587 // (3) There is a pid assigned to it, so it is either starting or 2588 // already running. 2589 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2590 + " app=" + app + " knownToBeDead=" + knownToBeDead 2591 + " thread=" + (app != null ? app.thread : null) 2592 + " pid=" + (app != null ? app.pid : -1)); 2593 if (app != null && app.pid > 0) { 2594 if (!knownToBeDead || app.thread == null) { 2595 // We already have the app running, or are waiting for it to 2596 // come up (we have a pid but not yet its thread), so keep it. 2597 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2598 // If this is a new package in the process, add the package to the list 2599 app.addPackage(info.packageName, mProcessStats); 2600 return app; 2601 } 2602 2603 // An application record is attached to a previous process, 2604 // clean it up now. 2605 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2606 handleAppDiedLocked(app, true, true); 2607 } 2608 2609 String hostingNameStr = hostingName != null 2610 ? hostingName.flattenToShortString() : null; 2611 2612 if (!isolated) { 2613 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2614 // If we are in the background, then check to see if this process 2615 // is bad. If so, we will just silently fail. 2616 if (mBadProcesses.get(info.processName, info.uid) != null) { 2617 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2618 + "/" + info.processName); 2619 return null; 2620 } 2621 } else { 2622 // When the user is explicitly starting a process, then clear its 2623 // crash count so that we won't make it bad until they see at 2624 // least one crash dialog again, and make the process good again 2625 // if it had been bad. 2626 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2627 + "/" + info.processName); 2628 mProcessCrashTimes.remove(info.processName, info.uid); 2629 if (mBadProcesses.get(info.processName, info.uid) != null) { 2630 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2631 UserHandle.getUserId(info.uid), info.uid, 2632 info.processName); 2633 mBadProcesses.remove(info.processName, info.uid); 2634 if (app != null) { 2635 app.bad = false; 2636 } 2637 } 2638 } 2639 } 2640 2641 if (app == null) { 2642 app = newProcessRecordLocked(info, processName, isolated); 2643 if (app == null) { 2644 Slog.w(TAG, "Failed making new process record for " 2645 + processName + "/" + info.uid + " isolated=" + isolated); 2646 return null; 2647 } 2648 mProcessNames.put(processName, app.uid, app); 2649 if (isolated) { 2650 mIsolatedProcesses.put(app.uid, app); 2651 } 2652 } else { 2653 // If this is a new package in the process, add the package to the list 2654 app.addPackage(info.packageName, mProcessStats); 2655 } 2656 2657 // If the system is not ready yet, then hold off on starting this 2658 // process until it is. 2659 if (!mProcessesReady 2660 && !isAllowedWhileBooting(info) 2661 && !allowWhileBooting) { 2662 if (!mProcessesOnHold.contains(app)) { 2663 mProcessesOnHold.add(app); 2664 } 2665 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2666 return app; 2667 } 2668 2669 startProcessLocked(app, hostingType, hostingNameStr); 2670 return (app.pid != 0) ? app : null; 2671 } 2672 2673 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2674 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2675 } 2676 2677 private final void startProcessLocked(ProcessRecord app, 2678 String hostingType, String hostingNameStr) { 2679 if (app.pid > 0 && app.pid != MY_PID) { 2680 synchronized (mPidsSelfLocked) { 2681 mPidsSelfLocked.remove(app.pid); 2682 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2683 } 2684 app.setPid(0); 2685 } 2686 2687 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2688 "startProcessLocked removing on hold: " + app); 2689 mProcessesOnHold.remove(app); 2690 2691 updateCpuStats(); 2692 2693 try { 2694 int uid = app.uid; 2695 2696 int[] gids = null; 2697 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2698 if (!app.isolated) { 2699 int[] permGids = null; 2700 try { 2701 final PackageManager pm = mContext.getPackageManager(); 2702 permGids = pm.getPackageGids(app.info.packageName); 2703 2704 if (Environment.isExternalStorageEmulated()) { 2705 if (pm.checkPermission( 2706 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2707 app.info.packageName) == PERMISSION_GRANTED) { 2708 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2709 } else { 2710 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2711 } 2712 } 2713 } catch (PackageManager.NameNotFoundException e) { 2714 Slog.w(TAG, "Unable to retrieve gids", e); 2715 } 2716 2717 /* 2718 * Add shared application GID so applications can share some 2719 * resources like shared libraries 2720 */ 2721 if (permGids == null) { 2722 gids = new int[1]; 2723 } else { 2724 gids = new int[permGids.length + 1]; 2725 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2726 } 2727 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2728 } 2729 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2730 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2731 && mTopComponent != null 2732 && app.processName.equals(mTopComponent.getPackageName())) { 2733 uid = 0; 2734 } 2735 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2736 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2737 uid = 0; 2738 } 2739 } 2740 int debugFlags = 0; 2741 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2742 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2743 // Also turn on CheckJNI for debuggable apps. It's quite 2744 // awkward to turn on otherwise. 2745 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2746 } 2747 // Run the app in safe mode if its manifest requests so or the 2748 // system is booted in safe mode. 2749 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2750 Zygote.systemInSafeMode == true) { 2751 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2752 } 2753 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2754 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2755 } 2756 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2757 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2758 } 2759 if ("1".equals(SystemProperties.get("debug.assert"))) { 2760 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2761 } 2762 2763 // Start the process. It will either succeed and return a result containing 2764 // the PID of the new process, or else throw a RuntimeException. 2765 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2766 app.processName, uid, uid, gids, debugFlags, mountExternal, 2767 app.info.targetSdkVersion, app.info.seinfo, null); 2768 2769 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2770 synchronized (bs) { 2771 if (bs.isOnBattery()) { 2772 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2773 } 2774 } 2775 2776 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2777 UserHandle.getUserId(uid), startResult.pid, uid, 2778 app.processName, hostingType, 2779 hostingNameStr != null ? hostingNameStr : ""); 2780 2781 if (app.persistent) { 2782 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2783 } 2784 2785 StringBuilder buf = mStringBuilder; 2786 buf.setLength(0); 2787 buf.append("Start proc "); 2788 buf.append(app.processName); 2789 buf.append(" for "); 2790 buf.append(hostingType); 2791 if (hostingNameStr != null) { 2792 buf.append(" "); 2793 buf.append(hostingNameStr); 2794 } 2795 buf.append(": pid="); 2796 buf.append(startResult.pid); 2797 buf.append(" uid="); 2798 buf.append(uid); 2799 buf.append(" gids={"); 2800 if (gids != null) { 2801 for (int gi=0; gi<gids.length; gi++) { 2802 if (gi != 0) buf.append(", "); 2803 buf.append(gids[gi]); 2804 2805 } 2806 } 2807 buf.append("}"); 2808 Slog.i(TAG, buf.toString()); 2809 app.setPid(startResult.pid); 2810 app.usingWrapper = startResult.usingWrapper; 2811 app.removed = false; 2812 synchronized (mPidsSelfLocked) { 2813 this.mPidsSelfLocked.put(startResult.pid, app); 2814 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2815 msg.obj = app; 2816 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2817 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2818 } 2819 } catch (RuntimeException e) { 2820 // XXX do better error recovery. 2821 app.setPid(0); 2822 Slog.e(TAG, "Failure starting process " + app.processName, e); 2823 } 2824 } 2825 2826 void updateUsageStats(ActivityRecord component, boolean resumed) { 2827 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2828 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2829 if (resumed) { 2830 mUsageStatsService.noteResumeComponent(component.realActivity); 2831 synchronized (stats) { 2832 stats.noteActivityResumedLocked(component.app.uid); 2833 } 2834 } else { 2835 mUsageStatsService.notePauseComponent(component.realActivity); 2836 synchronized (stats) { 2837 stats.noteActivityPausedLocked(component.app.uid); 2838 } 2839 } 2840 } 2841 2842 Intent getHomeIntent() { 2843 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2844 intent.setComponent(mTopComponent); 2845 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2846 intent.addCategory(Intent.CATEGORY_HOME); 2847 } 2848 return intent; 2849 } 2850 2851 boolean startHomeActivityLocked(int userId) { 2852 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2853 && mTopAction == null) { 2854 // We are running in factory test mode, but unable to find 2855 // the factory test app, so just sit around displaying the 2856 // error message and don't try to start anything. 2857 return false; 2858 } 2859 Intent intent = getHomeIntent(); 2860 ActivityInfo aInfo = 2861 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2862 if (aInfo != null) { 2863 intent.setComponent(new ComponentName( 2864 aInfo.applicationInfo.packageName, aInfo.name)); 2865 // Don't do this if the home app is currently being 2866 // instrumented. 2867 aInfo = new ActivityInfo(aInfo); 2868 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2869 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2870 aInfo.applicationInfo.uid, true); 2871 if (app == null || app.instrumentationClass == null) { 2872 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2873 mStackSupervisor.startHomeActivity(intent, aInfo); 2874 } 2875 } 2876 2877 return true; 2878 } 2879 2880 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2881 ActivityInfo ai = null; 2882 ComponentName comp = intent.getComponent(); 2883 try { 2884 if (comp != null) { 2885 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2886 } else { 2887 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2888 intent, 2889 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2890 flags, userId); 2891 2892 if (info != null) { 2893 ai = info.activityInfo; 2894 } 2895 } 2896 } catch (RemoteException e) { 2897 // ignore 2898 } 2899 2900 return ai; 2901 } 2902 2903 /** 2904 * Starts the "new version setup screen" if appropriate. 2905 */ 2906 void startSetupActivityLocked() { 2907 // Only do this once per boot. 2908 if (mCheckedForSetup) { 2909 return; 2910 } 2911 2912 // We will show this screen if the current one is a different 2913 // version than the last one shown, and we are not running in 2914 // low-level factory test mode. 2915 final ContentResolver resolver = mContext.getContentResolver(); 2916 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2917 Settings.Global.getInt(resolver, 2918 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2919 mCheckedForSetup = true; 2920 2921 // See if we should be showing the platform update setup UI. 2922 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2923 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2924 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2925 2926 // We don't allow third party apps to replace this. 2927 ResolveInfo ri = null; 2928 for (int i=0; ris != null && i<ris.size(); i++) { 2929 if ((ris.get(i).activityInfo.applicationInfo.flags 2930 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2931 ri = ris.get(i); 2932 break; 2933 } 2934 } 2935 2936 if (ri != null) { 2937 String vers = ri.activityInfo.metaData != null 2938 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2939 : null; 2940 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2941 vers = ri.activityInfo.applicationInfo.metaData.getString( 2942 Intent.METADATA_SETUP_VERSION); 2943 } 2944 String lastVers = Settings.Secure.getString( 2945 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2946 if (vers != null && !vers.equals(lastVers)) { 2947 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2948 intent.setComponent(new ComponentName( 2949 ri.activityInfo.packageName, ri.activityInfo.name)); 2950 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2951 null, null, 0, 0, 0, null, 0, null, false, null); 2952 } 2953 } 2954 } 2955 } 2956 2957 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2958 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2959 } 2960 2961 void enforceNotIsolatedCaller(String caller) { 2962 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2963 throw new SecurityException("Isolated process not allowed to call " + caller); 2964 } 2965 } 2966 2967 @Override 2968 public int getFrontActivityScreenCompatMode() { 2969 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2970 synchronized (this) { 2971 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2972 } 2973 } 2974 2975 @Override 2976 public void setFrontActivityScreenCompatMode(int mode) { 2977 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2978 "setFrontActivityScreenCompatMode"); 2979 synchronized (this) { 2980 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2981 } 2982 } 2983 2984 @Override 2985 public int getPackageScreenCompatMode(String packageName) { 2986 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2987 synchronized (this) { 2988 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2989 } 2990 } 2991 2992 @Override 2993 public void setPackageScreenCompatMode(String packageName, int mode) { 2994 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2995 "setPackageScreenCompatMode"); 2996 synchronized (this) { 2997 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2998 } 2999 } 3000 3001 @Override 3002 public boolean getPackageAskScreenCompat(String packageName) { 3003 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3004 synchronized (this) { 3005 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3006 } 3007 } 3008 3009 @Override 3010 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3011 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3012 "setPackageAskScreenCompat"); 3013 synchronized (this) { 3014 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3015 } 3016 } 3017 3018 private void dispatchProcessesChanged() { 3019 int N; 3020 synchronized (this) { 3021 N = mPendingProcessChanges.size(); 3022 if (mActiveProcessChanges.length < N) { 3023 mActiveProcessChanges = new ProcessChangeItem[N]; 3024 } 3025 mPendingProcessChanges.toArray(mActiveProcessChanges); 3026 mAvailProcessChanges.addAll(mPendingProcessChanges); 3027 mPendingProcessChanges.clear(); 3028 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3029 } 3030 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 for (int j=0; j<N; j++) { 3038 ProcessChangeItem item = mActiveProcessChanges[j]; 3039 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3040 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3041 + item.pid + " uid=" + item.uid + ": " 3042 + item.foregroundActivities); 3043 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3044 item.foregroundActivities); 3045 } 3046 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3047 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3048 + item.pid + " uid=" + item.uid + ": " + item.importance); 3049 observer.onImportanceChanged(item.pid, item.uid, 3050 item.importance); 3051 } 3052 } 3053 } catch (RemoteException e) { 3054 } 3055 } 3056 } 3057 mProcessObservers.finishBroadcast(); 3058 } 3059 3060 private void dispatchProcessDied(int pid, int uid) { 3061 int i = mProcessObservers.beginBroadcast(); 3062 while (i > 0) { 3063 i--; 3064 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3065 if (observer != null) { 3066 try { 3067 observer.onProcessDied(pid, uid); 3068 } catch (RemoteException e) { 3069 } 3070 } 3071 } 3072 mProcessObservers.finishBroadcast(); 3073 } 3074 3075 final void doPendingActivityLaunchesLocked(boolean doResume) { 3076 final int N = mPendingActivityLaunches.size(); 3077 if (N <= 0) { 3078 return; 3079 } 3080 for (int i=0; i<N; i++) { 3081 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3082 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3083 doResume && i == (N-1), null); 3084 } 3085 mPendingActivityLaunches.clear(); 3086 } 3087 3088 @Override 3089 public final int startActivity(IApplicationThread caller, String callingPackage, 3090 Intent intent, String resolvedType, IBinder resultTo, 3091 String resultWho, int requestCode, int startFlags, 3092 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3093 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3094 resultWho, requestCode, 3095 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3096 } 3097 3098 @Override 3099 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3100 Intent intent, String resolvedType, IBinder resultTo, 3101 String resultWho, int requestCode, int startFlags, 3102 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3103 enforceNotIsolatedCaller("startActivity"); 3104 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3105 false, true, "startActivity", null); 3106 // TODO: Switch to user app stacks here. 3107 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3108 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3109 null, null, options, userId); 3110 } 3111 3112 @Override 3113 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3114 Intent intent, String resolvedType, IBinder resultTo, 3115 String resultWho, int requestCode, int startFlags, String profileFile, 3116 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3117 enforceNotIsolatedCaller("startActivityAndWait"); 3118 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3119 false, true, "startActivityAndWait", null); 3120 WaitResult res = new WaitResult(); 3121 // TODO: Switch to user app stacks here. 3122 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3123 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3124 res, null, options, UserHandle.getCallingUserId()); 3125 return res; 3126 } 3127 3128 @Override 3129 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3130 Intent intent, String resolvedType, IBinder resultTo, 3131 String resultWho, int requestCode, int startFlags, Configuration config, 3132 Bundle options, int userId) { 3133 enforceNotIsolatedCaller("startActivityWithConfig"); 3134 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3135 false, true, "startActivityWithConfig", null); 3136 // TODO: Switch to user app stacks here. 3137 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3138 resolvedType, resultTo, resultWho, requestCode, startFlags, 3139 null, null, null, config, options, userId); 3140 return ret; 3141 } 3142 3143 @Override 3144 public int startActivityIntentSender(IApplicationThread caller, 3145 IntentSender intent, Intent fillInIntent, String resolvedType, 3146 IBinder resultTo, String resultWho, int requestCode, 3147 int flagsMask, int flagsValues, Bundle options) { 3148 enforceNotIsolatedCaller("startActivityIntentSender"); 3149 // Refuse possible leaked file descriptors 3150 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3151 throw new IllegalArgumentException("File descriptors passed in Intent"); 3152 } 3153 3154 IIntentSender sender = intent.getTarget(); 3155 if (!(sender instanceof PendingIntentRecord)) { 3156 throw new IllegalArgumentException("Bad PendingIntent object"); 3157 } 3158 3159 PendingIntentRecord pir = (PendingIntentRecord)sender; 3160 3161 synchronized (this) { 3162 // If this is coming from the currently resumed activity, it is 3163 // effectively saying that app switches are allowed at this point. 3164 final ActivityStack stack = getFocusedStack(); 3165 if (stack.mResumedActivity != null && 3166 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3167 mAppSwitchesAllowedTime = 0; 3168 } 3169 } 3170 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3171 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 3172 return ret; 3173 } 3174 3175 @Override 3176 public boolean startNextMatchingActivity(IBinder callingActivity, 3177 Intent intent, Bundle options) { 3178 // Refuse possible leaked file descriptors 3179 if (intent != null && intent.hasFileDescriptors() == true) { 3180 throw new IllegalArgumentException("File descriptors passed in Intent"); 3181 } 3182 3183 synchronized (this) { 3184 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3185 if (r == null) { 3186 ActivityOptions.abort(options); 3187 return false; 3188 } 3189 if (r.app == null || r.app.thread == null) { 3190 // The caller is not running... d'oh! 3191 ActivityOptions.abort(options); 3192 return false; 3193 } 3194 intent = new Intent(intent); 3195 // The caller is not allowed to change the data. 3196 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3197 // And we are resetting to find the next component... 3198 intent.setComponent(null); 3199 3200 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3201 3202 ActivityInfo aInfo = null; 3203 try { 3204 List<ResolveInfo> resolves = 3205 AppGlobals.getPackageManager().queryIntentActivities( 3206 intent, r.resolvedType, 3207 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3208 UserHandle.getCallingUserId()); 3209 3210 // Look for the original activity in the list... 3211 final int N = resolves != null ? resolves.size() : 0; 3212 for (int i=0; i<N; i++) { 3213 ResolveInfo rInfo = resolves.get(i); 3214 if (rInfo.activityInfo.packageName.equals(r.packageName) 3215 && rInfo.activityInfo.name.equals(r.info.name)) { 3216 // We found the current one... the next matching is 3217 // after it. 3218 i++; 3219 if (i<N) { 3220 aInfo = resolves.get(i).activityInfo; 3221 } 3222 if (debug) { 3223 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3224 + "/" + r.info.name); 3225 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3226 + "/" + aInfo.name); 3227 } 3228 break; 3229 } 3230 } 3231 } catch (RemoteException e) { 3232 } 3233 3234 if (aInfo == null) { 3235 // Nobody who is next! 3236 ActivityOptions.abort(options); 3237 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3238 return false; 3239 } 3240 3241 intent.setComponent(new ComponentName( 3242 aInfo.applicationInfo.packageName, aInfo.name)); 3243 intent.setFlags(intent.getFlags()&~( 3244 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3245 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3246 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3247 Intent.FLAG_ACTIVITY_NEW_TASK)); 3248 3249 // Okay now we need to start the new activity, replacing the 3250 // currently running activity. This is a little tricky because 3251 // we want to start the new one as if the current one is finished, 3252 // but not finish the current one first so that there is no flicker. 3253 // And thus... 3254 final boolean wasFinishing = r.finishing; 3255 r.finishing = true; 3256 3257 // Propagate reply information over to the new activity. 3258 final ActivityRecord resultTo = r.resultTo; 3259 final String resultWho = r.resultWho; 3260 final int requestCode = r.requestCode; 3261 r.resultTo = null; 3262 if (resultTo != null) { 3263 resultTo.removeResultsLocked(r, resultWho, requestCode); 3264 } 3265 3266 final long origId = Binder.clearCallingIdentity(); 3267 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3268 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3269 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3270 options, false, null); 3271 Binder.restoreCallingIdentity(origId); 3272 3273 r.finishing = wasFinishing; 3274 if (res != ActivityManager.START_SUCCESS) { 3275 return false; 3276 } 3277 return true; 3278 } 3279 } 3280 3281 final int startActivityInPackage(int uid, String callingPackage, 3282 Intent intent, String resolvedType, IBinder resultTo, 3283 String resultWho, int requestCode, int startFlags, Bundle options, int userId) { 3284 3285 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3286 false, true, "startActivityInPackage", null); 3287 3288 // TODO: Switch to user app stacks here. 3289 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3290 resultTo, resultWho, requestCode, startFlags, 3291 null, null, null, null, options, userId); 3292 return ret; 3293 } 3294 3295 @Override 3296 public final int startActivities(IApplicationThread caller, String callingPackage, 3297 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3298 int userId) { 3299 enforceNotIsolatedCaller("startActivities"); 3300 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3301 false, true, "startActivity", null); 3302 // TODO: Switch to user app stacks here. 3303 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3304 resolvedTypes, resultTo, options, userId); 3305 return ret; 3306 } 3307 3308 final int startActivitiesInPackage(int uid, String callingPackage, 3309 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3310 Bundle options, int userId) { 3311 3312 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3313 false, true, "startActivityInPackage", null); 3314 // TODO: Switch to user app stacks here. 3315 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3316 resultTo, options, userId); 3317 return ret; 3318 } 3319 3320 final void addRecentTaskLocked(TaskRecord task) { 3321 int N = mRecentTasks.size(); 3322 // Quick case: check if the top-most recent task is the same. 3323 if (N > 0 && mRecentTasks.get(0) == task) { 3324 return; 3325 } 3326 // Remove any existing entries that are the same kind of task. 3327 for (int i=0; i<N; i++) { 3328 TaskRecord tr = mRecentTasks.get(i); 3329 if (task.userId == tr.userId 3330 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 3331 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 3332 tr.disposeThumbnail(); 3333 mRecentTasks.remove(i); 3334 i--; 3335 N--; 3336 if (task.intent == null) { 3337 // If the new recent task we are adding is not fully 3338 // specified, then replace it with the existing recent task. 3339 task = tr; 3340 } 3341 } 3342 } 3343 if (N >= MAX_RECENT_TASKS) { 3344 mRecentTasks.remove(N-1).disposeThumbnail(); 3345 } 3346 mRecentTasks.add(0, task); 3347 } 3348 3349 @Override 3350 public void reportActivityFullyDrawn(IBinder token) { 3351 synchronized (this) { 3352 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3353 if (r == null) { 3354 return; 3355 } 3356 r.reportFullyDrawnLocked(); 3357 } 3358 } 3359 3360 @Override 3361 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3362 synchronized (this) { 3363 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3364 if (r == null) { 3365 return; 3366 } 3367 final long origId = Binder.clearCallingIdentity(); 3368 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3369 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3370 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3371 if (config != null) { 3372 r.frozenBeforeDestroy = true; 3373 if (!updateConfigurationLocked(config, r, false, false)) { 3374 mStackSupervisor.resumeTopActivitiesLocked(); 3375 } 3376 } 3377 Binder.restoreCallingIdentity(origId); 3378 } 3379 } 3380 3381 @Override 3382 public int getRequestedOrientation(IBinder token) { 3383 synchronized (this) { 3384 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3385 if (r == null) { 3386 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3387 } 3388 return mWindowManager.getAppOrientation(r.appToken); 3389 } 3390 } 3391 3392 /** 3393 * This is the internal entry point for handling Activity.finish(). 3394 * 3395 * @param token The Binder token referencing the Activity we want to finish. 3396 * @param resultCode Result code, if any, from this Activity. 3397 * @param resultData Result data (Intent), if any, from this Activity. 3398 * 3399 * @return Returns true if the activity successfully finished, or false if it is still running. 3400 */ 3401 @Override 3402 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3403 // Refuse possible leaked file descriptors 3404 if (resultData != null && resultData.hasFileDescriptors() == true) { 3405 throw new IllegalArgumentException("File descriptors passed in Intent"); 3406 } 3407 3408 synchronized(this) { 3409 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3410 if (r == null) { 3411 return true; 3412 } 3413 if (mController != null) { 3414 // Find the first activity that is not finishing. 3415 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3416 if (next != null) { 3417 // ask watcher if this is allowed 3418 boolean resumeOK = true; 3419 try { 3420 resumeOK = mController.activityResuming(next.packageName); 3421 } catch (RemoteException e) { 3422 mController = null; 3423 Watchdog.getInstance().setActivityController(null); 3424 } 3425 3426 if (!resumeOK) { 3427 return false; 3428 } 3429 } 3430 } 3431 final long origId = Binder.clearCallingIdentity(); 3432 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3433 resultData, "app-request", true); 3434 Binder.restoreCallingIdentity(origId); 3435 return res; 3436 } 3437 } 3438 3439 @Override 3440 public final void finishHeavyWeightApp() { 3441 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3442 != PackageManager.PERMISSION_GRANTED) { 3443 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3444 + Binder.getCallingPid() 3445 + ", uid=" + Binder.getCallingUid() 3446 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3447 Slog.w(TAG, msg); 3448 throw new SecurityException(msg); 3449 } 3450 3451 synchronized(this) { 3452 if (mHeavyWeightProcess == null) { 3453 return; 3454 } 3455 3456 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3457 mHeavyWeightProcess.activities); 3458 for (int i=0; i<activities.size(); i++) { 3459 ActivityRecord r = activities.get(i); 3460 if (!r.finishing) { 3461 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3462 null, "finish-heavy", true); 3463 } 3464 } 3465 3466 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3467 mHeavyWeightProcess.userId, 0)); 3468 mHeavyWeightProcess = null; 3469 } 3470 } 3471 3472 @Override 3473 public void crashApplication(int uid, int initialPid, String packageName, 3474 String message) { 3475 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3476 != PackageManager.PERMISSION_GRANTED) { 3477 String msg = "Permission Denial: crashApplication() from pid=" 3478 + Binder.getCallingPid() 3479 + ", uid=" + Binder.getCallingUid() 3480 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3481 Slog.w(TAG, msg); 3482 throw new SecurityException(msg); 3483 } 3484 3485 synchronized(this) { 3486 ProcessRecord proc = null; 3487 3488 // Figure out which process to kill. We don't trust that initialPid 3489 // still has any relation to current pids, so must scan through the 3490 // list. 3491 synchronized (mPidsSelfLocked) { 3492 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3493 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3494 if (p.uid != uid) { 3495 continue; 3496 } 3497 if (p.pid == initialPid) { 3498 proc = p; 3499 break; 3500 } 3501 if (p.pkgList.containsKey(packageName)) { 3502 proc = p; 3503 } 3504 } 3505 } 3506 3507 if (proc == null) { 3508 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3509 + " initialPid=" + initialPid 3510 + " packageName=" + packageName); 3511 return; 3512 } 3513 3514 if (proc.thread != null) { 3515 if (proc.pid == Process.myPid()) { 3516 Log.w(TAG, "crashApplication: trying to crash self!"); 3517 return; 3518 } 3519 long ident = Binder.clearCallingIdentity(); 3520 try { 3521 proc.thread.scheduleCrash(message); 3522 } catch (RemoteException e) { 3523 } 3524 Binder.restoreCallingIdentity(ident); 3525 } 3526 } 3527 } 3528 3529 @Override 3530 public final void finishSubActivity(IBinder token, String resultWho, 3531 int requestCode) { 3532 synchronized(this) { 3533 final long origId = Binder.clearCallingIdentity(); 3534 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3535 if (r != null) { 3536 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3537 } 3538 Binder.restoreCallingIdentity(origId); 3539 } 3540 } 3541 3542 @Override 3543 public boolean finishActivityAffinity(IBinder token) { 3544 synchronized(this) { 3545 final long origId = Binder.clearCallingIdentity(); 3546 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3547 boolean res = false; 3548 if (r != null) { 3549 res = r.task.stack.finishActivityAffinityLocked(r); 3550 } 3551 Binder.restoreCallingIdentity(origId); 3552 return res; 3553 } 3554 } 3555 3556 @Override 3557 public boolean willActivityBeVisible(IBinder token) { 3558 synchronized(this) { 3559 ActivityStack stack = ActivityRecord.getStackLocked(token); 3560 if (stack != null) { 3561 return stack.willActivityBeVisibleLocked(token); 3562 } 3563 return false; 3564 } 3565 } 3566 3567 @Override 3568 public void overridePendingTransition(IBinder token, String packageName, 3569 int enterAnim, int exitAnim) { 3570 synchronized(this) { 3571 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3572 if (self == null) { 3573 return; 3574 } 3575 3576 final long origId = Binder.clearCallingIdentity(); 3577 3578 if (self.state == ActivityState.RESUMED 3579 || self.state == ActivityState.PAUSING) { 3580 mWindowManager.overridePendingAppTransition(packageName, 3581 enterAnim, exitAnim, null); 3582 } 3583 3584 Binder.restoreCallingIdentity(origId); 3585 } 3586 } 3587 3588 /** 3589 * Main function for removing an existing process from the activity manager 3590 * as a result of that process going away. Clears out all connections 3591 * to the process. 3592 */ 3593 private final void handleAppDiedLocked(ProcessRecord app, 3594 boolean restarting, boolean allowRestart) { 3595 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3596 if (!restarting) { 3597 removeLruProcessLocked(app); 3598 } 3599 3600 if (mProfileProc == app) { 3601 clearProfilerLocked(); 3602 } 3603 3604 // Remove this application's activities from active lists. 3605 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3606 3607 app.activities.clear(); 3608 3609 if (app.instrumentationClass != null) { 3610 Slog.w(TAG, "Crash of app " + app.processName 3611 + " running instrumentation " + app.instrumentationClass); 3612 Bundle info = new Bundle(); 3613 info.putString("shortMsg", "Process crashed."); 3614 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3615 } 3616 3617 if (!restarting) { 3618 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3619 // If there was nothing to resume, and we are not already 3620 // restarting this process, but there is a visible activity that 3621 // is hosted by the process... then make sure all visible 3622 // activities are running, taking care of restarting this 3623 // process. 3624 if (hasVisibleActivities) { 3625 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3626 } 3627 } 3628 } 3629 } 3630 3631 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3632 IBinder threadBinder = thread.asBinder(); 3633 // Find the application record. 3634 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3635 ProcessRecord rec = mLruProcesses.get(i); 3636 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3637 return i; 3638 } 3639 } 3640 return -1; 3641 } 3642 3643 final ProcessRecord getRecordForAppLocked( 3644 IApplicationThread thread) { 3645 if (thread == null) { 3646 return null; 3647 } 3648 3649 int appIndex = getLRURecordIndexForAppLocked(thread); 3650 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3651 } 3652 3653 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3654 // If there are no longer any background processes running, 3655 // and the app that died was not running instrumentation, 3656 // then tell everyone we are now low on memory. 3657 boolean haveBg = false; 3658 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3659 ProcessRecord rec = mLruProcesses.get(i); 3660 if (rec.thread != null 3661 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3662 haveBg = true; 3663 break; 3664 } 3665 } 3666 3667 if (!haveBg) { 3668 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3669 if (doReport) { 3670 long now = SystemClock.uptimeMillis(); 3671 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3672 doReport = false; 3673 } else { 3674 mLastMemUsageReportTime = now; 3675 } 3676 } 3677 final ArrayList<ProcessMemInfo> memInfos 3678 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3679 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3680 long now = SystemClock.uptimeMillis(); 3681 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3682 ProcessRecord rec = mLruProcesses.get(i); 3683 if (rec == dyingProc || rec.thread == null) { 3684 continue; 3685 } 3686 if (doReport) { 3687 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3688 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3689 } 3690 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3691 // The low memory report is overriding any current 3692 // state for a GC request. Make sure to do 3693 // heavy/important/visible/foreground processes first. 3694 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3695 rec.lastRequestedGc = 0; 3696 } else { 3697 rec.lastRequestedGc = rec.lastLowMemory; 3698 } 3699 rec.reportLowMemory = true; 3700 rec.lastLowMemory = now; 3701 mProcessesToGc.remove(rec); 3702 addProcessToGcListLocked(rec); 3703 } 3704 } 3705 if (doReport) { 3706 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3707 mHandler.sendMessage(msg); 3708 } 3709 scheduleAppGcsLocked(); 3710 } 3711 } 3712 3713 final void appDiedLocked(ProcessRecord app, int pid, 3714 IApplicationThread thread) { 3715 3716 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3717 synchronized (stats) { 3718 stats.noteProcessDiedLocked(app.info.uid, pid); 3719 } 3720 3721 // Clean up already done if the process has been re-started. 3722 if (app.pid == pid && app.thread != null && 3723 app.thread.asBinder() == thread.asBinder()) { 3724 boolean doLowMem = app.instrumentationClass == null; 3725 boolean doOomAdj = doLowMem; 3726 if (!app.killedByAm) { 3727 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3728 + ") has died."); 3729 mAllowLowerMemLevel = true; 3730 } else { 3731 // Note that we always want to do oom adj to update our state with the 3732 // new number of procs. 3733 mAllowLowerMemLevel = false; 3734 doLowMem = false; 3735 } 3736 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3737 if (DEBUG_CLEANUP) Slog.v( 3738 TAG, "Dying app: " + app + ", pid: " + pid 3739 + ", thread: " + thread.asBinder()); 3740 handleAppDiedLocked(app, false, true); 3741 3742 if (doOomAdj) { 3743 updateOomAdjLocked(); 3744 } 3745 if (doLowMem) { 3746 doLowMemReportIfNeededLocked(app); 3747 } 3748 } else if (app.pid != pid) { 3749 // A new process has already been started. 3750 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3751 + ") has died and restarted (pid " + app.pid + ")."); 3752 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3753 } else if (DEBUG_PROCESSES) { 3754 Slog.d(TAG, "Received spurious death notification for thread " 3755 + thread.asBinder()); 3756 } 3757 } 3758 3759 /** 3760 * If a stack trace dump file is configured, dump process stack traces. 3761 * @param clearTraces causes the dump file to be erased prior to the new 3762 * traces being written, if true; when false, the new traces will be 3763 * appended to any existing file content. 3764 * @param firstPids of dalvik VM processes to dump stack traces for first 3765 * @param lastPids of dalvik VM processes to dump stack traces for last 3766 * @param nativeProcs optional list of native process names to dump stack crawls 3767 * @return file containing stack traces, or null if no dump file is configured 3768 */ 3769 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3770 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3771 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3772 if (tracesPath == null || tracesPath.length() == 0) { 3773 return null; 3774 } 3775 3776 File tracesFile = new File(tracesPath); 3777 try { 3778 File tracesDir = tracesFile.getParentFile(); 3779 if (!tracesDir.exists()) { 3780 tracesFile.mkdirs(); 3781 if (!SELinux.restorecon(tracesDir)) { 3782 return null; 3783 } 3784 } 3785 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3786 3787 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3788 tracesFile.createNewFile(); 3789 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3790 } catch (IOException e) { 3791 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3792 return null; 3793 } 3794 3795 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3796 return tracesFile; 3797 } 3798 3799 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3800 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3801 // Use a FileObserver to detect when traces finish writing. 3802 // The order of traces is considered important to maintain for legibility. 3803 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3804 @Override 3805 public synchronized void onEvent(int event, String path) { notify(); } 3806 }; 3807 3808 try { 3809 observer.startWatching(); 3810 3811 // First collect all of the stacks of the most important pids. 3812 if (firstPids != null) { 3813 try { 3814 int num = firstPids.size(); 3815 for (int i = 0; i < num; i++) { 3816 synchronized (observer) { 3817 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3818 observer.wait(200); // Wait for write-close, give up after 200msec 3819 } 3820 } 3821 } catch (InterruptedException e) { 3822 Log.wtf(TAG, e); 3823 } 3824 } 3825 3826 // Next collect the stacks of the native pids 3827 if (nativeProcs != null) { 3828 int[] pids = Process.getPidsForCommands(nativeProcs); 3829 if (pids != null) { 3830 for (int pid : pids) { 3831 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3832 } 3833 } 3834 } 3835 3836 // Lastly, measure CPU usage. 3837 if (processCpuTracker != null) { 3838 processCpuTracker.init(); 3839 System.gc(); 3840 processCpuTracker.update(); 3841 try { 3842 synchronized (processCpuTracker) { 3843 processCpuTracker.wait(500); // measure over 1/2 second. 3844 } 3845 } catch (InterruptedException e) { 3846 } 3847 processCpuTracker.update(); 3848 3849 // We'll take the stack crawls of just the top apps using CPU. 3850 final int N = processCpuTracker.countWorkingStats(); 3851 int numProcs = 0; 3852 for (int i=0; i<N && numProcs<5; i++) { 3853 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3854 if (lastPids.indexOfKey(stats.pid) >= 0) { 3855 numProcs++; 3856 try { 3857 synchronized (observer) { 3858 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3859 observer.wait(200); // Wait for write-close, give up after 200msec 3860 } 3861 } catch (InterruptedException e) { 3862 Log.wtf(TAG, e); 3863 } 3864 3865 } 3866 } 3867 } 3868 } finally { 3869 observer.stopWatching(); 3870 } 3871 } 3872 3873 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3874 if (true || IS_USER_BUILD) { 3875 return; 3876 } 3877 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3878 if (tracesPath == null || tracesPath.length() == 0) { 3879 return; 3880 } 3881 3882 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3883 StrictMode.allowThreadDiskWrites(); 3884 try { 3885 final File tracesFile = new File(tracesPath); 3886 final File tracesDir = tracesFile.getParentFile(); 3887 final File tracesTmp = new File(tracesDir, "__tmp__"); 3888 try { 3889 if (!tracesDir.exists()) { 3890 tracesFile.mkdirs(); 3891 if (!SELinux.restorecon(tracesDir.getPath())) { 3892 return; 3893 } 3894 } 3895 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3896 3897 if (tracesFile.exists()) { 3898 tracesTmp.delete(); 3899 tracesFile.renameTo(tracesTmp); 3900 } 3901 StringBuilder sb = new StringBuilder(); 3902 Time tobj = new Time(); 3903 tobj.set(System.currentTimeMillis()); 3904 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3905 sb.append(": "); 3906 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3907 sb.append(" since "); 3908 sb.append(msg); 3909 FileOutputStream fos = new FileOutputStream(tracesFile); 3910 fos.write(sb.toString().getBytes()); 3911 if (app == null) { 3912 fos.write("\n*** No application process!".getBytes()); 3913 } 3914 fos.close(); 3915 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3916 } catch (IOException e) { 3917 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3918 return; 3919 } 3920 3921 if (app != null) { 3922 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3923 firstPids.add(app.pid); 3924 dumpStackTraces(tracesPath, firstPids, null, null, null); 3925 } 3926 3927 File lastTracesFile = null; 3928 File curTracesFile = null; 3929 for (int i=9; i>=0; i--) { 3930 String name = String.format(Locale.US, "slow%02d.txt", i); 3931 curTracesFile = new File(tracesDir, name); 3932 if (curTracesFile.exists()) { 3933 if (lastTracesFile != null) { 3934 curTracesFile.renameTo(lastTracesFile); 3935 } else { 3936 curTracesFile.delete(); 3937 } 3938 } 3939 lastTracesFile = curTracesFile; 3940 } 3941 tracesFile.renameTo(curTracesFile); 3942 if (tracesTmp.exists()) { 3943 tracesTmp.renameTo(tracesFile); 3944 } 3945 } finally { 3946 StrictMode.setThreadPolicy(oldPolicy); 3947 } 3948 } 3949 3950 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3951 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3952 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3953 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3954 3955 if (mController != null) { 3956 try { 3957 // 0 == continue, -1 = kill process immediately 3958 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3959 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3960 } catch (RemoteException e) { 3961 mController = null; 3962 Watchdog.getInstance().setActivityController(null); 3963 } 3964 } 3965 3966 long anrTime = SystemClock.uptimeMillis(); 3967 if (MONITOR_CPU_USAGE) { 3968 updateCpuStatsNow(); 3969 } 3970 3971 synchronized (this) { 3972 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3973 if (mShuttingDown) { 3974 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3975 return; 3976 } else if (app.notResponding) { 3977 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3978 return; 3979 } else if (app.crashing) { 3980 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3981 return; 3982 } 3983 3984 // In case we come through here for the same app before completing 3985 // this one, mark as anring now so we will bail out. 3986 app.notResponding = true; 3987 3988 // Log the ANR to the event log. 3989 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3990 app.processName, app.info.flags, annotation); 3991 3992 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3993 firstPids.add(app.pid); 3994 3995 int parentPid = app.pid; 3996 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3997 if (parentPid != app.pid) firstPids.add(parentPid); 3998 3999 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4000 4001 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4002 ProcessRecord r = mLruProcesses.get(i); 4003 if (r != null && r.thread != null) { 4004 int pid = r.pid; 4005 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4006 if (r.persistent) { 4007 firstPids.add(pid); 4008 } else { 4009 lastPids.put(pid, Boolean.TRUE); 4010 } 4011 } 4012 } 4013 } 4014 } 4015 4016 // Log the ANR to the main log. 4017 StringBuilder info = new StringBuilder(); 4018 info.setLength(0); 4019 info.append("ANR in ").append(app.processName); 4020 if (activity != null && activity.shortComponentName != null) { 4021 info.append(" (").append(activity.shortComponentName).append(")"); 4022 } 4023 info.append("\n"); 4024 info.append("PID: ").append(app.pid).append("\n"); 4025 if (annotation != null) { 4026 info.append("Reason: ").append(annotation).append("\n"); 4027 } 4028 if (parent != null && parent != activity) { 4029 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4030 } 4031 4032 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4033 4034 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4035 NATIVE_STACKS_OF_INTEREST); 4036 4037 String cpuInfo = null; 4038 if (MONITOR_CPU_USAGE) { 4039 updateCpuStatsNow(); 4040 synchronized (mProcessCpuThread) { 4041 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4042 } 4043 info.append(processCpuTracker.printCurrentLoad()); 4044 info.append(cpuInfo); 4045 } 4046 4047 info.append(processCpuTracker.printCurrentState(anrTime)); 4048 4049 Slog.e(TAG, info.toString()); 4050 if (tracesFile == null) { 4051 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4052 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4053 } 4054 4055 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4056 cpuInfo, tracesFile, null); 4057 4058 if (mController != null) { 4059 try { 4060 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4061 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4062 if (res != 0) { 4063 if (res < 0 && app.pid != MY_PID) { 4064 Process.killProcess(app.pid); 4065 } else { 4066 synchronized (this) { 4067 mServices.scheduleServiceTimeoutLocked(app); 4068 } 4069 } 4070 return; 4071 } 4072 } catch (RemoteException e) { 4073 mController = null; 4074 Watchdog.getInstance().setActivityController(null); 4075 } 4076 } 4077 4078 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4079 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4080 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4081 4082 synchronized (this) { 4083 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4084 killUnneededProcessLocked(app, "background ANR"); 4085 return; 4086 } 4087 4088 // Set the app's notResponding state, and look up the errorReportReceiver 4089 makeAppNotRespondingLocked(app, 4090 activity != null ? activity.shortComponentName : null, 4091 annotation != null ? "ANR " + annotation : "ANR", 4092 info.toString()); 4093 4094 // Bring up the infamous App Not Responding dialog 4095 Message msg = Message.obtain(); 4096 HashMap<String, Object> map = new HashMap<String, Object>(); 4097 msg.what = SHOW_NOT_RESPONDING_MSG; 4098 msg.obj = map; 4099 msg.arg1 = aboveSystem ? 1 : 0; 4100 map.put("app", app); 4101 if (activity != null) { 4102 map.put("activity", activity); 4103 } 4104 4105 mHandler.sendMessage(msg); 4106 } 4107 } 4108 4109 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4110 if (!mLaunchWarningShown) { 4111 mLaunchWarningShown = true; 4112 mHandler.post(new Runnable() { 4113 @Override 4114 public void run() { 4115 synchronized (ActivityManagerService.this) { 4116 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4117 d.show(); 4118 mHandler.postDelayed(new Runnable() { 4119 @Override 4120 public void run() { 4121 synchronized (ActivityManagerService.this) { 4122 d.dismiss(); 4123 mLaunchWarningShown = false; 4124 } 4125 } 4126 }, 4000); 4127 } 4128 } 4129 }); 4130 } 4131 } 4132 4133 @Override 4134 public boolean clearApplicationUserData(final String packageName, 4135 final IPackageDataObserver observer, int userId) { 4136 enforceNotIsolatedCaller("clearApplicationUserData"); 4137 int uid = Binder.getCallingUid(); 4138 int pid = Binder.getCallingPid(); 4139 userId = handleIncomingUser(pid, uid, 4140 userId, false, true, "clearApplicationUserData", null); 4141 long callingId = Binder.clearCallingIdentity(); 4142 try { 4143 IPackageManager pm = AppGlobals.getPackageManager(); 4144 int pkgUid = -1; 4145 synchronized(this) { 4146 try { 4147 pkgUid = pm.getPackageUid(packageName, userId); 4148 } catch (RemoteException e) { 4149 } 4150 if (pkgUid == -1) { 4151 Slog.w(TAG, "Invalid packageName: " + packageName); 4152 if (observer != null) { 4153 try { 4154 observer.onRemoveCompleted(packageName, false); 4155 } catch (RemoteException e) { 4156 Slog.i(TAG, "Observer no longer exists."); 4157 } 4158 } 4159 return false; 4160 } 4161 if (uid == pkgUid || checkComponentPermission( 4162 android.Manifest.permission.CLEAR_APP_USER_DATA, 4163 pid, uid, -1, true) 4164 == PackageManager.PERMISSION_GRANTED) { 4165 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4166 } else { 4167 throw new SecurityException("PID " + pid + " does not have permission " 4168 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4169 + " of package " + packageName); 4170 } 4171 } 4172 4173 try { 4174 // Clear application user data 4175 pm.clearApplicationUserData(packageName, observer, userId); 4176 4177 // Remove all permissions granted from/to this package 4178 removeUriPermissionsForPackageLocked(packageName, userId, true); 4179 4180 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4181 Uri.fromParts("package", packageName, null)); 4182 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4183 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4184 null, null, 0, null, null, null, false, false, userId); 4185 } catch (RemoteException e) { 4186 } 4187 } finally { 4188 Binder.restoreCallingIdentity(callingId); 4189 } 4190 return true; 4191 } 4192 4193 @Override 4194 public void killBackgroundProcesses(final String packageName, int userId) { 4195 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4196 != PackageManager.PERMISSION_GRANTED && 4197 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4198 != PackageManager.PERMISSION_GRANTED) { 4199 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4200 + Binder.getCallingPid() 4201 + ", uid=" + Binder.getCallingUid() 4202 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4203 Slog.w(TAG, msg); 4204 throw new SecurityException(msg); 4205 } 4206 4207 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4208 userId, true, true, "killBackgroundProcesses", null); 4209 long callingId = Binder.clearCallingIdentity(); 4210 try { 4211 IPackageManager pm = AppGlobals.getPackageManager(); 4212 synchronized(this) { 4213 int appId = -1; 4214 try { 4215 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4216 } catch (RemoteException e) { 4217 } 4218 if (appId == -1) { 4219 Slog.w(TAG, "Invalid packageName: " + packageName); 4220 return; 4221 } 4222 killPackageProcessesLocked(packageName, appId, userId, 4223 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4224 } 4225 } finally { 4226 Binder.restoreCallingIdentity(callingId); 4227 } 4228 } 4229 4230 @Override 4231 public void killAllBackgroundProcesses() { 4232 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4233 != PackageManager.PERMISSION_GRANTED) { 4234 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4235 + Binder.getCallingPid() 4236 + ", uid=" + Binder.getCallingUid() 4237 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4238 Slog.w(TAG, msg); 4239 throw new SecurityException(msg); 4240 } 4241 4242 long callingId = Binder.clearCallingIdentity(); 4243 try { 4244 synchronized(this) { 4245 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4246 final int NP = mProcessNames.getMap().size(); 4247 for (int ip=0; ip<NP; ip++) { 4248 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4249 final int NA = apps.size(); 4250 for (int ia=0; ia<NA; ia++) { 4251 ProcessRecord app = apps.valueAt(ia); 4252 if (app.persistent) { 4253 // we don't kill persistent processes 4254 continue; 4255 } 4256 if (app.removed) { 4257 procs.add(app); 4258 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4259 app.removed = true; 4260 procs.add(app); 4261 } 4262 } 4263 } 4264 4265 int N = procs.size(); 4266 for (int i=0; i<N; i++) { 4267 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4268 } 4269 mAllowLowerMemLevel = true; 4270 updateOomAdjLocked(); 4271 doLowMemReportIfNeededLocked(null); 4272 } 4273 } finally { 4274 Binder.restoreCallingIdentity(callingId); 4275 } 4276 } 4277 4278 @Override 4279 public void forceStopPackage(final String packageName, int userId) { 4280 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4281 != PackageManager.PERMISSION_GRANTED) { 4282 String msg = "Permission Denial: forceStopPackage() from pid=" 4283 + Binder.getCallingPid() 4284 + ", uid=" + Binder.getCallingUid() 4285 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4286 Slog.w(TAG, msg); 4287 throw new SecurityException(msg); 4288 } 4289 final int callingPid = Binder.getCallingPid(); 4290 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4291 userId, true, true, "forceStopPackage", null); 4292 long callingId = Binder.clearCallingIdentity(); 4293 try { 4294 IPackageManager pm = AppGlobals.getPackageManager(); 4295 synchronized(this) { 4296 int[] users = userId == UserHandle.USER_ALL 4297 ? getUsersLocked() : new int[] { userId }; 4298 for (int user : users) { 4299 int pkgUid = -1; 4300 try { 4301 pkgUid = pm.getPackageUid(packageName, user); 4302 } catch (RemoteException e) { 4303 } 4304 if (pkgUid == -1) { 4305 Slog.w(TAG, "Invalid packageName: " + packageName); 4306 continue; 4307 } 4308 try { 4309 pm.setPackageStoppedState(packageName, true, user); 4310 } catch (RemoteException e) { 4311 } catch (IllegalArgumentException e) { 4312 Slog.w(TAG, "Failed trying to unstop package " 4313 + packageName + ": " + e); 4314 } 4315 if (isUserRunningLocked(user, false)) { 4316 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4317 } 4318 } 4319 } 4320 } finally { 4321 Binder.restoreCallingIdentity(callingId); 4322 } 4323 } 4324 4325 /* 4326 * The pkg name and app id have to be specified. 4327 */ 4328 @Override 4329 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4330 if (pkg == null) { 4331 return; 4332 } 4333 // Make sure the uid is valid. 4334 if (appid < 0) { 4335 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4336 return; 4337 } 4338 int callerUid = Binder.getCallingUid(); 4339 // Only the system server can kill an application 4340 if (callerUid == Process.SYSTEM_UID) { 4341 // Post an aysnc message to kill the application 4342 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4343 msg.arg1 = appid; 4344 msg.arg2 = 0; 4345 Bundle bundle = new Bundle(); 4346 bundle.putString("pkg", pkg); 4347 bundle.putString("reason", reason); 4348 msg.obj = bundle; 4349 mHandler.sendMessage(msg); 4350 } else { 4351 throw new SecurityException(callerUid + " cannot kill pkg: " + 4352 pkg); 4353 } 4354 } 4355 4356 @Override 4357 public void closeSystemDialogs(String reason) { 4358 enforceNotIsolatedCaller("closeSystemDialogs"); 4359 4360 final int pid = Binder.getCallingPid(); 4361 final int uid = Binder.getCallingUid(); 4362 final long origId = Binder.clearCallingIdentity(); 4363 try { 4364 synchronized (this) { 4365 // Only allow this from foreground processes, so that background 4366 // applications can't abuse it to prevent system UI from being shown. 4367 if (uid >= Process.FIRST_APPLICATION_UID) { 4368 ProcessRecord proc; 4369 synchronized (mPidsSelfLocked) { 4370 proc = mPidsSelfLocked.get(pid); 4371 } 4372 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4373 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4374 + " from background process " + proc); 4375 return; 4376 } 4377 } 4378 closeSystemDialogsLocked(reason); 4379 } 4380 } finally { 4381 Binder.restoreCallingIdentity(origId); 4382 } 4383 } 4384 4385 void closeSystemDialogsLocked(String reason) { 4386 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4387 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4388 | Intent.FLAG_RECEIVER_FOREGROUND); 4389 if (reason != null) { 4390 intent.putExtra("reason", reason); 4391 } 4392 mWindowManager.closeSystemDialogs(reason); 4393 4394 mStackSupervisor.closeSystemDialogsLocked(); 4395 4396 broadcastIntentLocked(null, null, intent, null, 4397 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4398 Process.SYSTEM_UID, UserHandle.USER_ALL); 4399 } 4400 4401 @Override 4402 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4403 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4404 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4405 for (int i=pids.length-1; i>=0; i--) { 4406 ProcessRecord proc; 4407 int oomAdj; 4408 synchronized (this) { 4409 synchronized (mPidsSelfLocked) { 4410 proc = mPidsSelfLocked.get(pids[i]); 4411 oomAdj = proc != null ? proc.setAdj : 0; 4412 } 4413 } 4414 infos[i] = new Debug.MemoryInfo(); 4415 Debug.getMemoryInfo(pids[i], infos[i]); 4416 if (proc != null) { 4417 synchronized (this) { 4418 if (proc.thread != null && proc.setAdj == oomAdj) { 4419 // Record this for posterity if the process has been stable. 4420 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4421 infos[i].getTotalUss(), false, proc.pkgList); 4422 } 4423 } 4424 } 4425 } 4426 return infos; 4427 } 4428 4429 @Override 4430 public long[] getProcessPss(int[] pids) { 4431 enforceNotIsolatedCaller("getProcessPss"); 4432 long[] pss = new long[pids.length]; 4433 for (int i=pids.length-1; i>=0; i--) { 4434 ProcessRecord proc; 4435 int oomAdj; 4436 synchronized (this) { 4437 synchronized (mPidsSelfLocked) { 4438 proc = mPidsSelfLocked.get(pids[i]); 4439 oomAdj = proc != null ? proc.setAdj : 0; 4440 } 4441 } 4442 long[] tmpUss = new long[1]; 4443 pss[i] = Debug.getPss(pids[i], tmpUss); 4444 if (proc != null) { 4445 synchronized (this) { 4446 if (proc.thread != null && proc.setAdj == oomAdj) { 4447 // Record this for posterity if the process has been stable. 4448 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4449 } 4450 } 4451 } 4452 } 4453 return pss; 4454 } 4455 4456 @Override 4457 public void killApplicationProcess(String processName, int uid) { 4458 if (processName == null) { 4459 return; 4460 } 4461 4462 int callerUid = Binder.getCallingUid(); 4463 // Only the system server can kill an application 4464 if (callerUid == Process.SYSTEM_UID) { 4465 synchronized (this) { 4466 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4467 if (app != null && app.thread != null) { 4468 try { 4469 app.thread.scheduleSuicide(); 4470 } catch (RemoteException e) { 4471 // If the other end already died, then our work here is done. 4472 } 4473 } else { 4474 Slog.w(TAG, "Process/uid not found attempting kill of " 4475 + processName + " / " + uid); 4476 } 4477 } 4478 } else { 4479 throw new SecurityException(callerUid + " cannot kill app process: " + 4480 processName); 4481 } 4482 } 4483 4484 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4485 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4486 false, true, false, UserHandle.getUserId(uid), reason); 4487 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4488 Uri.fromParts("package", packageName, null)); 4489 if (!mProcessesReady) { 4490 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4491 | Intent.FLAG_RECEIVER_FOREGROUND); 4492 } 4493 intent.putExtra(Intent.EXTRA_UID, uid); 4494 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4495 broadcastIntentLocked(null, null, intent, 4496 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4497 false, false, 4498 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4499 } 4500 4501 private void forceStopUserLocked(int userId, String reason) { 4502 forceStopPackageLocked(null, -1, false, false, true, false, userId, reason); 4503 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4504 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4505 | Intent.FLAG_RECEIVER_FOREGROUND); 4506 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4507 broadcastIntentLocked(null, null, intent, 4508 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4509 false, false, 4510 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4511 } 4512 4513 private final boolean killPackageProcessesLocked(String packageName, int appId, 4514 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4515 boolean doit, boolean evenPersistent, String reason) { 4516 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4517 4518 // Remove all processes this package may have touched: all with the 4519 // same UID (except for the system or root user), and all whose name 4520 // matches the package name. 4521 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4522 final int NP = mProcessNames.getMap().size(); 4523 for (int ip=0; ip<NP; ip++) { 4524 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4525 final int NA = apps.size(); 4526 for (int ia=0; ia<NA; ia++) { 4527 ProcessRecord app = apps.valueAt(ia); 4528 if (app.persistent && !evenPersistent) { 4529 // we don't kill persistent processes 4530 continue; 4531 } 4532 if (app.removed) { 4533 if (doit) { 4534 procs.add(app); 4535 } 4536 continue; 4537 } 4538 4539 // Skip process if it doesn't meet our oom adj requirement. 4540 if (app.setAdj < minOomAdj) { 4541 continue; 4542 } 4543 4544 // If no package is specified, we call all processes under the 4545 // give user id. 4546 if (packageName == null) { 4547 if (app.userId != userId) { 4548 continue; 4549 } 4550 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4551 continue; 4552 } 4553 // Package has been specified, we want to hit all processes 4554 // that match it. We need to qualify this by the processes 4555 // that are running under the specified app and user ID. 4556 } else { 4557 if (UserHandle.getAppId(app.uid) != appId) { 4558 continue; 4559 } 4560 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4561 continue; 4562 } 4563 if (!app.pkgList.containsKey(packageName)) { 4564 continue; 4565 } 4566 } 4567 4568 // Process has passed all conditions, kill it! 4569 if (!doit) { 4570 return true; 4571 } 4572 app.removed = true; 4573 procs.add(app); 4574 } 4575 } 4576 4577 int N = procs.size(); 4578 for (int i=0; i<N; i++) { 4579 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4580 } 4581 updateOomAdjLocked(); 4582 return N > 0; 4583 } 4584 4585 private final boolean forceStopPackageLocked(String name, int appId, 4586 boolean callerWillRestart, boolean purgeCache, boolean doit, 4587 boolean evenPersistent, int userId, String reason) { 4588 int i; 4589 int N; 4590 4591 if (userId == UserHandle.USER_ALL && name == null) { 4592 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4593 } 4594 4595 if (appId < 0 && name != null) { 4596 try { 4597 appId = UserHandle.getAppId( 4598 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4599 } catch (RemoteException e) { 4600 } 4601 } 4602 4603 if (doit) { 4604 if (name != null) { 4605 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4606 + " user=" + userId + ": " + reason); 4607 } else { 4608 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4609 } 4610 4611 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4612 for (int ip=pmap.size()-1; ip>=0; ip--) { 4613 SparseArray<Long> ba = pmap.valueAt(ip); 4614 for (i=ba.size()-1; i>=0; i--) { 4615 boolean remove = false; 4616 final int entUid = ba.keyAt(i); 4617 if (name != null) { 4618 if (userId == UserHandle.USER_ALL) { 4619 if (UserHandle.getAppId(entUid) == appId) { 4620 remove = true; 4621 } 4622 } else { 4623 if (entUid == UserHandle.getUid(userId, appId)) { 4624 remove = true; 4625 } 4626 } 4627 } else if (UserHandle.getUserId(entUid) == userId) { 4628 remove = true; 4629 } 4630 if (remove) { 4631 ba.removeAt(i); 4632 } 4633 } 4634 if (ba.size() == 0) { 4635 pmap.removeAt(ip); 4636 } 4637 } 4638 } 4639 4640 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4641 -100, callerWillRestart, true, doit, evenPersistent, 4642 name == null ? ("stop user " + userId) : ("stop " + name)); 4643 4644 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4645 if (!doit) { 4646 return true; 4647 } 4648 didSomething = true; 4649 } 4650 4651 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4652 if (!doit) { 4653 return true; 4654 } 4655 didSomething = true; 4656 } 4657 4658 if (name == null) { 4659 // Remove all sticky broadcasts from this user. 4660 mStickyBroadcasts.remove(userId); 4661 } 4662 4663 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4664 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4665 userId, providers)) { 4666 if (!doit) { 4667 return true; 4668 } 4669 didSomething = true; 4670 } 4671 N = providers.size(); 4672 for (i=0; i<N; i++) { 4673 removeDyingProviderLocked(null, providers.get(i), true); 4674 } 4675 4676 // Remove transient permissions granted from/to this package/user 4677 removeUriPermissionsForPackageLocked(name, userId, false); 4678 4679 if (name == null) { 4680 // Remove pending intents. For now we only do this when force 4681 // stopping users, because we have some problems when doing this 4682 // for packages -- app widgets are not currently cleaned up for 4683 // such packages, so they can be left with bad pending intents. 4684 if (mIntentSenderRecords.size() > 0) { 4685 Iterator<WeakReference<PendingIntentRecord>> it 4686 = mIntentSenderRecords.values().iterator(); 4687 while (it.hasNext()) { 4688 WeakReference<PendingIntentRecord> wpir = it.next(); 4689 if (wpir == null) { 4690 it.remove(); 4691 continue; 4692 } 4693 PendingIntentRecord pir = wpir.get(); 4694 if (pir == null) { 4695 it.remove(); 4696 continue; 4697 } 4698 if (name == null) { 4699 // Stopping user, remove all objects for the user. 4700 if (pir.key.userId != userId) { 4701 // Not the same user, skip it. 4702 continue; 4703 } 4704 } else { 4705 if (UserHandle.getAppId(pir.uid) != appId) { 4706 // Different app id, skip it. 4707 continue; 4708 } 4709 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4710 // Different user, skip it. 4711 continue; 4712 } 4713 if (!pir.key.packageName.equals(name)) { 4714 // Different package, skip it. 4715 continue; 4716 } 4717 } 4718 if (!doit) { 4719 return true; 4720 } 4721 didSomething = true; 4722 it.remove(); 4723 pir.canceled = true; 4724 if (pir.key.activity != null) { 4725 pir.key.activity.pendingResults.remove(pir.ref); 4726 } 4727 } 4728 } 4729 } 4730 4731 if (doit) { 4732 if (purgeCache && name != null) { 4733 AttributeCache ac = AttributeCache.instance(); 4734 if (ac != null) { 4735 ac.removePackage(name); 4736 } 4737 } 4738 if (mBooted) { 4739 mStackSupervisor.resumeTopActivitiesLocked(); 4740 mStackSupervisor.scheduleIdleLocked(); 4741 } 4742 } 4743 4744 return didSomething; 4745 } 4746 4747 private final boolean removeProcessLocked(ProcessRecord app, 4748 boolean callerWillRestart, boolean allowRestart, String reason) { 4749 final String name = app.processName; 4750 final int uid = app.uid; 4751 if (DEBUG_PROCESSES) Slog.d( 4752 TAG, "Force removing proc " + app.toShortString() + " (" + name 4753 + "/" + uid + ")"); 4754 4755 mProcessNames.remove(name, uid); 4756 mIsolatedProcesses.remove(app.uid); 4757 if (mHeavyWeightProcess == app) { 4758 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4759 mHeavyWeightProcess.userId, 0)); 4760 mHeavyWeightProcess = null; 4761 } 4762 boolean needRestart = false; 4763 if (app.pid > 0 && app.pid != MY_PID) { 4764 int pid = app.pid; 4765 synchronized (mPidsSelfLocked) { 4766 mPidsSelfLocked.remove(pid); 4767 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4768 } 4769 killUnneededProcessLocked(app, reason); 4770 handleAppDiedLocked(app, true, allowRestart); 4771 removeLruProcessLocked(app); 4772 4773 if (app.persistent && !app.isolated) { 4774 if (!callerWillRestart) { 4775 addAppLocked(app.info, false); 4776 } else { 4777 needRestart = true; 4778 } 4779 } 4780 } else { 4781 mRemovedProcesses.add(app); 4782 } 4783 4784 return needRestart; 4785 } 4786 4787 private final void processStartTimedOutLocked(ProcessRecord app) { 4788 final int pid = app.pid; 4789 boolean gone = false; 4790 synchronized (mPidsSelfLocked) { 4791 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4792 if (knownApp != null && knownApp.thread == null) { 4793 mPidsSelfLocked.remove(pid); 4794 gone = true; 4795 } 4796 } 4797 4798 if (gone) { 4799 Slog.w(TAG, "Process " + app + " failed to attach"); 4800 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4801 pid, app.uid, app.processName); 4802 mProcessNames.remove(app.processName, app.uid); 4803 mIsolatedProcesses.remove(app.uid); 4804 if (mHeavyWeightProcess == app) { 4805 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4806 mHeavyWeightProcess.userId, 0)); 4807 mHeavyWeightProcess = null; 4808 } 4809 // Take care of any launching providers waiting for this process. 4810 checkAppInLaunchingProvidersLocked(app, true); 4811 // Take care of any services that are waiting for the process. 4812 mServices.processStartTimedOutLocked(app); 4813 killUnneededProcessLocked(app, "start timeout"); 4814 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4815 Slog.w(TAG, "Unattached app died before backup, skipping"); 4816 try { 4817 IBackupManager bm = IBackupManager.Stub.asInterface( 4818 ServiceManager.getService(Context.BACKUP_SERVICE)); 4819 bm.agentDisconnected(app.info.packageName); 4820 } catch (RemoteException e) { 4821 // Can't happen; the backup manager is local 4822 } 4823 } 4824 if (isPendingBroadcastProcessLocked(pid)) { 4825 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4826 skipPendingBroadcastLocked(pid); 4827 } 4828 } else { 4829 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4830 } 4831 } 4832 4833 private final boolean attachApplicationLocked(IApplicationThread thread, 4834 int pid) { 4835 4836 // Find the application record that is being attached... either via 4837 // the pid if we are running in multiple processes, or just pull the 4838 // next app record if we are emulating process with anonymous threads. 4839 ProcessRecord app; 4840 if (pid != MY_PID && pid >= 0) { 4841 synchronized (mPidsSelfLocked) { 4842 app = mPidsSelfLocked.get(pid); 4843 } 4844 } else { 4845 app = null; 4846 } 4847 4848 if (app == null) { 4849 Slog.w(TAG, "No pending application record for pid " + pid 4850 + " (IApplicationThread " + thread + "); dropping process"); 4851 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4852 if (pid > 0 && pid != MY_PID) { 4853 Process.killProcessQuiet(pid); 4854 } else { 4855 try { 4856 thread.scheduleExit(); 4857 } catch (Exception e) { 4858 // Ignore exceptions. 4859 } 4860 } 4861 return false; 4862 } 4863 4864 // If this application record is still attached to a previous 4865 // process, clean it up now. 4866 if (app.thread != null) { 4867 handleAppDiedLocked(app, true, true); 4868 } 4869 4870 // Tell the process all about itself. 4871 4872 if (localLOGV) Slog.v( 4873 TAG, "Binding process pid " + pid + " to record " + app); 4874 4875 final String processName = app.processName; 4876 try { 4877 AppDeathRecipient adr = new AppDeathRecipient( 4878 app, pid, thread); 4879 thread.asBinder().linkToDeath(adr, 0); 4880 app.deathRecipient = adr; 4881 } catch (RemoteException e) { 4882 app.resetPackageList(mProcessStats); 4883 startProcessLocked(app, "link fail", processName); 4884 return false; 4885 } 4886 4887 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4888 4889 app.makeActive(thread, mProcessStats); 4890 app.curAdj = app.setAdj = -100; 4891 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4892 app.forcingToForeground = null; 4893 app.foregroundServices = false; 4894 app.hasShownUi = false; 4895 app.debugging = false; 4896 app.cached = false; 4897 4898 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4899 4900 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4901 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4902 4903 if (!normalMode) { 4904 Slog.i(TAG, "Launching preboot mode app: " + app); 4905 } 4906 4907 if (localLOGV) Slog.v( 4908 TAG, "New app record " + app 4909 + " thread=" + thread.asBinder() + " pid=" + pid); 4910 try { 4911 int testMode = IApplicationThread.DEBUG_OFF; 4912 if (mDebugApp != null && mDebugApp.equals(processName)) { 4913 testMode = mWaitForDebugger 4914 ? IApplicationThread.DEBUG_WAIT 4915 : IApplicationThread.DEBUG_ON; 4916 app.debugging = true; 4917 if (mDebugTransient) { 4918 mDebugApp = mOrigDebugApp; 4919 mWaitForDebugger = mOrigWaitForDebugger; 4920 } 4921 } 4922 String profileFile = app.instrumentationProfileFile; 4923 ParcelFileDescriptor profileFd = null; 4924 boolean profileAutoStop = false; 4925 if (mProfileApp != null && mProfileApp.equals(processName)) { 4926 mProfileProc = app; 4927 profileFile = mProfileFile; 4928 profileFd = mProfileFd; 4929 profileAutoStop = mAutoStopProfiler; 4930 } 4931 boolean enableOpenGlTrace = false; 4932 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4933 enableOpenGlTrace = true; 4934 mOpenGlTraceApp = null; 4935 } 4936 4937 // If the app is being launched for restore or full backup, set it up specially 4938 boolean isRestrictedBackupMode = false; 4939 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4940 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4941 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4942 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4943 } 4944 4945 ensurePackageDexOpt(app.instrumentationInfo != null 4946 ? app.instrumentationInfo.packageName 4947 : app.info.packageName); 4948 if (app.instrumentationClass != null) { 4949 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4950 } 4951 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4952 + processName + " with config " + mConfiguration); 4953 ApplicationInfo appInfo = app.instrumentationInfo != null 4954 ? app.instrumentationInfo : app.info; 4955 app.compat = compatibilityInfoForPackageLocked(appInfo); 4956 if (profileFd != null) { 4957 profileFd = profileFd.dup(); 4958 } 4959 thread.bindApplication(processName, appInfo, providers, 4960 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4961 app.instrumentationArguments, app.instrumentationWatcher, 4962 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4963 isRestrictedBackupMode || !normalMode, app.persistent, 4964 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4965 mCoreSettingsObserver.getCoreSettingsLocked()); 4966 updateLruProcessLocked(app, false, null); 4967 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4968 } catch (Exception e) { 4969 // todo: Yikes! What should we do? For now we will try to 4970 // start another process, but that could easily get us in 4971 // an infinite loop of restarting processes... 4972 Slog.w(TAG, "Exception thrown during bind!", e); 4973 4974 app.resetPackageList(mProcessStats); 4975 app.unlinkDeathRecipient(); 4976 startProcessLocked(app, "bind fail", processName); 4977 return false; 4978 } 4979 4980 // Remove this record from the list of starting applications. 4981 mPersistentStartingProcesses.remove(app); 4982 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4983 "Attach application locked removing on hold: " + app); 4984 mProcessesOnHold.remove(app); 4985 4986 boolean badApp = false; 4987 boolean didSomething = false; 4988 4989 // See if the top visible activity is waiting to run in this process... 4990 if (normalMode) { 4991 try { 4992 if (mStackSupervisor.attachApplicationLocked(app)) { 4993 didSomething = true; 4994 } 4995 } catch (Exception e) { 4996 badApp = true; 4997 } 4998 } 4999 5000 // Find any services that should be running in this process... 5001 if (!badApp) { 5002 try { 5003 didSomething |= mServices.attachApplicationLocked(app, processName); 5004 } catch (Exception e) { 5005 badApp = true; 5006 } 5007 } 5008 5009 // Check if a next-broadcast receiver is in this process... 5010 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5011 try { 5012 didSomething |= sendPendingBroadcastsLocked(app); 5013 } catch (Exception e) { 5014 // If the app died trying to launch the receiver we declare it 'bad' 5015 badApp = true; 5016 } 5017 } 5018 5019 // Check whether the next backup agent is in this process... 5020 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5021 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5022 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5023 try { 5024 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5025 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5026 mBackupTarget.backupMode); 5027 } catch (Exception e) { 5028 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5029 e.printStackTrace(); 5030 } 5031 } 5032 5033 if (badApp) { 5034 // todo: Also need to kill application to deal with all 5035 // kinds of exceptions. 5036 handleAppDiedLocked(app, false, true); 5037 return false; 5038 } 5039 5040 if (!didSomething) { 5041 updateOomAdjLocked(); 5042 } 5043 5044 return true; 5045 } 5046 5047 @Override 5048 public final void attachApplication(IApplicationThread thread) { 5049 synchronized (this) { 5050 int callingPid = Binder.getCallingPid(); 5051 final long origId = Binder.clearCallingIdentity(); 5052 attachApplicationLocked(thread, callingPid); 5053 Binder.restoreCallingIdentity(origId); 5054 } 5055 } 5056 5057 @Override 5058 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5059 final long origId = Binder.clearCallingIdentity(); 5060 synchronized (this) { 5061 ActivityStack stack = ActivityRecord.getStackLocked(token); 5062 if (stack != null) { 5063 ActivityRecord r = 5064 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5065 if (stopProfiling) { 5066 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5067 try { 5068 mProfileFd.close(); 5069 } catch (IOException e) { 5070 } 5071 clearProfilerLocked(); 5072 } 5073 } 5074 } 5075 } 5076 Binder.restoreCallingIdentity(origId); 5077 } 5078 5079 void enableScreenAfterBoot() { 5080 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5081 SystemClock.uptimeMillis()); 5082 mWindowManager.enableScreenAfterBoot(); 5083 5084 synchronized (this) { 5085 updateEventDispatchingLocked(); 5086 } 5087 } 5088 5089 @Override 5090 public void showBootMessage(final CharSequence msg, final boolean always) { 5091 enforceNotIsolatedCaller("showBootMessage"); 5092 mWindowManager.showBootMessage(msg, always); 5093 } 5094 5095 @Override 5096 public void dismissKeyguardOnNextActivity() { 5097 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5098 final long token = Binder.clearCallingIdentity(); 5099 try { 5100 synchronized (this) { 5101 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5102 if (mLockScreenShown) { 5103 mLockScreenShown = false; 5104 comeOutOfSleepIfNeededLocked(); 5105 } 5106 mStackSupervisor.setDismissKeyguard(true); 5107 } 5108 } finally { 5109 Binder.restoreCallingIdentity(token); 5110 } 5111 } 5112 5113 final void finishBooting() { 5114 IntentFilter pkgFilter = new IntentFilter(); 5115 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5116 pkgFilter.addDataScheme("package"); 5117 mContext.registerReceiver(new BroadcastReceiver() { 5118 @Override 5119 public void onReceive(Context context, Intent intent) { 5120 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5121 if (pkgs != null) { 5122 for (String pkg : pkgs) { 5123 synchronized (ActivityManagerService.this) { 5124 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0, 5125 "finished booting")) { 5126 setResultCode(Activity.RESULT_OK); 5127 return; 5128 } 5129 } 5130 } 5131 } 5132 } 5133 }, pkgFilter); 5134 5135 synchronized (this) { 5136 // Ensure that any processes we had put on hold are now started 5137 // up. 5138 final int NP = mProcessesOnHold.size(); 5139 if (NP > 0) { 5140 ArrayList<ProcessRecord> procs = 5141 new ArrayList<ProcessRecord>(mProcessesOnHold); 5142 for (int ip=0; ip<NP; ip++) { 5143 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5144 + procs.get(ip)); 5145 startProcessLocked(procs.get(ip), "on-hold", null); 5146 } 5147 } 5148 5149 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 5150 // Start looking for apps that are abusing wake locks. 5151 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5152 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5153 // Tell anyone interested that we are done booting! 5154 SystemProperties.set("sys.boot_completed", "1"); 5155 SystemProperties.set("dev.bootcomplete", "1"); 5156 for (int i=0; i<mStartedUsers.size(); i++) { 5157 UserStartedState uss = mStartedUsers.valueAt(i); 5158 if (uss.mState == UserStartedState.STATE_BOOTING) { 5159 uss.mState = UserStartedState.STATE_RUNNING; 5160 final int userId = mStartedUsers.keyAt(i); 5161 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5162 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5163 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5164 broadcastIntentLocked(null, null, intent, null, 5165 new IIntentReceiver.Stub() { 5166 @Override 5167 public void performReceive(Intent intent, int resultCode, 5168 String data, Bundle extras, boolean ordered, 5169 boolean sticky, int sendingUser) { 5170 synchronized (ActivityManagerService.this) { 5171 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5172 true, false); 5173 } 5174 } 5175 }, 5176 0, null, null, 5177 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5178 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5179 userId); 5180 } 5181 } 5182 } 5183 } 5184 } 5185 5186 final void ensureBootCompleted() { 5187 boolean booting; 5188 boolean enableScreen; 5189 synchronized (this) { 5190 booting = mBooting; 5191 mBooting = false; 5192 enableScreen = !mBooted; 5193 mBooted = true; 5194 } 5195 5196 if (booting) { 5197 finishBooting(); 5198 } 5199 5200 if (enableScreen) { 5201 enableScreenAfterBoot(); 5202 } 5203 } 5204 5205 @Override 5206 public final void activityResumed(IBinder token) { 5207 final long origId = Binder.clearCallingIdentity(); 5208 synchronized(this) { 5209 ActivityStack stack = ActivityRecord.getStackLocked(token); 5210 if (stack != null) { 5211 ActivityRecord.activityResumedLocked(token); 5212 } 5213 } 5214 Binder.restoreCallingIdentity(origId); 5215 } 5216 5217 @Override 5218 public final void activityPaused(IBinder token) { 5219 final long origId = Binder.clearCallingIdentity(); 5220 synchronized(this) { 5221 ActivityStack stack = ActivityRecord.getStackLocked(token); 5222 if (stack != null) { 5223 stack.activityPausedLocked(token, false); 5224 } 5225 } 5226 Binder.restoreCallingIdentity(origId); 5227 } 5228 5229 @Override 5230 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5231 CharSequence description) { 5232 if (localLOGV) Slog.v( 5233 TAG, "Activity stopped: token=" + token); 5234 5235 // Refuse possible leaked file descriptors 5236 if (icicle != null && icicle.hasFileDescriptors()) { 5237 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5238 } 5239 5240 ActivityRecord r = null; 5241 5242 final long origId = Binder.clearCallingIdentity(); 5243 5244 synchronized (this) { 5245 r = ActivityRecord.isInStackLocked(token); 5246 if (r != null) { 5247 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5248 } 5249 } 5250 5251 if (r != null) { 5252 sendPendingThumbnail(r, null, null, null, false); 5253 } 5254 5255 trimApplications(); 5256 5257 Binder.restoreCallingIdentity(origId); 5258 } 5259 5260 @Override 5261 public final void activityDestroyed(IBinder token) { 5262 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5263 synchronized (this) { 5264 ActivityStack stack = ActivityRecord.getStackLocked(token); 5265 if (stack != null) { 5266 stack.activityDestroyedLocked(token); 5267 } 5268 } 5269 } 5270 5271 @Override 5272 public String getCallingPackage(IBinder token) { 5273 synchronized (this) { 5274 ActivityRecord r = getCallingRecordLocked(token); 5275 return r != null ? r.info.packageName : null; 5276 } 5277 } 5278 5279 @Override 5280 public ComponentName getCallingActivity(IBinder token) { 5281 synchronized (this) { 5282 ActivityRecord r = getCallingRecordLocked(token); 5283 return r != null ? r.intent.getComponent() : null; 5284 } 5285 } 5286 5287 private ActivityRecord getCallingRecordLocked(IBinder token) { 5288 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5289 if (r == null) { 5290 return null; 5291 } 5292 return r.resultTo; 5293 } 5294 5295 @Override 5296 public ComponentName getActivityClassForToken(IBinder token) { 5297 synchronized(this) { 5298 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5299 if (r == null) { 5300 return null; 5301 } 5302 return r.intent.getComponent(); 5303 } 5304 } 5305 5306 @Override 5307 public String getPackageForToken(IBinder token) { 5308 synchronized(this) { 5309 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5310 if (r == null) { 5311 return null; 5312 } 5313 return r.packageName; 5314 } 5315 } 5316 5317 @Override 5318 public IIntentSender getIntentSender(int type, 5319 String packageName, IBinder token, String resultWho, 5320 int requestCode, Intent[] intents, String[] resolvedTypes, 5321 int flags, Bundle options, int userId) { 5322 enforceNotIsolatedCaller("getIntentSender"); 5323 // Refuse possible leaked file descriptors 5324 if (intents != null) { 5325 if (intents.length < 1) { 5326 throw new IllegalArgumentException("Intents array length must be >= 1"); 5327 } 5328 for (int i=0; i<intents.length; i++) { 5329 Intent intent = intents[i]; 5330 if (intent != null) { 5331 if (intent.hasFileDescriptors()) { 5332 throw new IllegalArgumentException("File descriptors passed in Intent"); 5333 } 5334 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5335 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5336 throw new IllegalArgumentException( 5337 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5338 } 5339 intents[i] = new Intent(intent); 5340 } 5341 } 5342 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5343 throw new IllegalArgumentException( 5344 "Intent array length does not match resolvedTypes length"); 5345 } 5346 } 5347 if (options != null) { 5348 if (options.hasFileDescriptors()) { 5349 throw new IllegalArgumentException("File descriptors passed in options"); 5350 } 5351 } 5352 5353 synchronized(this) { 5354 int callingUid = Binder.getCallingUid(); 5355 int origUserId = userId; 5356 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5357 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5358 "getIntentSender", null); 5359 if (origUserId == UserHandle.USER_CURRENT) { 5360 // We don't want to evaluate this until the pending intent is 5361 // actually executed. However, we do want to always do the 5362 // security checking for it above. 5363 userId = UserHandle.USER_CURRENT; 5364 } 5365 try { 5366 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5367 int uid = AppGlobals.getPackageManager() 5368 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5369 if (!UserHandle.isSameApp(callingUid, uid)) { 5370 String msg = "Permission Denial: getIntentSender() from pid=" 5371 + Binder.getCallingPid() 5372 + ", uid=" + Binder.getCallingUid() 5373 + ", (need uid=" + uid + ")" 5374 + " is not allowed to send as package " + packageName; 5375 Slog.w(TAG, msg); 5376 throw new SecurityException(msg); 5377 } 5378 } 5379 5380 return getIntentSenderLocked(type, packageName, callingUid, userId, 5381 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5382 5383 } catch (RemoteException e) { 5384 throw new SecurityException(e); 5385 } 5386 } 5387 } 5388 5389 IIntentSender getIntentSenderLocked(int type, String packageName, 5390 int callingUid, int userId, IBinder token, String resultWho, 5391 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5392 Bundle options) { 5393 if (DEBUG_MU) 5394 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5395 ActivityRecord activity = null; 5396 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5397 activity = ActivityRecord.isInStackLocked(token); 5398 if (activity == null) { 5399 return null; 5400 } 5401 if (activity.finishing) { 5402 return null; 5403 } 5404 } 5405 5406 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5407 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5408 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5409 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5410 |PendingIntent.FLAG_UPDATE_CURRENT); 5411 5412 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5413 type, packageName, activity, resultWho, 5414 requestCode, intents, resolvedTypes, flags, options, userId); 5415 WeakReference<PendingIntentRecord> ref; 5416 ref = mIntentSenderRecords.get(key); 5417 PendingIntentRecord rec = ref != null ? ref.get() : null; 5418 if (rec != null) { 5419 if (!cancelCurrent) { 5420 if (updateCurrent) { 5421 if (rec.key.requestIntent != null) { 5422 rec.key.requestIntent.replaceExtras(intents != null ? 5423 intents[intents.length - 1] : null); 5424 } 5425 if (intents != null) { 5426 intents[intents.length-1] = rec.key.requestIntent; 5427 rec.key.allIntents = intents; 5428 rec.key.allResolvedTypes = resolvedTypes; 5429 } else { 5430 rec.key.allIntents = null; 5431 rec.key.allResolvedTypes = null; 5432 } 5433 } 5434 return rec; 5435 } 5436 rec.canceled = true; 5437 mIntentSenderRecords.remove(key); 5438 } 5439 if (noCreate) { 5440 return rec; 5441 } 5442 rec = new PendingIntentRecord(this, key, callingUid); 5443 mIntentSenderRecords.put(key, rec.ref); 5444 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5445 if (activity.pendingResults == null) { 5446 activity.pendingResults 5447 = new HashSet<WeakReference<PendingIntentRecord>>(); 5448 } 5449 activity.pendingResults.add(rec.ref); 5450 } 5451 return rec; 5452 } 5453 5454 @Override 5455 public void cancelIntentSender(IIntentSender sender) { 5456 if (!(sender instanceof PendingIntentRecord)) { 5457 return; 5458 } 5459 synchronized(this) { 5460 PendingIntentRecord rec = (PendingIntentRecord)sender; 5461 try { 5462 int uid = AppGlobals.getPackageManager() 5463 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5464 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5465 String msg = "Permission Denial: cancelIntentSender() from pid=" 5466 + Binder.getCallingPid() 5467 + ", uid=" + Binder.getCallingUid() 5468 + " is not allowed to cancel packges " 5469 + rec.key.packageName; 5470 Slog.w(TAG, msg); 5471 throw new SecurityException(msg); 5472 } 5473 } catch (RemoteException e) { 5474 throw new SecurityException(e); 5475 } 5476 cancelIntentSenderLocked(rec, true); 5477 } 5478 } 5479 5480 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5481 rec.canceled = true; 5482 mIntentSenderRecords.remove(rec.key); 5483 if (cleanActivity && rec.key.activity != null) { 5484 rec.key.activity.pendingResults.remove(rec.ref); 5485 } 5486 } 5487 5488 @Override 5489 public String getPackageForIntentSender(IIntentSender pendingResult) { 5490 if (!(pendingResult instanceof PendingIntentRecord)) { 5491 return null; 5492 } 5493 try { 5494 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5495 return res.key.packageName; 5496 } catch (ClassCastException e) { 5497 } 5498 return null; 5499 } 5500 5501 @Override 5502 public int getUidForIntentSender(IIntentSender sender) { 5503 if (sender instanceof PendingIntentRecord) { 5504 try { 5505 PendingIntentRecord res = (PendingIntentRecord)sender; 5506 return res.uid; 5507 } catch (ClassCastException e) { 5508 } 5509 } 5510 return -1; 5511 } 5512 5513 @Override 5514 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5515 if (!(pendingResult instanceof PendingIntentRecord)) { 5516 return false; 5517 } 5518 try { 5519 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5520 if (res.key.allIntents == null) { 5521 return false; 5522 } 5523 for (int i=0; i<res.key.allIntents.length; i++) { 5524 Intent intent = res.key.allIntents[i]; 5525 if (intent.getPackage() != null && intent.getComponent() != null) { 5526 return false; 5527 } 5528 } 5529 return true; 5530 } catch (ClassCastException e) { 5531 } 5532 return false; 5533 } 5534 5535 @Override 5536 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5537 if (!(pendingResult instanceof PendingIntentRecord)) { 5538 return false; 5539 } 5540 try { 5541 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5542 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5543 return true; 5544 } 5545 return false; 5546 } catch (ClassCastException e) { 5547 } 5548 return false; 5549 } 5550 5551 @Override 5552 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5553 if (!(pendingResult instanceof PendingIntentRecord)) { 5554 return null; 5555 } 5556 try { 5557 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5558 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5559 } catch (ClassCastException e) { 5560 } 5561 return null; 5562 } 5563 5564 @Override 5565 public void setProcessLimit(int max) { 5566 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5567 "setProcessLimit()"); 5568 synchronized (this) { 5569 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5570 mProcessLimitOverride = max; 5571 } 5572 trimApplications(); 5573 } 5574 5575 @Override 5576 public int getProcessLimit() { 5577 synchronized (this) { 5578 return mProcessLimitOverride; 5579 } 5580 } 5581 5582 void foregroundTokenDied(ForegroundToken token) { 5583 synchronized (ActivityManagerService.this) { 5584 synchronized (mPidsSelfLocked) { 5585 ForegroundToken cur 5586 = mForegroundProcesses.get(token.pid); 5587 if (cur != token) { 5588 return; 5589 } 5590 mForegroundProcesses.remove(token.pid); 5591 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5592 if (pr == null) { 5593 return; 5594 } 5595 pr.forcingToForeground = null; 5596 pr.foregroundServices = false; 5597 } 5598 updateOomAdjLocked(); 5599 } 5600 } 5601 5602 @Override 5603 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5604 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5605 "setProcessForeground()"); 5606 synchronized(this) { 5607 boolean changed = false; 5608 5609 synchronized (mPidsSelfLocked) { 5610 ProcessRecord pr = mPidsSelfLocked.get(pid); 5611 if (pr == null && isForeground) { 5612 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5613 return; 5614 } 5615 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5616 if (oldToken != null) { 5617 oldToken.token.unlinkToDeath(oldToken, 0); 5618 mForegroundProcesses.remove(pid); 5619 if (pr != null) { 5620 pr.forcingToForeground = null; 5621 } 5622 changed = true; 5623 } 5624 if (isForeground && token != null) { 5625 ForegroundToken newToken = new ForegroundToken() { 5626 @Override 5627 public void binderDied() { 5628 foregroundTokenDied(this); 5629 } 5630 }; 5631 newToken.pid = pid; 5632 newToken.token = token; 5633 try { 5634 token.linkToDeath(newToken, 0); 5635 mForegroundProcesses.put(pid, newToken); 5636 pr.forcingToForeground = token; 5637 changed = true; 5638 } catch (RemoteException e) { 5639 // If the process died while doing this, we will later 5640 // do the cleanup with the process death link. 5641 } 5642 } 5643 } 5644 5645 if (changed) { 5646 updateOomAdjLocked(); 5647 } 5648 } 5649 } 5650 5651 // ========================================================= 5652 // PERMISSIONS 5653 // ========================================================= 5654 5655 static class PermissionController extends IPermissionController.Stub { 5656 ActivityManagerService mActivityManagerService; 5657 PermissionController(ActivityManagerService activityManagerService) { 5658 mActivityManagerService = activityManagerService; 5659 } 5660 5661 @Override 5662 public boolean checkPermission(String permission, int pid, int uid) { 5663 return mActivityManagerService.checkPermission(permission, pid, 5664 uid) == PackageManager.PERMISSION_GRANTED; 5665 } 5666 } 5667 5668 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5669 @Override 5670 public int checkComponentPermission(String permission, int pid, int uid, 5671 int owningUid, boolean exported) { 5672 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5673 owningUid, exported); 5674 } 5675 5676 @Override 5677 public Object getAMSLock() { 5678 return ActivityManagerService.this; 5679 } 5680 } 5681 5682 /** 5683 * This can be called with or without the global lock held. 5684 */ 5685 int checkComponentPermission(String permission, int pid, int uid, 5686 int owningUid, boolean exported) { 5687 // We might be performing an operation on behalf of an indirect binder 5688 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5689 // client identity accordingly before proceeding. 5690 Identity tlsIdentity = sCallerIdentity.get(); 5691 if (tlsIdentity != null) { 5692 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5693 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5694 uid = tlsIdentity.uid; 5695 pid = tlsIdentity.pid; 5696 } 5697 5698 if (pid == MY_PID) { 5699 return PackageManager.PERMISSION_GRANTED; 5700 } 5701 5702 return ActivityManager.checkComponentPermission(permission, uid, 5703 owningUid, exported); 5704 } 5705 5706 /** 5707 * As the only public entry point for permissions checking, this method 5708 * can enforce the semantic that requesting a check on a null global 5709 * permission is automatically denied. (Internally a null permission 5710 * string is used when calling {@link #checkComponentPermission} in cases 5711 * when only uid-based security is needed.) 5712 * 5713 * This can be called with or without the global lock held. 5714 */ 5715 @Override 5716 public int checkPermission(String permission, int pid, int uid) { 5717 if (permission == null) { 5718 return PackageManager.PERMISSION_DENIED; 5719 } 5720 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5721 } 5722 5723 /** 5724 * Binder IPC calls go through the public entry point. 5725 * This can be called with or without the global lock held. 5726 */ 5727 int checkCallingPermission(String permission) { 5728 return checkPermission(permission, 5729 Binder.getCallingPid(), 5730 UserHandle.getAppId(Binder.getCallingUid())); 5731 } 5732 5733 /** 5734 * This can be called with or without the global lock held. 5735 */ 5736 void enforceCallingPermission(String permission, String func) { 5737 if (checkCallingPermission(permission) 5738 == PackageManager.PERMISSION_GRANTED) { 5739 return; 5740 } 5741 5742 String msg = "Permission Denial: " + func + " from pid=" 5743 + Binder.getCallingPid() 5744 + ", uid=" + Binder.getCallingUid() 5745 + " requires " + permission; 5746 Slog.w(TAG, msg); 5747 throw new SecurityException(msg); 5748 } 5749 5750 /** 5751 * Determine if UID is holding permissions required to access {@link Uri} in 5752 * the given {@link ProviderInfo}. Final permission checking is always done 5753 * in {@link ContentProvider}. 5754 */ 5755 private final boolean checkHoldingPermissionsLocked( 5756 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5757 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5758 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5759 5760 if (pi.applicationInfo.uid == uid) { 5761 return true; 5762 } else if (!pi.exported) { 5763 return false; 5764 } 5765 5766 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5767 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5768 try { 5769 // check if target holds top-level <provider> permissions 5770 if (!readMet && pi.readPermission != null 5771 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5772 readMet = true; 5773 } 5774 if (!writeMet && pi.writePermission != null 5775 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5776 writeMet = true; 5777 } 5778 5779 // track if unprotected read/write is allowed; any denied 5780 // <path-permission> below removes this ability 5781 boolean allowDefaultRead = pi.readPermission == null; 5782 boolean allowDefaultWrite = pi.writePermission == null; 5783 5784 // check if target holds any <path-permission> that match uri 5785 final PathPermission[] pps = pi.pathPermissions; 5786 if (pps != null) { 5787 final String path = uri.getPath(); 5788 int i = pps.length; 5789 while (i > 0 && (!readMet || !writeMet)) { 5790 i--; 5791 PathPermission pp = pps[i]; 5792 if (pp.match(path)) { 5793 if (!readMet) { 5794 final String pprperm = pp.getReadPermission(); 5795 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5796 + pprperm + " for " + pp.getPath() 5797 + ": match=" + pp.match(path) 5798 + " check=" + pm.checkUidPermission(pprperm, uid)); 5799 if (pprperm != null) { 5800 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5801 readMet = true; 5802 } else { 5803 allowDefaultRead = false; 5804 } 5805 } 5806 } 5807 if (!writeMet) { 5808 final String ppwperm = pp.getWritePermission(); 5809 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5810 + ppwperm + " for " + pp.getPath() 5811 + ": match=" + pp.match(path) 5812 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5813 if (ppwperm != null) { 5814 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5815 writeMet = true; 5816 } else { 5817 allowDefaultWrite = false; 5818 } 5819 } 5820 } 5821 } 5822 } 5823 } 5824 5825 // grant unprotected <provider> read/write, if not blocked by 5826 // <path-permission> above 5827 if (allowDefaultRead) readMet = true; 5828 if (allowDefaultWrite) writeMet = true; 5829 5830 } catch (RemoteException e) { 5831 return false; 5832 } 5833 5834 return readMet && writeMet; 5835 } 5836 5837 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5838 ProviderInfo pi = null; 5839 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5840 if (cpr != null) { 5841 pi = cpr.info; 5842 } else { 5843 try { 5844 pi = AppGlobals.getPackageManager().resolveContentProvider( 5845 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5846 } catch (RemoteException ex) { 5847 } 5848 } 5849 return pi; 5850 } 5851 5852 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5853 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5854 if (targetUris != null) { 5855 return targetUris.get(uri); 5856 } else { 5857 return null; 5858 } 5859 } 5860 5861 private UriPermission findOrCreateUriPermissionLocked( 5862 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5863 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5864 if (targetUris == null) { 5865 targetUris = Maps.newArrayMap(); 5866 mGrantedUriPermissions.put(targetUid, targetUris); 5867 } 5868 5869 UriPermission perm = targetUris.get(uri); 5870 if (perm == null) { 5871 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5872 targetUris.put(uri, perm); 5873 } 5874 5875 return perm; 5876 } 5877 5878 private final boolean checkUriPermissionLocked( 5879 Uri uri, int uid, int modeFlags, int minStrength) { 5880 // Root gets to do everything. 5881 if (uid == 0) { 5882 return true; 5883 } 5884 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5885 if (perms == null) return false; 5886 UriPermission perm = perms.get(uri); 5887 if (perm == null) return false; 5888 return perm.getStrength(modeFlags) >= minStrength; 5889 } 5890 5891 @Override 5892 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5893 enforceNotIsolatedCaller("checkUriPermission"); 5894 5895 // Another redirected-binder-call permissions check as in 5896 // {@link checkComponentPermission}. 5897 Identity tlsIdentity = sCallerIdentity.get(); 5898 if (tlsIdentity != null) { 5899 uid = tlsIdentity.uid; 5900 pid = tlsIdentity.pid; 5901 } 5902 5903 // Our own process gets to do everything. 5904 if (pid == MY_PID) { 5905 return PackageManager.PERMISSION_GRANTED; 5906 } 5907 synchronized(this) { 5908 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5909 ? PackageManager.PERMISSION_GRANTED 5910 : PackageManager.PERMISSION_DENIED; 5911 } 5912 } 5913 5914 /** 5915 * Check if the targetPkg can be granted permission to access uri by 5916 * the callingUid using the given modeFlags. Throws a security exception 5917 * if callingUid is not allowed to do this. Returns the uid of the target 5918 * if the URI permission grant should be performed; returns -1 if it is not 5919 * needed (for example targetPkg already has permission to access the URI). 5920 * If you already know the uid of the target, you can supply it in 5921 * lastTargetUid else set that to -1. 5922 */ 5923 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5924 Uri uri, int modeFlags, int lastTargetUid) { 5925 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5926 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5927 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5928 if (modeFlags == 0) { 5929 return -1; 5930 } 5931 5932 if (targetPkg != null) { 5933 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5934 "Checking grant " + targetPkg + " permission to " + uri); 5935 } 5936 5937 final IPackageManager pm = AppGlobals.getPackageManager(); 5938 5939 // If this is not a content: uri, we can't do anything with it. 5940 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5941 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5942 "Can't grant URI permission for non-content URI: " + uri); 5943 return -1; 5944 } 5945 5946 final String authority = uri.getAuthority(); 5947 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 5948 if (pi == null) { 5949 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5950 return -1; 5951 } 5952 5953 int targetUid = lastTargetUid; 5954 if (targetUid < 0 && targetPkg != null) { 5955 try { 5956 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5957 if (targetUid < 0) { 5958 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5959 "Can't grant URI permission no uid for: " + targetPkg); 5960 return -1; 5961 } 5962 } catch (RemoteException ex) { 5963 return -1; 5964 } 5965 } 5966 5967 if (targetUid >= 0) { 5968 // First... does the target actually need this permission? 5969 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5970 // No need to grant the target this permission. 5971 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5972 "Target " + targetPkg + " already has full permission to " + uri); 5973 return -1; 5974 } 5975 } else { 5976 // First... there is no target package, so can anyone access it? 5977 boolean allowed = pi.exported; 5978 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5979 if (pi.readPermission != null) { 5980 allowed = false; 5981 } 5982 } 5983 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5984 if (pi.writePermission != null) { 5985 allowed = false; 5986 } 5987 } 5988 if (allowed) { 5989 return -1; 5990 } 5991 } 5992 5993 // Second... is the provider allowing granting of URI permissions? 5994 if (!pi.grantUriPermissions) { 5995 throw new SecurityException("Provider " + pi.packageName 5996 + "/" + pi.name 5997 + " does not allow granting of Uri permissions (uri " 5998 + uri + ")"); 5999 } 6000 if (pi.uriPermissionPatterns != null) { 6001 final int N = pi.uriPermissionPatterns.length; 6002 boolean allowed = false; 6003 for (int i=0; i<N; i++) { 6004 if (pi.uriPermissionPatterns[i] != null 6005 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6006 allowed = true; 6007 break; 6008 } 6009 } 6010 if (!allowed) { 6011 throw new SecurityException("Provider " + pi.packageName 6012 + "/" + pi.name 6013 + " does not allow granting of permission to path of Uri " 6014 + uri); 6015 } 6016 } 6017 6018 // Third... does the caller itself have permission to access 6019 // this uri? 6020 if (callingUid != Process.myUid()) { 6021 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6022 // Require they hold a strong enough Uri permission 6023 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6024 : UriPermission.STRENGTH_OWNED; 6025 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6026 throw new SecurityException("Uid " + callingUid 6027 + " does not have permission to uri " + uri); 6028 } 6029 } 6030 } 6031 6032 return targetUid; 6033 } 6034 6035 @Override 6036 public int checkGrantUriPermission(int callingUid, String targetPkg, 6037 Uri uri, int modeFlags) { 6038 enforceNotIsolatedCaller("checkGrantUriPermission"); 6039 synchronized(this) { 6040 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6041 } 6042 } 6043 6044 void grantUriPermissionUncheckedLocked( 6045 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6046 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6047 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6048 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6049 if (modeFlags == 0) { 6050 return; 6051 } 6052 6053 // So here we are: the caller has the assumed permission 6054 // to the uri, and the target doesn't. Let's now give this to 6055 // the target. 6056 6057 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6058 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6059 6060 final String authority = uri.getAuthority(); 6061 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6062 if (pi == null) { 6063 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6064 return; 6065 } 6066 6067 final UriPermission perm = findOrCreateUriPermissionLocked( 6068 pi.packageName, targetPkg, targetUid, uri); 6069 perm.grantModes(modeFlags, persistable, owner); 6070 } 6071 6072 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6073 int modeFlags, UriPermissionOwner owner) { 6074 if (targetPkg == null) { 6075 throw new NullPointerException("targetPkg"); 6076 } 6077 6078 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6079 if (targetUid < 0) { 6080 return; 6081 } 6082 6083 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6084 } 6085 6086 static class NeededUriGrants extends ArrayList<Uri> { 6087 final String targetPkg; 6088 final int targetUid; 6089 final int flags; 6090 6091 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6092 this.targetPkg = targetPkg; 6093 this.targetUid = targetUid; 6094 this.flags = flags; 6095 } 6096 } 6097 6098 /** 6099 * Like checkGrantUriPermissionLocked, but takes an Intent. 6100 */ 6101 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6102 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6103 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6104 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6105 + " clip=" + (intent != null ? intent.getClipData() : null) 6106 + " from " + intent + "; flags=0x" 6107 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6108 6109 if (targetPkg == null) { 6110 throw new NullPointerException("targetPkg"); 6111 } 6112 6113 if (intent == null) { 6114 return null; 6115 } 6116 Uri data = intent.getData(); 6117 ClipData clip = intent.getClipData(); 6118 if (data == null && clip == null) { 6119 return null; 6120 } 6121 6122 if (data != null) { 6123 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6124 mode, needed != null ? needed.targetUid : -1); 6125 if (targetUid > 0) { 6126 if (needed == null) { 6127 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6128 } 6129 needed.add(data); 6130 } 6131 } 6132 if (clip != null) { 6133 for (int i=0; i<clip.getItemCount(); i++) { 6134 Uri uri = clip.getItemAt(i).getUri(); 6135 if (uri != null) { 6136 int targetUid = -1; 6137 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6138 mode, needed != null ? needed.targetUid : -1); 6139 if (targetUid > 0) { 6140 if (needed == null) { 6141 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6142 } 6143 needed.add(uri); 6144 } 6145 } else { 6146 Intent clipIntent = clip.getItemAt(i).getIntent(); 6147 if (clipIntent != null) { 6148 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6149 callingUid, targetPkg, clipIntent, mode, needed); 6150 if (newNeeded != null) { 6151 needed = newNeeded; 6152 } 6153 } 6154 } 6155 } 6156 } 6157 6158 return needed; 6159 } 6160 6161 /** 6162 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6163 */ 6164 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6165 UriPermissionOwner owner) { 6166 if (needed != null) { 6167 for (int i=0; i<needed.size(); i++) { 6168 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6169 needed.get(i), needed.flags, owner); 6170 } 6171 } 6172 } 6173 6174 void grantUriPermissionFromIntentLocked(int callingUid, 6175 String targetPkg, Intent intent, UriPermissionOwner owner) { 6176 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6177 intent, intent != null ? intent.getFlags() : 0, null); 6178 if (needed == null) { 6179 return; 6180 } 6181 6182 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6183 } 6184 6185 @Override 6186 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6187 Uri uri, int modeFlags) { 6188 enforceNotIsolatedCaller("grantUriPermission"); 6189 synchronized(this) { 6190 final ProcessRecord r = getRecordForAppLocked(caller); 6191 if (r == null) { 6192 throw new SecurityException("Unable to find app for caller " 6193 + caller 6194 + " when granting permission to uri " + uri); 6195 } 6196 if (targetPkg == null) { 6197 throw new IllegalArgumentException("null target"); 6198 } 6199 if (uri == null) { 6200 throw new IllegalArgumentException("null uri"); 6201 } 6202 6203 // Persistable only supported through Intents 6204 Preconditions.checkFlagsArgument(modeFlags, 6205 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6206 6207 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6208 null); 6209 } 6210 } 6211 6212 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6213 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6214 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6215 ArrayMap<Uri, UriPermission> perms 6216 = mGrantedUriPermissions.get(perm.targetUid); 6217 if (perms != null) { 6218 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6219 "Removing " + perm.targetUid + " permission to " + perm.uri); 6220 perms.remove(perm.uri); 6221 if (perms.size() == 0) { 6222 mGrantedUriPermissions.remove(perm.targetUid); 6223 } 6224 } 6225 } 6226 } 6227 6228 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6229 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6230 6231 final IPackageManager pm = AppGlobals.getPackageManager(); 6232 final String authority = uri.getAuthority(); 6233 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6234 if (pi == null) { 6235 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6236 return; 6237 } 6238 6239 // Does the caller have this permission on the URI? 6240 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6241 // Right now, if you are not the original owner of the permission, 6242 // you are not allowed to revoke it. 6243 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6244 throw new SecurityException("Uid " + callingUid 6245 + " does not have permission to uri " + uri); 6246 //} 6247 } 6248 6249 boolean persistChanged = false; 6250 6251 // Go through all of the permissions and remove any that match. 6252 final List<String> SEGMENTS = uri.getPathSegments(); 6253 if (SEGMENTS != null) { 6254 final int NS = SEGMENTS.size(); 6255 int N = mGrantedUriPermissions.size(); 6256 for (int i=0; i<N; i++) { 6257 ArrayMap<Uri, UriPermission> perms 6258 = mGrantedUriPermissions.valueAt(i); 6259 Iterator<UriPermission> it = perms.values().iterator(); 6260 toploop: 6261 while (it.hasNext()) { 6262 UriPermission perm = it.next(); 6263 Uri targetUri = perm.uri; 6264 if (!authority.equals(targetUri.getAuthority())) { 6265 continue; 6266 } 6267 List<String> targetSegments = targetUri.getPathSegments(); 6268 if (targetSegments == null) { 6269 continue; 6270 } 6271 if (targetSegments.size() < NS) { 6272 continue; 6273 } 6274 for (int j=0; j<NS; j++) { 6275 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6276 continue toploop; 6277 } 6278 } 6279 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6280 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6281 persistChanged |= perm.clearModes(modeFlags, true); 6282 if (perm.modeFlags == 0) { 6283 it.remove(); 6284 } 6285 } 6286 if (perms.size() == 0) { 6287 mGrantedUriPermissions.remove( 6288 mGrantedUriPermissions.keyAt(i)); 6289 N--; 6290 i--; 6291 } 6292 } 6293 } 6294 6295 if (persistChanged) { 6296 schedulePersistUriGrants(); 6297 } 6298 } 6299 6300 @Override 6301 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6302 int modeFlags) { 6303 enforceNotIsolatedCaller("revokeUriPermission"); 6304 synchronized(this) { 6305 final ProcessRecord r = getRecordForAppLocked(caller); 6306 if (r == null) { 6307 throw new SecurityException("Unable to find app for caller " 6308 + caller 6309 + " when revoking permission to uri " + uri); 6310 } 6311 if (uri == null) { 6312 Slog.w(TAG, "revokeUriPermission: null uri"); 6313 return; 6314 } 6315 6316 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6317 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6318 if (modeFlags == 0) { 6319 return; 6320 } 6321 6322 final IPackageManager pm = AppGlobals.getPackageManager(); 6323 final String authority = uri.getAuthority(); 6324 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6325 if (pi == null) { 6326 Slog.w(TAG, "No content provider found for permission revoke: " 6327 + uri.toSafeString()); 6328 return; 6329 } 6330 6331 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6332 } 6333 } 6334 6335 /** 6336 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6337 * given package. 6338 * 6339 * @param packageName Package name to match, or {@code null} to apply to all 6340 * packages. 6341 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6342 * to all users. 6343 * @param persistable If persistable grants should be removed. 6344 */ 6345 private void removeUriPermissionsForPackageLocked( 6346 String packageName, int userHandle, boolean persistable) { 6347 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6348 throw new IllegalArgumentException("Must narrow by either package or user"); 6349 } 6350 6351 boolean persistChanged = false; 6352 6353 final int size = mGrantedUriPermissions.size(); 6354 for (int i = 0; i < size; i++) { 6355 // Only inspect grants matching user 6356 if (userHandle == UserHandle.USER_ALL 6357 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6358 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6359 .values().iterator(); 6360 while (it.hasNext()) { 6361 final UriPermission perm = it.next(); 6362 6363 // Only inspect grants matching package 6364 if (packageName == null || perm.sourcePkg.equals(packageName) 6365 || perm.targetPkg.equals(packageName)) { 6366 persistChanged |= perm.clearModes(~0, persistable); 6367 6368 // Only remove when no modes remain; any persisted grants 6369 // will keep this alive. 6370 if (perm.modeFlags == 0) { 6371 it.remove(); 6372 } 6373 } 6374 } 6375 } 6376 } 6377 6378 if (persistChanged) { 6379 schedulePersistUriGrants(); 6380 } 6381 } 6382 6383 @Override 6384 public IBinder newUriPermissionOwner(String name) { 6385 enforceNotIsolatedCaller("newUriPermissionOwner"); 6386 synchronized(this) { 6387 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6388 return owner.getExternalTokenLocked(); 6389 } 6390 } 6391 6392 @Override 6393 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6394 Uri uri, int modeFlags) { 6395 synchronized(this) { 6396 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6397 if (owner == null) { 6398 throw new IllegalArgumentException("Unknown owner: " + token); 6399 } 6400 if (fromUid != Binder.getCallingUid()) { 6401 if (Binder.getCallingUid() != Process.myUid()) { 6402 // Only system code can grant URI permissions on behalf 6403 // of other users. 6404 throw new SecurityException("nice try"); 6405 } 6406 } 6407 if (targetPkg == null) { 6408 throw new IllegalArgumentException("null target"); 6409 } 6410 if (uri == null) { 6411 throw new IllegalArgumentException("null uri"); 6412 } 6413 6414 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6415 } 6416 } 6417 6418 @Override 6419 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6420 synchronized(this) { 6421 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6422 if (owner == null) { 6423 throw new IllegalArgumentException("Unknown owner: " + token); 6424 } 6425 6426 if (uri == null) { 6427 owner.removeUriPermissionsLocked(mode); 6428 } else { 6429 owner.removeUriPermissionLocked(uri, mode); 6430 } 6431 } 6432 } 6433 6434 private void schedulePersistUriGrants() { 6435 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6436 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6437 10 * DateUtils.SECOND_IN_MILLIS); 6438 } 6439 } 6440 6441 private void writeGrantedUriPermissions() { 6442 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6443 6444 // Snapshot permissions so we can persist without lock 6445 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6446 synchronized (this) { 6447 final int size = mGrantedUriPermissions.size(); 6448 for (int i = 0 ; i < size; i++) { 6449 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6450 if (perm.persistedModeFlags != 0) { 6451 persist.add(perm.snapshot()); 6452 } 6453 } 6454 } 6455 } 6456 6457 FileOutputStream fos = null; 6458 try { 6459 fos = mGrantFile.startWrite(); 6460 6461 XmlSerializer out = new FastXmlSerializer(); 6462 out.setOutput(fos, "utf-8"); 6463 out.startDocument(null, true); 6464 out.startTag(null, TAG_URI_GRANTS); 6465 for (UriPermission.Snapshot perm : persist) { 6466 out.startTag(null, TAG_URI_GRANT); 6467 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6468 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6469 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6470 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6471 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6472 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6473 out.endTag(null, TAG_URI_GRANT); 6474 } 6475 out.endTag(null, TAG_URI_GRANTS); 6476 out.endDocument(); 6477 6478 mGrantFile.finishWrite(fos); 6479 } catch (IOException e) { 6480 if (fos != null) { 6481 mGrantFile.failWrite(fos); 6482 } 6483 } 6484 } 6485 6486 private void readGrantedUriPermissionsLocked() { 6487 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6488 6489 final long now = System.currentTimeMillis(); 6490 6491 FileInputStream fis = null; 6492 try { 6493 fis = mGrantFile.openRead(); 6494 final XmlPullParser in = Xml.newPullParser(); 6495 in.setInput(fis, null); 6496 6497 int type; 6498 while ((type = in.next()) != END_DOCUMENT) { 6499 final String tag = in.getName(); 6500 if (type == START_TAG) { 6501 if (TAG_URI_GRANT.equals(tag)) { 6502 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6503 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6504 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6505 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6506 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6507 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6508 6509 // Sanity check that provider still belongs to source package 6510 final ProviderInfo pi = getProviderInfoLocked( 6511 uri.getAuthority(), userHandle); 6512 if (pi != null && sourcePkg.equals(pi.packageName)) { 6513 int targetUid = -1; 6514 try { 6515 targetUid = AppGlobals.getPackageManager() 6516 .getPackageUid(targetPkg, userHandle); 6517 } catch (RemoteException e) { 6518 } 6519 if (targetUid != -1) { 6520 final UriPermission perm = findOrCreateUriPermissionLocked( 6521 sourcePkg, targetPkg, targetUid, uri); 6522 perm.initPersistedModes(modeFlags, createdTime); 6523 } 6524 } else { 6525 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6526 + " but instead found " + pi); 6527 } 6528 } 6529 } 6530 } 6531 } catch (FileNotFoundException e) { 6532 // Missing grants is okay 6533 } catch (IOException e) { 6534 Log.wtf(TAG, "Failed reading Uri grants", e); 6535 } catch (XmlPullParserException e) { 6536 Log.wtf(TAG, "Failed reading Uri grants", e); 6537 } finally { 6538 IoUtils.closeQuietly(fis); 6539 } 6540 } 6541 6542 @Override 6543 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6544 enforceNotIsolatedCaller("takePersistableUriPermission"); 6545 6546 Preconditions.checkFlagsArgument(modeFlags, 6547 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6548 6549 synchronized (this) { 6550 final int callingUid = Binder.getCallingUid(); 6551 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6552 if (perm == null) { 6553 throw new SecurityException("No permission grant found for UID " + callingUid 6554 + " and Uri " + uri.toSafeString()); 6555 } 6556 6557 boolean persistChanged = perm.takePersistableModes(modeFlags); 6558 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6559 6560 if (persistChanged) { 6561 schedulePersistUriGrants(); 6562 } 6563 } 6564 } 6565 6566 @Override 6567 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6568 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6569 6570 Preconditions.checkFlagsArgument(modeFlags, 6571 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6572 6573 synchronized (this) { 6574 final int callingUid = Binder.getCallingUid(); 6575 6576 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6577 if (perm == null) { 6578 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6579 + uri.toSafeString()); 6580 return; 6581 } 6582 6583 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6584 removeUriPermissionIfNeededLocked(perm); 6585 if (persistChanged) { 6586 schedulePersistUriGrants(); 6587 } 6588 } 6589 } 6590 6591 /** 6592 * Prune any older {@link UriPermission} for the given UID until outstanding 6593 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6594 * 6595 * @return if any mutations occured that require persisting. 6596 */ 6597 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6598 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6599 if (perms == null) return false; 6600 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6601 6602 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6603 for (UriPermission perm : perms.values()) { 6604 if (perm.persistedModeFlags != 0) { 6605 persisted.add(perm); 6606 } 6607 } 6608 6609 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6610 if (trimCount <= 0) return false; 6611 6612 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6613 for (int i = 0; i < trimCount; i++) { 6614 final UriPermission perm = persisted.get(i); 6615 6616 if (DEBUG_URI_PERMISSION) { 6617 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6618 } 6619 6620 perm.releasePersistableModes(~0); 6621 removeUriPermissionIfNeededLocked(perm); 6622 } 6623 6624 return true; 6625 } 6626 6627 @Override 6628 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6629 String packageName, boolean incoming) { 6630 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6631 Preconditions.checkNotNull(packageName, "packageName"); 6632 6633 final int callingUid = Binder.getCallingUid(); 6634 final IPackageManager pm = AppGlobals.getPackageManager(); 6635 try { 6636 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6637 if (packageUid != callingUid) { 6638 throw new SecurityException( 6639 "Package " + packageName + " does not belong to calling UID " + callingUid); 6640 } 6641 } catch (RemoteException e) { 6642 throw new SecurityException("Failed to verify package name ownership"); 6643 } 6644 6645 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6646 synchronized (this) { 6647 if (incoming) { 6648 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6649 if (perms == null) { 6650 Slog.w(TAG, "No permission grants found for " + packageName); 6651 } else { 6652 final int size = perms.size(); 6653 for (int i = 0; i < size; i++) { 6654 final UriPermission perm = perms.valueAt(i); 6655 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6656 result.add(perm.buildPersistedPublicApiObject()); 6657 } 6658 } 6659 } 6660 } else { 6661 final int size = mGrantedUriPermissions.size(); 6662 for (int i = 0; i < size; i++) { 6663 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6664 final int permsSize = perms.size(); 6665 for (int j = 0; j < permsSize; j++) { 6666 final UriPermission perm = perms.valueAt(j); 6667 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6668 result.add(perm.buildPersistedPublicApiObject()); 6669 } 6670 } 6671 } 6672 } 6673 } 6674 return new ParceledListSlice<android.content.UriPermission>(result); 6675 } 6676 6677 @Override 6678 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6679 synchronized (this) { 6680 ProcessRecord app = 6681 who != null ? getRecordForAppLocked(who) : null; 6682 if (app == null) return; 6683 6684 Message msg = Message.obtain(); 6685 msg.what = WAIT_FOR_DEBUGGER_MSG; 6686 msg.obj = app; 6687 msg.arg1 = waiting ? 1 : 0; 6688 mHandler.sendMessage(msg); 6689 } 6690 } 6691 6692 @Override 6693 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6694 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6695 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6696 outInfo.availMem = Process.getFreeMemory(); 6697 outInfo.totalMem = Process.getTotalMemory(); 6698 outInfo.threshold = homeAppMem; 6699 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6700 outInfo.hiddenAppThreshold = cachedAppMem; 6701 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6702 ProcessList.SERVICE_ADJ); 6703 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6704 ProcessList.VISIBLE_APP_ADJ); 6705 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6706 ProcessList.FOREGROUND_APP_ADJ); 6707 } 6708 6709 // ========================================================= 6710 // TASK MANAGEMENT 6711 // ========================================================= 6712 6713 @Override 6714 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6715 IThumbnailReceiver receiver) { 6716 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6717 6718 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6719 ActivityRecord topRecord = null; 6720 6721 synchronized(this) { 6722 if (localLOGV) Slog.v( 6723 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6724 + ", receiver=" + receiver); 6725 6726 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6727 != PackageManager.PERMISSION_GRANTED) { 6728 if (receiver != null) { 6729 // If the caller wants to wait for pending thumbnails, 6730 // it ain't gonna get them. 6731 try { 6732 receiver.finished(); 6733 } catch (RemoteException ex) { 6734 } 6735 } 6736 String msg = "Permission Denial: getTasks() from pid=" 6737 + Binder.getCallingPid() 6738 + ", uid=" + Binder.getCallingUid() 6739 + " requires " + android.Manifest.permission.GET_TASKS; 6740 Slog.w(TAG, msg); 6741 throw new SecurityException(msg); 6742 } 6743 6744 // TODO: Improve with MRU list from all ActivityStacks. 6745 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6746 6747 if (!pending.pendingRecords.isEmpty()) { 6748 mPendingThumbnails.add(pending); 6749 } 6750 } 6751 6752 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6753 6754 if (topRecord != null) { 6755 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6756 try { 6757 IApplicationThread topThumbnail = topRecord.app.thread; 6758 topThumbnail.requestThumbnail(topRecord.appToken); 6759 } catch (Exception e) { 6760 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6761 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6762 } 6763 } 6764 6765 if (pending == null && receiver != null) { 6766 // In this case all thumbnails were available and the client 6767 // is being asked to be told when the remaining ones come in... 6768 // which is unusually, since the top-most currently running 6769 // activity should never have a canned thumbnail! Oh well. 6770 try { 6771 receiver.finished(); 6772 } catch (RemoteException ex) { 6773 } 6774 } 6775 6776 return list; 6777 } 6778 6779 TaskRecord getMostRecentTask() { 6780 return mRecentTasks.get(0); 6781 } 6782 6783 @Override 6784 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6785 int flags, int userId) { 6786 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6787 false, true, "getRecentTasks", null); 6788 6789 synchronized (this) { 6790 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6791 "getRecentTasks()"); 6792 final boolean detailed = checkCallingPermission( 6793 android.Manifest.permission.GET_DETAILED_TASKS) 6794 == PackageManager.PERMISSION_GRANTED; 6795 6796 IPackageManager pm = AppGlobals.getPackageManager(); 6797 6798 final int N = mRecentTasks.size(); 6799 ArrayList<ActivityManager.RecentTaskInfo> res 6800 = new ArrayList<ActivityManager.RecentTaskInfo>( 6801 maxNum < N ? maxNum : N); 6802 for (int i=0; i<N && maxNum > 0; i++) { 6803 TaskRecord tr = mRecentTasks.get(i); 6804 // Only add calling user's recent tasks 6805 if (tr.userId != userId) continue; 6806 // Return the entry if desired by the caller. We always return 6807 // the first entry, because callers always expect this to be the 6808 // foreground app. We may filter others if the caller has 6809 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6810 // we should exclude the entry. 6811 6812 if (i == 0 6813 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6814 || (tr.intent == null) 6815 || ((tr.intent.getFlags() 6816 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6817 ActivityManager.RecentTaskInfo rti 6818 = new ActivityManager.RecentTaskInfo(); 6819 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6820 rti.persistentId = tr.taskId; 6821 rti.baseIntent = new Intent( 6822 tr.intent != null ? tr.intent : tr.affinityIntent); 6823 if (!detailed) { 6824 rti.baseIntent.replaceExtras((Bundle)null); 6825 } 6826 rti.origActivity = tr.origActivity; 6827 rti.description = tr.lastDescription; 6828 rti.stackId = tr.stack.mStackId; 6829 6830 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6831 // Check whether this activity is currently available. 6832 try { 6833 if (rti.origActivity != null) { 6834 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6835 == null) { 6836 continue; 6837 } 6838 } else if (rti.baseIntent != null) { 6839 if (pm.queryIntentActivities(rti.baseIntent, 6840 null, 0, userId) == null) { 6841 continue; 6842 } 6843 } 6844 } catch (RemoteException e) { 6845 // Will never happen. 6846 } 6847 } 6848 6849 res.add(rti); 6850 maxNum--; 6851 } 6852 } 6853 return res; 6854 } 6855 } 6856 6857 private TaskRecord recentTaskForIdLocked(int id) { 6858 final int N = mRecentTasks.size(); 6859 for (int i=0; i<N; i++) { 6860 TaskRecord tr = mRecentTasks.get(i); 6861 if (tr.taskId == id) { 6862 return tr; 6863 } 6864 } 6865 return null; 6866 } 6867 6868 @Override 6869 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6870 synchronized (this) { 6871 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6872 "getTaskThumbnails()"); 6873 TaskRecord tr = recentTaskForIdLocked(id); 6874 if (tr != null) { 6875 return tr.getTaskThumbnailsLocked(); 6876 } 6877 } 6878 return null; 6879 } 6880 6881 @Override 6882 public Bitmap getTaskTopThumbnail(int id) { 6883 synchronized (this) { 6884 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6885 "getTaskTopThumbnail()"); 6886 TaskRecord tr = recentTaskForIdLocked(id); 6887 if (tr != null) { 6888 return tr.getTaskTopThumbnailLocked(); 6889 } 6890 } 6891 return null; 6892 } 6893 6894 @Override 6895 public boolean removeSubTask(int taskId, int subTaskIndex) { 6896 synchronized (this) { 6897 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6898 "removeSubTask()"); 6899 long ident = Binder.clearCallingIdentity(); 6900 try { 6901 TaskRecord tr = recentTaskForIdLocked(taskId); 6902 if (tr != null) { 6903 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6904 } 6905 return false; 6906 } finally { 6907 Binder.restoreCallingIdentity(ident); 6908 } 6909 } 6910 } 6911 6912 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6913 if (!pr.killedByAm) { 6914 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6915 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6916 pr.processName, pr.setAdj, reason); 6917 pr.killedByAm = true; 6918 Process.killProcessQuiet(pr.pid); 6919 } 6920 } 6921 6922 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6923 tr.disposeThumbnail(); 6924 mRecentTasks.remove(tr); 6925 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6926 Intent baseIntent = new Intent( 6927 tr.intent != null ? tr.intent : tr.affinityIntent); 6928 ComponentName component = baseIntent.getComponent(); 6929 if (component == null) { 6930 Slog.w(TAG, "Now component for base intent of task: " + tr); 6931 return; 6932 } 6933 6934 // Find any running services associated with this app. 6935 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6936 6937 if (killProcesses) { 6938 // Find any running processes associated with this app. 6939 final String pkg = component.getPackageName(); 6940 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6941 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 6942 for (int i=0; i<pmap.size(); i++) { 6943 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 6944 for (int j=0; j<uids.size(); j++) { 6945 ProcessRecord proc = uids.valueAt(j); 6946 if (proc.userId != tr.userId) { 6947 continue; 6948 } 6949 if (!proc.pkgList.containsKey(pkg)) { 6950 continue; 6951 } 6952 procs.add(proc); 6953 } 6954 } 6955 6956 // Kill the running processes. 6957 for (int i=0; i<procs.size(); i++) { 6958 ProcessRecord pr = procs.get(i); 6959 if (pr == mHomeProcess) { 6960 // Don't kill the home process along with tasks from the same package. 6961 continue; 6962 } 6963 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 6964 killUnneededProcessLocked(pr, "remove task"); 6965 } else { 6966 pr.waitingToKill = "remove task"; 6967 } 6968 } 6969 } 6970 } 6971 6972 @Override 6973 public boolean removeTask(int taskId, int flags) { 6974 synchronized (this) { 6975 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6976 "removeTask()"); 6977 long ident = Binder.clearCallingIdentity(); 6978 try { 6979 TaskRecord tr = recentTaskForIdLocked(taskId); 6980 if (tr != null) { 6981 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 6982 if (r != null) { 6983 cleanUpRemovedTaskLocked(tr, flags); 6984 return true; 6985 } 6986 if (tr.mActivities.size() == 0) { 6987 // Caller is just removing a recent task that is 6988 // not actively running. That is easy! 6989 cleanUpRemovedTaskLocked(tr, flags); 6990 return true; 6991 } 6992 Slog.w(TAG, "removeTask: task " + taskId 6993 + " does not have activities to remove, " 6994 + " but numActivities=" + tr.numActivities 6995 + ": " + tr); 6996 } 6997 } finally { 6998 Binder.restoreCallingIdentity(ident); 6999 } 7000 } 7001 return false; 7002 } 7003 7004 /** 7005 * TODO: Add mController hook 7006 */ 7007 @Override 7008 public void moveTaskToFront(int task, int flags, Bundle options) { 7009 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7010 "moveTaskToFront()"); 7011 7012 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task); 7013 synchronized(this) { 7014 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7015 Binder.getCallingUid(), "Task to front")) { 7016 ActivityOptions.abort(options); 7017 return; 7018 } 7019 final long origId = Binder.clearCallingIdentity(); 7020 try { 7021 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7022 } finally { 7023 Binder.restoreCallingIdentity(origId); 7024 } 7025 ActivityOptions.abort(options); 7026 } 7027 } 7028 7029 @Override 7030 public void moveTaskToBack(int taskId) { 7031 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7032 "moveTaskToBack()"); 7033 7034 synchronized(this) { 7035 TaskRecord tr = recentTaskForIdLocked(taskId); 7036 if (tr != null) { 7037 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7038 ActivityStack stack = tr.stack; 7039 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7040 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7041 Binder.getCallingUid(), "Task to back")) { 7042 return; 7043 } 7044 } 7045 final long origId = Binder.clearCallingIdentity(); 7046 try { 7047 stack.moveTaskToBackLocked(taskId, null); 7048 } finally { 7049 Binder.restoreCallingIdentity(origId); 7050 } 7051 } 7052 } 7053 } 7054 7055 /** 7056 * Moves an activity, and all of the other activities within the same task, to the bottom 7057 * of the history stack. The activity's order within the task is unchanged. 7058 * 7059 * @param token A reference to the activity we wish to move 7060 * @param nonRoot If false then this only works if the activity is the root 7061 * of a task; if true it will work for any activity in a task. 7062 * @return Returns true if the move completed, false if not. 7063 */ 7064 @Override 7065 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7066 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7067 synchronized(this) { 7068 final long origId = Binder.clearCallingIdentity(); 7069 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7070 if (taskId >= 0) { 7071 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7072 } 7073 Binder.restoreCallingIdentity(origId); 7074 } 7075 return false; 7076 } 7077 7078 @Override 7079 public void moveTaskBackwards(int task) { 7080 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7081 "moveTaskBackwards()"); 7082 7083 synchronized(this) { 7084 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7085 Binder.getCallingUid(), "Task backwards")) { 7086 return; 7087 } 7088 final long origId = Binder.clearCallingIdentity(); 7089 moveTaskBackwardsLocked(task); 7090 Binder.restoreCallingIdentity(origId); 7091 } 7092 } 7093 7094 private final void moveTaskBackwardsLocked(int task) { 7095 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7096 } 7097 7098 @Override 7099 public IBinder getHomeActivityToken() throws RemoteException { 7100 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7101 "getHomeActivityToken()"); 7102 synchronized (this) { 7103 return mStackSupervisor.getHomeActivityToken(); 7104 } 7105 } 7106 7107 @Override 7108 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7109 IActivityContainerCallback callback) throws RemoteException { 7110 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7111 "createActivityContainer()"); 7112 synchronized (this) { 7113 if (parentActivityToken == null) { 7114 throw new IllegalArgumentException("parent token must not be null"); 7115 } 7116 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7117 if (r == null) { 7118 return null; 7119 } 7120 return mStackSupervisor.createActivityContainer(r, callback); 7121 } 7122 } 7123 7124 @Override 7125 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7126 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7127 "moveTaskToStack()"); 7128 if (stackId == HOME_STACK_ID) { 7129 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7130 new RuntimeException("here").fillInStackTrace()); 7131 } 7132 synchronized (this) { 7133 long ident = Binder.clearCallingIdentity(); 7134 try { 7135 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7136 + stackId + " toTop=" + toTop); 7137 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7138 } finally { 7139 Binder.restoreCallingIdentity(ident); 7140 } 7141 } 7142 } 7143 7144 @Override 7145 public void resizeStack(int stackBoxId, Rect bounds) { 7146 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7147 "resizeStackBox()"); 7148 long ident = Binder.clearCallingIdentity(); 7149 try { 7150 mWindowManager.resizeStack(stackBoxId, bounds); 7151 } finally { 7152 Binder.restoreCallingIdentity(ident); 7153 } 7154 } 7155 7156 @Override 7157 public List<StackInfo> getAllStackInfos() { 7158 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7159 "getAllStackInfos()"); 7160 long ident = Binder.clearCallingIdentity(); 7161 try { 7162 synchronized (this) { 7163 return mStackSupervisor.getAllStackInfosLocked(); 7164 } 7165 } finally { 7166 Binder.restoreCallingIdentity(ident); 7167 } 7168 } 7169 7170 @Override 7171 public StackInfo getStackInfo(int stackId) { 7172 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7173 "getStackInfo()"); 7174 long ident = Binder.clearCallingIdentity(); 7175 try { 7176 synchronized (this) { 7177 return mStackSupervisor.getStackInfoLocked(stackId); 7178 } 7179 } finally { 7180 Binder.restoreCallingIdentity(ident); 7181 } 7182 } 7183 7184 @Override 7185 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7186 synchronized(this) { 7187 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7188 } 7189 } 7190 7191 // ========================================================= 7192 // THUMBNAILS 7193 // ========================================================= 7194 7195 public void reportThumbnail(IBinder token, 7196 Bitmap thumbnail, CharSequence description) { 7197 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7198 final long origId = Binder.clearCallingIdentity(); 7199 sendPendingThumbnail(null, token, thumbnail, description, true); 7200 Binder.restoreCallingIdentity(origId); 7201 } 7202 7203 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7204 Bitmap thumbnail, CharSequence description, boolean always) { 7205 TaskRecord task; 7206 ArrayList<PendingThumbnailsRecord> receivers = null; 7207 7208 //System.out.println("Send pending thumbnail: " + r); 7209 7210 synchronized(this) { 7211 if (r == null) { 7212 r = ActivityRecord.isInStackLocked(token); 7213 if (r == null) { 7214 return; 7215 } 7216 } 7217 if (thumbnail == null && r.thumbHolder != null) { 7218 thumbnail = r.thumbHolder.lastThumbnail; 7219 description = r.thumbHolder.lastDescription; 7220 } 7221 if (thumbnail == null && !always) { 7222 // If there is no thumbnail, and this entry is not actually 7223 // going away, then abort for now and pick up the next 7224 // thumbnail we get. 7225 return; 7226 } 7227 task = r.task; 7228 7229 int N = mPendingThumbnails.size(); 7230 int i=0; 7231 while (i<N) { 7232 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7233 //System.out.println("Looking in " + pr.pendingRecords); 7234 if (pr.pendingRecords.remove(r)) { 7235 if (receivers == null) { 7236 receivers = new ArrayList<PendingThumbnailsRecord>(); 7237 } 7238 receivers.add(pr); 7239 if (pr.pendingRecords.size() == 0) { 7240 pr.finished = true; 7241 mPendingThumbnails.remove(i); 7242 N--; 7243 continue; 7244 } 7245 } 7246 i++; 7247 } 7248 } 7249 7250 if (receivers != null) { 7251 final int N = receivers.size(); 7252 for (int i=0; i<N; i++) { 7253 try { 7254 PendingThumbnailsRecord pr = receivers.get(i); 7255 pr.receiver.newThumbnail( 7256 task != null ? task.taskId : -1, thumbnail, description); 7257 if (pr.finished) { 7258 pr.receiver.finished(); 7259 } 7260 } catch (Exception e) { 7261 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7262 } 7263 } 7264 } 7265 } 7266 7267 // ========================================================= 7268 // CONTENT PROVIDERS 7269 // ========================================================= 7270 7271 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7272 List<ProviderInfo> providers = null; 7273 try { 7274 providers = AppGlobals.getPackageManager(). 7275 queryContentProviders(app.processName, app.uid, 7276 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7277 } catch (RemoteException ex) { 7278 } 7279 if (DEBUG_MU) 7280 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7281 int userId = app.userId; 7282 if (providers != null) { 7283 int N = providers.size(); 7284 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7285 for (int i=0; i<N; i++) { 7286 ProviderInfo cpi = 7287 (ProviderInfo)providers.get(i); 7288 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7289 cpi.name, cpi.flags); 7290 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7291 // This is a singleton provider, but a user besides the 7292 // default user is asking to initialize a process it runs 7293 // in... well, no, it doesn't actually run in this process, 7294 // it runs in the process of the default user. Get rid of it. 7295 providers.remove(i); 7296 N--; 7297 i--; 7298 continue; 7299 } 7300 7301 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7302 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7303 if (cpr == null) { 7304 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7305 mProviderMap.putProviderByClass(comp, cpr); 7306 } 7307 if (DEBUG_MU) 7308 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7309 app.pubProviders.put(cpi.name, cpr); 7310 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7311 // Don't add this if it is a platform component that is marked 7312 // to run in multiple processes, because this is actually 7313 // part of the framework so doesn't make sense to track as a 7314 // separate apk in the process. 7315 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7316 } 7317 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7318 } 7319 } 7320 return providers; 7321 } 7322 7323 /** 7324 * Check if {@link ProcessRecord} has a possible chance at accessing the 7325 * given {@link ProviderInfo}. Final permission checking is always done 7326 * in {@link ContentProvider}. 7327 */ 7328 private final String checkContentProviderPermissionLocked( 7329 ProviderInfo cpi, ProcessRecord r) { 7330 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7331 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7332 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7333 cpi.applicationInfo.uid, cpi.exported) 7334 == PackageManager.PERMISSION_GRANTED) { 7335 return null; 7336 } 7337 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7338 cpi.applicationInfo.uid, cpi.exported) 7339 == PackageManager.PERMISSION_GRANTED) { 7340 return null; 7341 } 7342 7343 PathPermission[] pps = cpi.pathPermissions; 7344 if (pps != null) { 7345 int i = pps.length; 7346 while (i > 0) { 7347 i--; 7348 PathPermission pp = pps[i]; 7349 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7350 cpi.applicationInfo.uid, cpi.exported) 7351 == PackageManager.PERMISSION_GRANTED) { 7352 return null; 7353 } 7354 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7355 cpi.applicationInfo.uid, cpi.exported) 7356 == PackageManager.PERMISSION_GRANTED) { 7357 return null; 7358 } 7359 } 7360 } 7361 7362 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7363 if (perms != null) { 7364 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7365 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7366 return null; 7367 } 7368 } 7369 } 7370 7371 String msg; 7372 if (!cpi.exported) { 7373 msg = "Permission Denial: opening provider " + cpi.name 7374 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7375 + ", uid=" + callingUid + ") that is not exported from uid " 7376 + cpi.applicationInfo.uid; 7377 } else { 7378 msg = "Permission Denial: opening provider " + cpi.name 7379 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7380 + ", uid=" + callingUid + ") requires " 7381 + cpi.readPermission + " or " + cpi.writePermission; 7382 } 7383 Slog.w(TAG, msg); 7384 return msg; 7385 } 7386 7387 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7388 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7389 if (r != null) { 7390 for (int i=0; i<r.conProviders.size(); i++) { 7391 ContentProviderConnection conn = r.conProviders.get(i); 7392 if (conn.provider == cpr) { 7393 if (DEBUG_PROVIDER) Slog.v(TAG, 7394 "Adding provider requested by " 7395 + r.processName + " from process " 7396 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7397 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7398 if (stable) { 7399 conn.stableCount++; 7400 conn.numStableIncs++; 7401 } else { 7402 conn.unstableCount++; 7403 conn.numUnstableIncs++; 7404 } 7405 return conn; 7406 } 7407 } 7408 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7409 if (stable) { 7410 conn.stableCount = 1; 7411 conn.numStableIncs = 1; 7412 } else { 7413 conn.unstableCount = 1; 7414 conn.numUnstableIncs = 1; 7415 } 7416 cpr.connections.add(conn); 7417 r.conProviders.add(conn); 7418 return conn; 7419 } 7420 cpr.addExternalProcessHandleLocked(externalProcessToken); 7421 return null; 7422 } 7423 7424 boolean decProviderCountLocked(ContentProviderConnection conn, 7425 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7426 if (conn != null) { 7427 cpr = conn.provider; 7428 if (DEBUG_PROVIDER) Slog.v(TAG, 7429 "Removing provider requested by " 7430 + conn.client.processName + " from process " 7431 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7432 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7433 if (stable) { 7434 conn.stableCount--; 7435 } else { 7436 conn.unstableCount--; 7437 } 7438 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7439 cpr.connections.remove(conn); 7440 conn.client.conProviders.remove(conn); 7441 return true; 7442 } 7443 return false; 7444 } 7445 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7446 return false; 7447 } 7448 7449 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7450 String name, IBinder token, boolean stable, int userId) { 7451 ContentProviderRecord cpr; 7452 ContentProviderConnection conn = null; 7453 ProviderInfo cpi = null; 7454 7455 synchronized(this) { 7456 ProcessRecord r = null; 7457 if (caller != null) { 7458 r = getRecordForAppLocked(caller); 7459 if (r == null) { 7460 throw new SecurityException( 7461 "Unable to find app for caller " + caller 7462 + " (pid=" + Binder.getCallingPid() 7463 + ") when getting content provider " + name); 7464 } 7465 } 7466 7467 // First check if this content provider has been published... 7468 cpr = mProviderMap.getProviderByName(name, userId); 7469 boolean providerRunning = cpr != null; 7470 if (providerRunning) { 7471 cpi = cpr.info; 7472 String msg; 7473 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7474 throw new SecurityException(msg); 7475 } 7476 7477 if (r != null && cpr.canRunHere(r)) { 7478 // This provider has been published or is in the process 7479 // of being published... but it is also allowed to run 7480 // in the caller's process, so don't make a connection 7481 // and just let the caller instantiate its own instance. 7482 ContentProviderHolder holder = cpr.newHolder(null); 7483 // don't give caller the provider object, it needs 7484 // to make its own. 7485 holder.provider = null; 7486 return holder; 7487 } 7488 7489 final long origId = Binder.clearCallingIdentity(); 7490 7491 // In this case the provider instance already exists, so we can 7492 // return it right away. 7493 conn = incProviderCountLocked(r, cpr, token, stable); 7494 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7495 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7496 // If this is a perceptible app accessing the provider, 7497 // make sure to count it as being accessed and thus 7498 // back up on the LRU list. This is good because 7499 // content providers are often expensive to start. 7500 updateLruProcessLocked(cpr.proc, false, null); 7501 } 7502 } 7503 7504 if (cpr.proc != null) { 7505 if (false) { 7506 if (cpr.name.flattenToShortString().equals( 7507 "com.android.providers.calendar/.CalendarProvider2")) { 7508 Slog.v(TAG, "****************** KILLING " 7509 + cpr.name.flattenToShortString()); 7510 Process.killProcess(cpr.proc.pid); 7511 } 7512 } 7513 boolean success = updateOomAdjLocked(cpr.proc); 7514 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7515 // NOTE: there is still a race here where a signal could be 7516 // pending on the process even though we managed to update its 7517 // adj level. Not sure what to do about this, but at least 7518 // the race is now smaller. 7519 if (!success) { 7520 // Uh oh... it looks like the provider's process 7521 // has been killed on us. We need to wait for a new 7522 // process to be started, and make sure its death 7523 // doesn't kill our process. 7524 Slog.i(TAG, 7525 "Existing provider " + cpr.name.flattenToShortString() 7526 + " is crashing; detaching " + r); 7527 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7528 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7529 if (!lastRef) { 7530 // This wasn't the last ref our process had on 7531 // the provider... we have now been killed, bail. 7532 return null; 7533 } 7534 providerRunning = false; 7535 conn = null; 7536 } 7537 } 7538 7539 Binder.restoreCallingIdentity(origId); 7540 } 7541 7542 boolean singleton; 7543 if (!providerRunning) { 7544 try { 7545 cpi = AppGlobals.getPackageManager(). 7546 resolveContentProvider(name, 7547 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7548 } catch (RemoteException ex) { 7549 } 7550 if (cpi == null) { 7551 return null; 7552 } 7553 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7554 cpi.name, cpi.flags); 7555 if (singleton) { 7556 userId = 0; 7557 } 7558 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7559 7560 String msg; 7561 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7562 throw new SecurityException(msg); 7563 } 7564 7565 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7566 && !cpi.processName.equals("system")) { 7567 // If this content provider does not run in the system 7568 // process, and the system is not yet ready to run other 7569 // processes, then fail fast instead of hanging. 7570 throw new IllegalArgumentException( 7571 "Attempt to launch content provider before system ready"); 7572 } 7573 7574 // Make sure that the user who owns this provider is started. If not, 7575 // we don't want to allow it to run. 7576 if (mStartedUsers.get(userId) == null) { 7577 Slog.w(TAG, "Unable to launch app " 7578 + cpi.applicationInfo.packageName + "/" 7579 + cpi.applicationInfo.uid + " for provider " 7580 + name + ": user " + userId + " is stopped"); 7581 return null; 7582 } 7583 7584 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7585 cpr = mProviderMap.getProviderByClass(comp, userId); 7586 final boolean firstClass = cpr == null; 7587 if (firstClass) { 7588 try { 7589 ApplicationInfo ai = 7590 AppGlobals.getPackageManager(). 7591 getApplicationInfo( 7592 cpi.applicationInfo.packageName, 7593 STOCK_PM_FLAGS, userId); 7594 if (ai == null) { 7595 Slog.w(TAG, "No package info for content provider " 7596 + cpi.name); 7597 return null; 7598 } 7599 ai = getAppInfoForUser(ai, userId); 7600 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7601 } catch (RemoteException ex) { 7602 // pm is in same process, this will never happen. 7603 } 7604 } 7605 7606 if (r != null && cpr.canRunHere(r)) { 7607 // If this is a multiprocess provider, then just return its 7608 // info and allow the caller to instantiate it. Only do 7609 // this if the provider is the same user as the caller's 7610 // process, or can run as root (so can be in any process). 7611 return cpr.newHolder(null); 7612 } 7613 7614 if (DEBUG_PROVIDER) { 7615 RuntimeException e = new RuntimeException("here"); 7616 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7617 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7618 } 7619 7620 // This is single process, and our app is now connecting to it. 7621 // See if we are already in the process of launching this 7622 // provider. 7623 final int N = mLaunchingProviders.size(); 7624 int i; 7625 for (i=0; i<N; i++) { 7626 if (mLaunchingProviders.get(i) == cpr) { 7627 break; 7628 } 7629 } 7630 7631 // If the provider is not already being launched, then get it 7632 // started. 7633 if (i >= N) { 7634 final long origId = Binder.clearCallingIdentity(); 7635 7636 try { 7637 // Content provider is now in use, its package can't be stopped. 7638 try { 7639 AppGlobals.getPackageManager().setPackageStoppedState( 7640 cpr.appInfo.packageName, false, userId); 7641 } catch (RemoteException e) { 7642 } catch (IllegalArgumentException e) { 7643 Slog.w(TAG, "Failed trying to unstop package " 7644 + cpr.appInfo.packageName + ": " + e); 7645 } 7646 7647 // Use existing process if already started 7648 ProcessRecord proc = getProcessRecordLocked( 7649 cpi.processName, cpr.appInfo.uid, false); 7650 if (proc != null && proc.thread != null) { 7651 if (DEBUG_PROVIDER) { 7652 Slog.d(TAG, "Installing in existing process " + proc); 7653 } 7654 proc.pubProviders.put(cpi.name, cpr); 7655 try { 7656 proc.thread.scheduleInstallProvider(cpi); 7657 } catch (RemoteException e) { 7658 } 7659 } else { 7660 proc = startProcessLocked(cpi.processName, 7661 cpr.appInfo, false, 0, "content provider", 7662 new ComponentName(cpi.applicationInfo.packageName, 7663 cpi.name), false, false, false); 7664 if (proc == null) { 7665 Slog.w(TAG, "Unable to launch app " 7666 + cpi.applicationInfo.packageName + "/" 7667 + cpi.applicationInfo.uid + " for provider " 7668 + name + ": process is bad"); 7669 return null; 7670 } 7671 } 7672 cpr.launchingApp = proc; 7673 mLaunchingProviders.add(cpr); 7674 } finally { 7675 Binder.restoreCallingIdentity(origId); 7676 } 7677 } 7678 7679 // Make sure the provider is published (the same provider class 7680 // may be published under multiple names). 7681 if (firstClass) { 7682 mProviderMap.putProviderByClass(comp, cpr); 7683 } 7684 7685 mProviderMap.putProviderByName(name, cpr); 7686 conn = incProviderCountLocked(r, cpr, token, stable); 7687 if (conn != null) { 7688 conn.waiting = true; 7689 } 7690 } 7691 } 7692 7693 // Wait for the provider to be published... 7694 synchronized (cpr) { 7695 while (cpr.provider == null) { 7696 if (cpr.launchingApp == null) { 7697 Slog.w(TAG, "Unable to launch app " 7698 + cpi.applicationInfo.packageName + "/" 7699 + cpi.applicationInfo.uid + " for provider " 7700 + name + ": launching app became null"); 7701 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7702 UserHandle.getUserId(cpi.applicationInfo.uid), 7703 cpi.applicationInfo.packageName, 7704 cpi.applicationInfo.uid, name); 7705 return null; 7706 } 7707 try { 7708 if (DEBUG_MU) { 7709 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7710 + cpr.launchingApp); 7711 } 7712 if (conn != null) { 7713 conn.waiting = true; 7714 } 7715 cpr.wait(); 7716 } catch (InterruptedException ex) { 7717 } finally { 7718 if (conn != null) { 7719 conn.waiting = false; 7720 } 7721 } 7722 } 7723 } 7724 return cpr != null ? cpr.newHolder(conn) : null; 7725 } 7726 7727 public final ContentProviderHolder getContentProvider( 7728 IApplicationThread caller, String name, int userId, boolean stable) { 7729 enforceNotIsolatedCaller("getContentProvider"); 7730 if (caller == null) { 7731 String msg = "null IApplicationThread when getting content provider " 7732 + name; 7733 Slog.w(TAG, msg); 7734 throw new SecurityException(msg); 7735 } 7736 7737 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7738 false, true, "getContentProvider", null); 7739 return getContentProviderImpl(caller, name, null, stable, userId); 7740 } 7741 7742 public ContentProviderHolder getContentProviderExternal( 7743 String name, int userId, IBinder token) { 7744 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7745 "Do not have permission in call getContentProviderExternal()"); 7746 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7747 false, true, "getContentProvider", null); 7748 return getContentProviderExternalUnchecked(name, token, userId); 7749 } 7750 7751 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7752 IBinder token, int userId) { 7753 return getContentProviderImpl(null, name, token, true, userId); 7754 } 7755 7756 /** 7757 * Drop a content provider from a ProcessRecord's bookkeeping 7758 */ 7759 public void removeContentProvider(IBinder connection, boolean stable) { 7760 enforceNotIsolatedCaller("removeContentProvider"); 7761 synchronized (this) { 7762 ContentProviderConnection conn; 7763 try { 7764 conn = (ContentProviderConnection)connection; 7765 } catch (ClassCastException e) { 7766 String msg ="removeContentProvider: " + connection 7767 + " not a ContentProviderConnection"; 7768 Slog.w(TAG, msg); 7769 throw new IllegalArgumentException(msg); 7770 } 7771 if (conn == null) { 7772 throw new NullPointerException("connection is null"); 7773 } 7774 if (decProviderCountLocked(conn, null, null, stable)) { 7775 updateOomAdjLocked(); 7776 } 7777 } 7778 } 7779 7780 public void removeContentProviderExternal(String name, IBinder token) { 7781 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7782 "Do not have permission in call removeContentProviderExternal()"); 7783 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7784 } 7785 7786 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7787 synchronized (this) { 7788 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7789 if(cpr == null) { 7790 //remove from mProvidersByClass 7791 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7792 return; 7793 } 7794 7795 //update content provider record entry info 7796 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7797 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7798 if (localCpr.hasExternalProcessHandles()) { 7799 if (localCpr.removeExternalProcessHandleLocked(token)) { 7800 updateOomAdjLocked(); 7801 } else { 7802 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7803 + " with no external reference for token: " 7804 + token + "."); 7805 } 7806 } else { 7807 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7808 + " with no external references."); 7809 } 7810 } 7811 } 7812 7813 public final void publishContentProviders(IApplicationThread caller, 7814 List<ContentProviderHolder> providers) { 7815 if (providers == null) { 7816 return; 7817 } 7818 7819 enforceNotIsolatedCaller("publishContentProviders"); 7820 synchronized (this) { 7821 final ProcessRecord r = getRecordForAppLocked(caller); 7822 if (DEBUG_MU) 7823 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 7824 if (r == null) { 7825 throw new SecurityException( 7826 "Unable to find app for caller " + caller 7827 + " (pid=" + Binder.getCallingPid() 7828 + ") when publishing content providers"); 7829 } 7830 7831 final long origId = Binder.clearCallingIdentity(); 7832 7833 final int N = providers.size(); 7834 for (int i=0; i<N; i++) { 7835 ContentProviderHolder src = providers.get(i); 7836 if (src == null || src.info == null || src.provider == null) { 7837 continue; 7838 } 7839 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 7840 if (DEBUG_MU) 7841 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 7842 if (dst != null) { 7843 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 7844 mProviderMap.putProviderByClass(comp, dst); 7845 String names[] = dst.info.authority.split(";"); 7846 for (int j = 0; j < names.length; j++) { 7847 mProviderMap.putProviderByName(names[j], dst); 7848 } 7849 7850 int NL = mLaunchingProviders.size(); 7851 int j; 7852 for (j=0; j<NL; j++) { 7853 if (mLaunchingProviders.get(j) == dst) { 7854 mLaunchingProviders.remove(j); 7855 j--; 7856 NL--; 7857 } 7858 } 7859 synchronized (dst) { 7860 dst.provider = src.provider; 7861 dst.proc = r; 7862 dst.notifyAll(); 7863 } 7864 updateOomAdjLocked(r); 7865 } 7866 } 7867 7868 Binder.restoreCallingIdentity(origId); 7869 } 7870 } 7871 7872 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 7873 ContentProviderConnection conn; 7874 try { 7875 conn = (ContentProviderConnection)connection; 7876 } catch (ClassCastException e) { 7877 String msg ="refContentProvider: " + connection 7878 + " not a ContentProviderConnection"; 7879 Slog.w(TAG, msg); 7880 throw new IllegalArgumentException(msg); 7881 } 7882 if (conn == null) { 7883 throw new NullPointerException("connection is null"); 7884 } 7885 7886 synchronized (this) { 7887 if (stable > 0) { 7888 conn.numStableIncs += stable; 7889 } 7890 stable = conn.stableCount + stable; 7891 if (stable < 0) { 7892 throw new IllegalStateException("stableCount < 0: " + stable); 7893 } 7894 7895 if (unstable > 0) { 7896 conn.numUnstableIncs += unstable; 7897 } 7898 unstable = conn.unstableCount + unstable; 7899 if (unstable < 0) { 7900 throw new IllegalStateException("unstableCount < 0: " + unstable); 7901 } 7902 7903 if ((stable+unstable) <= 0) { 7904 throw new IllegalStateException("ref counts can't go to zero here: stable=" 7905 + stable + " unstable=" + unstable); 7906 } 7907 conn.stableCount = stable; 7908 conn.unstableCount = unstable; 7909 return !conn.dead; 7910 } 7911 } 7912 7913 public void unstableProviderDied(IBinder connection) { 7914 ContentProviderConnection conn; 7915 try { 7916 conn = (ContentProviderConnection)connection; 7917 } catch (ClassCastException e) { 7918 String msg ="refContentProvider: " + connection 7919 + " not a ContentProviderConnection"; 7920 Slog.w(TAG, msg); 7921 throw new IllegalArgumentException(msg); 7922 } 7923 if (conn == null) { 7924 throw new NullPointerException("connection is null"); 7925 } 7926 7927 // Safely retrieve the content provider associated with the connection. 7928 IContentProvider provider; 7929 synchronized (this) { 7930 provider = conn.provider.provider; 7931 } 7932 7933 if (provider == null) { 7934 // Um, yeah, we're way ahead of you. 7935 return; 7936 } 7937 7938 // Make sure the caller is being honest with us. 7939 if (provider.asBinder().pingBinder()) { 7940 // Er, no, still looks good to us. 7941 synchronized (this) { 7942 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 7943 + " says " + conn + " died, but we don't agree"); 7944 return; 7945 } 7946 } 7947 7948 // Well look at that! It's dead! 7949 synchronized (this) { 7950 if (conn.provider.provider != provider) { 7951 // But something changed... good enough. 7952 return; 7953 } 7954 7955 ProcessRecord proc = conn.provider.proc; 7956 if (proc == null || proc.thread == null) { 7957 // Seems like the process is already cleaned up. 7958 return; 7959 } 7960 7961 // As far as we're concerned, this is just like receiving a 7962 // death notification... just a bit prematurely. 7963 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 7964 + ") early provider death"); 7965 final long ident = Binder.clearCallingIdentity(); 7966 try { 7967 appDiedLocked(proc, proc.pid, proc.thread); 7968 } finally { 7969 Binder.restoreCallingIdentity(ident); 7970 } 7971 } 7972 } 7973 7974 @Override 7975 public void appNotRespondingViaProvider(IBinder connection) { 7976 enforceCallingPermission( 7977 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 7978 7979 final ContentProviderConnection conn = (ContentProviderConnection) connection; 7980 if (conn == null) { 7981 Slog.w(TAG, "ContentProviderConnection is null"); 7982 return; 7983 } 7984 7985 final ProcessRecord host = conn.provider.proc; 7986 if (host == null) { 7987 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 7988 return; 7989 } 7990 7991 final long token = Binder.clearCallingIdentity(); 7992 try { 7993 appNotResponding(host, null, null, false, "ContentProvider not responding"); 7994 } finally { 7995 Binder.restoreCallingIdentity(token); 7996 } 7997 } 7998 7999 public static final void installSystemProviders() { 8000 List<ProviderInfo> providers; 8001 synchronized (mSelf) { 8002 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 8003 providers = mSelf.generateApplicationProvidersLocked(app); 8004 if (providers != null) { 8005 for (int i=providers.size()-1; i>=0; i--) { 8006 ProviderInfo pi = (ProviderInfo)providers.get(i); 8007 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8008 Slog.w(TAG, "Not installing system proc provider " + pi.name 8009 + ": not system .apk"); 8010 providers.remove(i); 8011 } 8012 } 8013 } 8014 } 8015 if (providers != null) { 8016 mSystemThread.installSystemProviders(providers); 8017 } 8018 8019 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 8020 8021 mSelf.mUsageStatsService.monitorPackages(); 8022 } 8023 8024 /** 8025 * Allows app to retrieve the MIME type of a URI without having permission 8026 * to access its content provider. 8027 * 8028 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8029 * 8030 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8031 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8032 */ 8033 public String getProviderMimeType(Uri uri, int userId) { 8034 enforceNotIsolatedCaller("getProviderMimeType"); 8035 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8036 userId, false, true, "getProviderMimeType", null); 8037 final String name = uri.getAuthority(); 8038 final long ident = Binder.clearCallingIdentity(); 8039 ContentProviderHolder holder = null; 8040 8041 try { 8042 holder = getContentProviderExternalUnchecked(name, null, userId); 8043 if (holder != null) { 8044 return holder.provider.getType(uri); 8045 } 8046 } catch (RemoteException e) { 8047 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8048 return null; 8049 } finally { 8050 if (holder != null) { 8051 removeContentProviderExternalUnchecked(name, null, userId); 8052 } 8053 Binder.restoreCallingIdentity(ident); 8054 } 8055 8056 return null; 8057 } 8058 8059 // ========================================================= 8060 // GLOBAL MANAGEMENT 8061 // ========================================================= 8062 8063 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8064 boolean isolated) { 8065 String proc = customProcess != null ? customProcess : info.processName; 8066 BatteryStatsImpl.Uid.Proc ps = null; 8067 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8068 int uid = info.uid; 8069 if (isolated) { 8070 int userId = UserHandle.getUserId(uid); 8071 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8072 while (true) { 8073 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8074 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8075 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8076 } 8077 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8078 mNextIsolatedProcessUid++; 8079 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8080 // No process for this uid, use it. 8081 break; 8082 } 8083 stepsLeft--; 8084 if (stepsLeft <= 0) { 8085 return null; 8086 } 8087 } 8088 } 8089 return new ProcessRecord(stats, info, proc, uid); 8090 } 8091 8092 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8093 ProcessRecord app; 8094 if (!isolated) { 8095 app = getProcessRecordLocked(info.processName, info.uid, true); 8096 } else { 8097 app = null; 8098 } 8099 8100 if (app == null) { 8101 app = newProcessRecordLocked(info, null, isolated); 8102 mProcessNames.put(info.processName, app.uid, app); 8103 if (isolated) { 8104 mIsolatedProcesses.put(app.uid, app); 8105 } 8106 updateLruProcessLocked(app, false, null); 8107 updateOomAdjLocked(); 8108 } 8109 8110 // This package really, really can not be stopped. 8111 try { 8112 AppGlobals.getPackageManager().setPackageStoppedState( 8113 info.packageName, false, UserHandle.getUserId(app.uid)); 8114 } catch (RemoteException e) { 8115 } catch (IllegalArgumentException e) { 8116 Slog.w(TAG, "Failed trying to unstop package " 8117 + info.packageName + ": " + e); 8118 } 8119 8120 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8121 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8122 app.persistent = true; 8123 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8124 } 8125 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8126 mPersistentStartingProcesses.add(app); 8127 startProcessLocked(app, "added application", app.processName); 8128 } 8129 8130 return app; 8131 } 8132 8133 public void unhandledBack() { 8134 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8135 "unhandledBack()"); 8136 8137 synchronized(this) { 8138 final long origId = Binder.clearCallingIdentity(); 8139 try { 8140 getFocusedStack().unhandledBackLocked(); 8141 } finally { 8142 Binder.restoreCallingIdentity(origId); 8143 } 8144 } 8145 } 8146 8147 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8148 enforceNotIsolatedCaller("openContentUri"); 8149 final int userId = UserHandle.getCallingUserId(); 8150 String name = uri.getAuthority(); 8151 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8152 ParcelFileDescriptor pfd = null; 8153 if (cph != null) { 8154 // We record the binder invoker's uid in thread-local storage before 8155 // going to the content provider to open the file. Later, in the code 8156 // that handles all permissions checks, we look for this uid and use 8157 // that rather than the Activity Manager's own uid. The effect is that 8158 // we do the check against the caller's permissions even though it looks 8159 // to the content provider like the Activity Manager itself is making 8160 // the request. 8161 sCallerIdentity.set(new Identity( 8162 Binder.getCallingPid(), Binder.getCallingUid())); 8163 try { 8164 pfd = cph.provider.openFile(null, uri, "r", null); 8165 } catch (FileNotFoundException e) { 8166 // do nothing; pfd will be returned null 8167 } finally { 8168 // Ensure that whatever happens, we clean up the identity state 8169 sCallerIdentity.remove(); 8170 } 8171 8172 // We've got the fd now, so we're done with the provider. 8173 removeContentProviderExternalUnchecked(name, null, userId); 8174 } else { 8175 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8176 } 8177 return pfd; 8178 } 8179 8180 // Actually is sleeping or shutting down or whatever else in the future 8181 // is an inactive state. 8182 public boolean isSleepingOrShuttingDown() { 8183 return mSleeping || mShuttingDown; 8184 } 8185 8186 public void goingToSleep() { 8187 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8188 != PackageManager.PERMISSION_GRANTED) { 8189 throw new SecurityException("Requires permission " 8190 + android.Manifest.permission.DEVICE_POWER); 8191 } 8192 8193 synchronized(this) { 8194 mWentToSleep = true; 8195 updateEventDispatchingLocked(); 8196 8197 if (!mSleeping) { 8198 mSleeping = true; 8199 mStackSupervisor.goingToSleepLocked(); 8200 8201 // Initialize the wake times of all processes. 8202 checkExcessivePowerUsageLocked(false); 8203 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8204 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8205 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8206 } 8207 } 8208 } 8209 8210 @Override 8211 public boolean shutdown(int timeout) { 8212 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8213 != PackageManager.PERMISSION_GRANTED) { 8214 throw new SecurityException("Requires permission " 8215 + android.Manifest.permission.SHUTDOWN); 8216 } 8217 8218 boolean timedout = false; 8219 8220 synchronized(this) { 8221 mShuttingDown = true; 8222 updateEventDispatchingLocked(); 8223 timedout = mStackSupervisor.shutdownLocked(timeout); 8224 } 8225 8226 mAppOpsService.shutdown(); 8227 mUsageStatsService.shutdown(); 8228 mBatteryStatsService.shutdown(); 8229 synchronized (this) { 8230 mProcessStats.shutdownLocked(); 8231 } 8232 8233 return timedout; 8234 } 8235 8236 public final void activitySlept(IBinder token) { 8237 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8238 8239 final long origId = Binder.clearCallingIdentity(); 8240 8241 synchronized (this) { 8242 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8243 if (r != null) { 8244 mStackSupervisor.activitySleptLocked(r); 8245 } 8246 } 8247 8248 Binder.restoreCallingIdentity(origId); 8249 } 8250 8251 void logLockScreen(String msg) { 8252 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8253 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8254 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8255 mStackSupervisor.mDismissKeyguardOnNextActivity); 8256 } 8257 8258 private void comeOutOfSleepIfNeededLocked() { 8259 if (!mWentToSleep && !mLockScreenShown) { 8260 if (mSleeping) { 8261 mSleeping = false; 8262 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8263 } 8264 } 8265 } 8266 8267 public void wakingUp() { 8268 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8269 != PackageManager.PERMISSION_GRANTED) { 8270 throw new SecurityException("Requires permission " 8271 + android.Manifest.permission.DEVICE_POWER); 8272 } 8273 8274 synchronized(this) { 8275 mWentToSleep = false; 8276 updateEventDispatchingLocked(); 8277 comeOutOfSleepIfNeededLocked(); 8278 } 8279 } 8280 8281 private void updateEventDispatchingLocked() { 8282 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8283 } 8284 8285 public void setLockScreenShown(boolean shown) { 8286 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8287 != PackageManager.PERMISSION_GRANTED) { 8288 throw new SecurityException("Requires permission " 8289 + android.Manifest.permission.DEVICE_POWER); 8290 } 8291 8292 synchronized(this) { 8293 long ident = Binder.clearCallingIdentity(); 8294 try { 8295 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8296 mLockScreenShown = shown; 8297 comeOutOfSleepIfNeededLocked(); 8298 } finally { 8299 Binder.restoreCallingIdentity(ident); 8300 } 8301 } 8302 } 8303 8304 public void stopAppSwitches() { 8305 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8306 != PackageManager.PERMISSION_GRANTED) { 8307 throw new SecurityException("Requires permission " 8308 + android.Manifest.permission.STOP_APP_SWITCHES); 8309 } 8310 8311 synchronized(this) { 8312 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8313 + APP_SWITCH_DELAY_TIME; 8314 mDidAppSwitch = false; 8315 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8316 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8317 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8318 } 8319 } 8320 8321 public void resumeAppSwitches() { 8322 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8323 != PackageManager.PERMISSION_GRANTED) { 8324 throw new SecurityException("Requires permission " 8325 + android.Manifest.permission.STOP_APP_SWITCHES); 8326 } 8327 8328 synchronized(this) { 8329 // Note that we don't execute any pending app switches... we will 8330 // let those wait until either the timeout, or the next start 8331 // activity request. 8332 mAppSwitchesAllowedTime = 0; 8333 } 8334 } 8335 8336 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8337 String name) { 8338 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8339 return true; 8340 } 8341 8342 final int perm = checkComponentPermission( 8343 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8344 callingUid, -1, true); 8345 if (perm == PackageManager.PERMISSION_GRANTED) { 8346 return true; 8347 } 8348 8349 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8350 return false; 8351 } 8352 8353 public void setDebugApp(String packageName, boolean waitForDebugger, 8354 boolean persistent) { 8355 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8356 "setDebugApp()"); 8357 8358 long ident = Binder.clearCallingIdentity(); 8359 try { 8360 // Note that this is not really thread safe if there are multiple 8361 // callers into it at the same time, but that's not a situation we 8362 // care about. 8363 if (persistent) { 8364 final ContentResolver resolver = mContext.getContentResolver(); 8365 Settings.Global.putString( 8366 resolver, Settings.Global.DEBUG_APP, 8367 packageName); 8368 Settings.Global.putInt( 8369 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8370 waitForDebugger ? 1 : 0); 8371 } 8372 8373 synchronized (this) { 8374 if (!persistent) { 8375 mOrigDebugApp = mDebugApp; 8376 mOrigWaitForDebugger = mWaitForDebugger; 8377 } 8378 mDebugApp = packageName; 8379 mWaitForDebugger = waitForDebugger; 8380 mDebugTransient = !persistent; 8381 if (packageName != null) { 8382 forceStopPackageLocked(packageName, -1, false, false, true, true, 8383 UserHandle.USER_ALL, "set debug app"); 8384 } 8385 } 8386 } finally { 8387 Binder.restoreCallingIdentity(ident); 8388 } 8389 } 8390 8391 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8392 synchronized (this) { 8393 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8394 if (!isDebuggable) { 8395 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8396 throw new SecurityException("Process not debuggable: " + app.packageName); 8397 } 8398 } 8399 8400 mOpenGlTraceApp = processName; 8401 } 8402 } 8403 8404 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8405 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8406 synchronized (this) { 8407 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8408 if (!isDebuggable) { 8409 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8410 throw new SecurityException("Process not debuggable: " + app.packageName); 8411 } 8412 } 8413 mProfileApp = processName; 8414 mProfileFile = profileFile; 8415 if (mProfileFd != null) { 8416 try { 8417 mProfileFd.close(); 8418 } catch (IOException e) { 8419 } 8420 mProfileFd = null; 8421 } 8422 mProfileFd = profileFd; 8423 mProfileType = 0; 8424 mAutoStopProfiler = autoStopProfiler; 8425 } 8426 } 8427 8428 @Override 8429 public void setAlwaysFinish(boolean enabled) { 8430 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8431 "setAlwaysFinish()"); 8432 8433 Settings.Global.putInt( 8434 mContext.getContentResolver(), 8435 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8436 8437 synchronized (this) { 8438 mAlwaysFinishActivities = enabled; 8439 } 8440 } 8441 8442 @Override 8443 public void setActivityController(IActivityController controller) { 8444 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8445 "setActivityController()"); 8446 synchronized (this) { 8447 mController = controller; 8448 Watchdog.getInstance().setActivityController(controller); 8449 } 8450 } 8451 8452 @Override 8453 public void setUserIsMonkey(boolean userIsMonkey) { 8454 synchronized (this) { 8455 synchronized (mPidsSelfLocked) { 8456 final int callingPid = Binder.getCallingPid(); 8457 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8458 if (precessRecord == null) { 8459 throw new SecurityException("Unknown process: " + callingPid); 8460 } 8461 if (precessRecord.instrumentationUiAutomationConnection == null) { 8462 throw new SecurityException("Only an instrumentation process " 8463 + "with a UiAutomation can call setUserIsMonkey"); 8464 } 8465 } 8466 mUserIsMonkey = userIsMonkey; 8467 } 8468 } 8469 8470 @Override 8471 public boolean isUserAMonkey() { 8472 synchronized (this) { 8473 // If there is a controller also implies the user is a monkey. 8474 return (mUserIsMonkey || mController != null); 8475 } 8476 } 8477 8478 public void requestBugReport() { 8479 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8480 SystemProperties.set("ctl.start", "bugreport"); 8481 } 8482 8483 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8484 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8485 } 8486 8487 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8488 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8489 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8490 } 8491 return KEY_DISPATCHING_TIMEOUT; 8492 } 8493 8494 @Override 8495 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8496 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8497 != PackageManager.PERMISSION_GRANTED) { 8498 throw new SecurityException("Requires permission " 8499 + android.Manifest.permission.FILTER_EVENTS); 8500 } 8501 ProcessRecord proc; 8502 long timeout; 8503 synchronized (this) { 8504 synchronized (mPidsSelfLocked) { 8505 proc = mPidsSelfLocked.get(pid); 8506 } 8507 timeout = getInputDispatchingTimeoutLocked(proc); 8508 } 8509 8510 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8511 return -1; 8512 } 8513 8514 return timeout; 8515 } 8516 8517 /** 8518 * Handle input dispatching timeouts. 8519 * Returns whether input dispatching should be aborted or not. 8520 */ 8521 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8522 final ActivityRecord activity, final ActivityRecord parent, 8523 final boolean aboveSystem, String reason) { 8524 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8525 != PackageManager.PERMISSION_GRANTED) { 8526 throw new SecurityException("Requires permission " 8527 + android.Manifest.permission.FILTER_EVENTS); 8528 } 8529 8530 final String annotation; 8531 if (reason == null) { 8532 annotation = "Input dispatching timed out"; 8533 } else { 8534 annotation = "Input dispatching timed out (" + reason + ")"; 8535 } 8536 8537 if (proc != null) { 8538 synchronized (this) { 8539 if (proc.debugging) { 8540 return false; 8541 } 8542 8543 if (mDidDexOpt) { 8544 // Give more time since we were dexopting. 8545 mDidDexOpt = false; 8546 return false; 8547 } 8548 8549 if (proc.instrumentationClass != null) { 8550 Bundle info = new Bundle(); 8551 info.putString("shortMsg", "keyDispatchingTimedOut"); 8552 info.putString("longMsg", annotation); 8553 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8554 return true; 8555 } 8556 } 8557 mHandler.post(new Runnable() { 8558 @Override 8559 public void run() { 8560 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8561 } 8562 }); 8563 } 8564 8565 return true; 8566 } 8567 8568 public Bundle getAssistContextExtras(int requestType) { 8569 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8570 "getAssistContextExtras()"); 8571 PendingAssistExtras pae; 8572 Bundle extras = new Bundle(); 8573 synchronized (this) { 8574 ActivityRecord activity = getFocusedStack().mResumedActivity; 8575 if (activity == null) { 8576 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8577 return null; 8578 } 8579 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8580 if (activity.app == null || activity.app.thread == null) { 8581 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8582 return extras; 8583 } 8584 if (activity.app.pid == Binder.getCallingPid()) { 8585 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8586 return extras; 8587 } 8588 pae = new PendingAssistExtras(activity); 8589 try { 8590 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8591 requestType); 8592 mPendingAssistExtras.add(pae); 8593 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8594 } catch (RemoteException e) { 8595 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8596 return extras; 8597 } 8598 } 8599 synchronized (pae) { 8600 while (!pae.haveResult) { 8601 try { 8602 pae.wait(); 8603 } catch (InterruptedException e) { 8604 } 8605 } 8606 if (pae.result != null) { 8607 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8608 } 8609 } 8610 synchronized (this) { 8611 mPendingAssistExtras.remove(pae); 8612 mHandler.removeCallbacks(pae); 8613 } 8614 return extras; 8615 } 8616 8617 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8618 PendingAssistExtras pae = (PendingAssistExtras)token; 8619 synchronized (pae) { 8620 pae.result = extras; 8621 pae.haveResult = true; 8622 pae.notifyAll(); 8623 } 8624 } 8625 8626 public void registerProcessObserver(IProcessObserver observer) { 8627 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8628 "registerProcessObserver()"); 8629 synchronized (this) { 8630 mProcessObservers.register(observer); 8631 } 8632 } 8633 8634 @Override 8635 public void unregisterProcessObserver(IProcessObserver observer) { 8636 synchronized (this) { 8637 mProcessObservers.unregister(observer); 8638 } 8639 } 8640 8641 @Override 8642 public boolean convertFromTranslucent(IBinder token) { 8643 final long origId = Binder.clearCallingIdentity(); 8644 try { 8645 synchronized (this) { 8646 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8647 if (r == null) { 8648 return false; 8649 } 8650 if (r.changeWindowTranslucency(true)) { 8651 mWindowManager.setAppFullscreen(token, true); 8652 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8653 return true; 8654 } 8655 return false; 8656 } 8657 } finally { 8658 Binder.restoreCallingIdentity(origId); 8659 } 8660 } 8661 8662 @Override 8663 public boolean convertToTranslucent(IBinder token) { 8664 final long origId = Binder.clearCallingIdentity(); 8665 try { 8666 synchronized (this) { 8667 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8668 if (r == null) { 8669 return false; 8670 } 8671 if (r.changeWindowTranslucency(false)) { 8672 r.task.stack.convertToTranslucent(r); 8673 mWindowManager.setAppFullscreen(token, false); 8674 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8675 return true; 8676 } 8677 return false; 8678 } 8679 } finally { 8680 Binder.restoreCallingIdentity(origId); 8681 } 8682 } 8683 8684 @Override 8685 public void setImmersive(IBinder token, boolean immersive) { 8686 synchronized(this) { 8687 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8688 if (r == null) { 8689 throw new IllegalArgumentException(); 8690 } 8691 r.immersive = immersive; 8692 8693 // update associated state if we're frontmost 8694 if (r == mFocusedActivity) { 8695 if (DEBUG_IMMERSIVE) { 8696 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8697 } 8698 applyUpdateLockStateLocked(r); 8699 } 8700 } 8701 } 8702 8703 @Override 8704 public boolean isImmersive(IBinder token) { 8705 synchronized (this) { 8706 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8707 if (r == null) { 8708 throw new IllegalArgumentException(); 8709 } 8710 return r.immersive; 8711 } 8712 } 8713 8714 public boolean isTopActivityImmersive() { 8715 enforceNotIsolatedCaller("startActivity"); 8716 synchronized (this) { 8717 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8718 return (r != null) ? r.immersive : false; 8719 } 8720 } 8721 8722 public final void enterSafeMode() { 8723 synchronized(this) { 8724 // It only makes sense to do this before the system is ready 8725 // and started launching other packages. 8726 if (!mSystemReady) { 8727 try { 8728 AppGlobals.getPackageManager().enterSafeMode(); 8729 } catch (RemoteException e) { 8730 } 8731 } 8732 } 8733 } 8734 8735 public final void showSafeModeOverlay() { 8736 View v = LayoutInflater.from(mContext).inflate( 8737 com.android.internal.R.layout.safe_mode, null); 8738 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8739 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8740 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8741 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8742 lp.gravity = Gravity.BOTTOM | Gravity.START; 8743 lp.format = v.getBackground().getOpacity(); 8744 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8745 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8746 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8747 ((WindowManager)mContext.getSystemService( 8748 Context.WINDOW_SERVICE)).addView(v, lp); 8749 } 8750 8751 public void noteWakeupAlarm(IIntentSender sender) { 8752 if (!(sender instanceof PendingIntentRecord)) { 8753 return; 8754 } 8755 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8756 synchronized (stats) { 8757 if (mBatteryStatsService.isOnBattery()) { 8758 mBatteryStatsService.enforceCallingPermission(); 8759 PendingIntentRecord rec = (PendingIntentRecord)sender; 8760 int MY_UID = Binder.getCallingUid(); 8761 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8762 BatteryStatsImpl.Uid.Pkg pkg = 8763 stats.getPackageStatsLocked(uid, rec.key.packageName); 8764 pkg.incWakeupsLocked(); 8765 } 8766 } 8767 } 8768 8769 public boolean killPids(int[] pids, String pReason, boolean secure) { 8770 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8771 throw new SecurityException("killPids only available to the system"); 8772 } 8773 String reason = (pReason == null) ? "Unknown" : pReason; 8774 // XXX Note: don't acquire main activity lock here, because the window 8775 // manager calls in with its locks held. 8776 8777 boolean killed = false; 8778 synchronized (mPidsSelfLocked) { 8779 int[] types = new int[pids.length]; 8780 int worstType = 0; 8781 for (int i=0; i<pids.length; i++) { 8782 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8783 if (proc != null) { 8784 int type = proc.setAdj; 8785 types[i] = type; 8786 if (type > worstType) { 8787 worstType = type; 8788 } 8789 } 8790 } 8791 8792 // If the worst oom_adj is somewhere in the cached proc LRU range, 8793 // then constrain it so we will kill all cached procs. 8794 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8795 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8796 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8797 } 8798 8799 // If this is not a secure call, don't let it kill processes that 8800 // are important. 8801 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8802 worstType = ProcessList.SERVICE_ADJ; 8803 } 8804 8805 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8806 for (int i=0; i<pids.length; i++) { 8807 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8808 if (proc == null) { 8809 continue; 8810 } 8811 int adj = proc.setAdj; 8812 if (adj >= worstType && !proc.killedByAm) { 8813 killUnneededProcessLocked(proc, reason); 8814 killed = true; 8815 } 8816 } 8817 } 8818 return killed; 8819 } 8820 8821 @Override 8822 public void killUid(int uid, String reason) { 8823 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8824 throw new SecurityException("killUid only available to the system"); 8825 } 8826 synchronized (this) { 8827 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 8828 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 8829 reason != null ? reason : "kill uid"); 8830 } 8831 } 8832 8833 @Override 8834 public boolean killProcessesBelowForeground(String reason) { 8835 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8836 throw new SecurityException("killProcessesBelowForeground() only available to system"); 8837 } 8838 8839 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 8840 } 8841 8842 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 8843 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8844 throw new SecurityException("killProcessesBelowAdj() only available to system"); 8845 } 8846 8847 boolean killed = false; 8848 synchronized (mPidsSelfLocked) { 8849 final int size = mPidsSelfLocked.size(); 8850 for (int i = 0; i < size; i++) { 8851 final int pid = mPidsSelfLocked.keyAt(i); 8852 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8853 if (proc == null) continue; 8854 8855 final int adj = proc.setAdj; 8856 if (adj > belowAdj && !proc.killedByAm) { 8857 killUnneededProcessLocked(proc, reason); 8858 killed = true; 8859 } 8860 } 8861 } 8862 return killed; 8863 } 8864 8865 @Override 8866 public void hang(final IBinder who, boolean allowRestart) { 8867 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8868 != PackageManager.PERMISSION_GRANTED) { 8869 throw new SecurityException("Requires permission " 8870 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8871 } 8872 8873 final IBinder.DeathRecipient death = new DeathRecipient() { 8874 @Override 8875 public void binderDied() { 8876 synchronized (this) { 8877 notifyAll(); 8878 } 8879 } 8880 }; 8881 8882 try { 8883 who.linkToDeath(death, 0); 8884 } catch (RemoteException e) { 8885 Slog.w(TAG, "hang: given caller IBinder is already dead."); 8886 return; 8887 } 8888 8889 synchronized (this) { 8890 Watchdog.getInstance().setAllowRestart(allowRestart); 8891 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 8892 synchronized (death) { 8893 while (who.isBinderAlive()) { 8894 try { 8895 death.wait(); 8896 } catch (InterruptedException e) { 8897 } 8898 } 8899 } 8900 Watchdog.getInstance().setAllowRestart(true); 8901 } 8902 } 8903 8904 @Override 8905 public void restart() { 8906 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8907 != PackageManager.PERMISSION_GRANTED) { 8908 throw new SecurityException("Requires permission " 8909 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8910 } 8911 8912 Log.i(TAG, "Sending shutdown broadcast..."); 8913 8914 BroadcastReceiver br = new BroadcastReceiver() { 8915 @Override public void onReceive(Context context, Intent intent) { 8916 // Now the broadcast is done, finish up the low-level shutdown. 8917 Log.i(TAG, "Shutting down activity manager..."); 8918 shutdown(10000); 8919 Log.i(TAG, "Shutdown complete, restarting!"); 8920 Process.killProcess(Process.myPid()); 8921 System.exit(10); 8922 } 8923 }; 8924 8925 // First send the high-level shut down broadcast. 8926 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 8927 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 8928 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 8929 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 8930 mContext.sendOrderedBroadcastAsUser(intent, 8931 UserHandle.ALL, null, br, mHandler, 0, null, null); 8932 */ 8933 br.onReceive(mContext, intent); 8934 } 8935 8936 private long getLowRamTimeSinceIdle(long now) { 8937 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 8938 } 8939 8940 @Override 8941 public void performIdleMaintenance() { 8942 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8943 != PackageManager.PERMISSION_GRANTED) { 8944 throw new SecurityException("Requires permission " 8945 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8946 } 8947 8948 synchronized (this) { 8949 final long now = SystemClock.uptimeMillis(); 8950 final long timeSinceLastIdle = now - mLastIdleTime; 8951 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 8952 mLastIdleTime = now; 8953 mLowRamTimeSinceLastIdle = 0; 8954 if (mLowRamStartTime != 0) { 8955 mLowRamStartTime = now; 8956 } 8957 8958 StringBuilder sb = new StringBuilder(128); 8959 sb.append("Idle maintenance over "); 8960 TimeUtils.formatDuration(timeSinceLastIdle, sb); 8961 sb.append(" low RAM for "); 8962 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 8963 Slog.i(TAG, sb.toString()); 8964 8965 // If at least 1/3 of our time since the last idle period has been spent 8966 // with RAM low, then we want to kill processes. 8967 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 8968 8969 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 8970 ProcessRecord proc = mLruProcesses.get(i); 8971 if (proc.notCachedSinceIdle) { 8972 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 8973 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 8974 if (doKilling && proc.initialIdlePss != 0 8975 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 8976 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 8977 + " from " + proc.initialIdlePss + ")"); 8978 } 8979 } 8980 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 8981 proc.notCachedSinceIdle = true; 8982 proc.initialIdlePss = 0; 8983 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 8984 mSleeping, now); 8985 } 8986 } 8987 8988 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 8989 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 8990 } 8991 } 8992 8993 public final void startRunning(String pkg, String cls, String action, 8994 String data) { 8995 synchronized(this) { 8996 if (mStartRunning) { 8997 return; 8998 } 8999 mStartRunning = true; 9000 mTopComponent = pkg != null && cls != null 9001 ? new ComponentName(pkg, cls) : null; 9002 mTopAction = action != null ? action : Intent.ACTION_MAIN; 9003 mTopData = data; 9004 if (!mSystemReady) { 9005 return; 9006 } 9007 } 9008 9009 systemReady(null); 9010 } 9011 9012 private void retrieveSettings() { 9013 final ContentResolver resolver = mContext.getContentResolver(); 9014 String debugApp = Settings.Global.getString( 9015 resolver, Settings.Global.DEBUG_APP); 9016 boolean waitForDebugger = Settings.Global.getInt( 9017 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9018 boolean alwaysFinishActivities = Settings.Global.getInt( 9019 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9020 boolean forceRtl = Settings.Global.getInt( 9021 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9022 // Transfer any global setting for forcing RTL layout, into a System Property 9023 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9024 9025 Configuration configuration = new Configuration(); 9026 Settings.System.getConfiguration(resolver, configuration); 9027 if (forceRtl) { 9028 // This will take care of setting the correct layout direction flags 9029 configuration.setLayoutDirection(configuration.locale); 9030 } 9031 9032 synchronized (this) { 9033 mDebugApp = mOrigDebugApp = debugApp; 9034 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9035 mAlwaysFinishActivities = alwaysFinishActivities; 9036 // This happens before any activities are started, so we can 9037 // change mConfiguration in-place. 9038 updateConfigurationLocked(configuration, null, false, true); 9039 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9040 } 9041 } 9042 9043 public boolean testIsSystemReady() { 9044 // no need to synchronize(this) just to read & return the value 9045 return mSystemReady; 9046 } 9047 9048 private static File getCalledPreBootReceiversFile() { 9049 File dataDir = Environment.getDataDirectory(); 9050 File systemDir = new File(dataDir, "system"); 9051 File fname = new File(systemDir, "called_pre_boots.dat"); 9052 return fname; 9053 } 9054 9055 static final int LAST_DONE_VERSION = 10000; 9056 9057 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9058 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9059 File file = getCalledPreBootReceiversFile(); 9060 FileInputStream fis = null; 9061 try { 9062 fis = new FileInputStream(file); 9063 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9064 int fvers = dis.readInt(); 9065 if (fvers == LAST_DONE_VERSION) { 9066 String vers = dis.readUTF(); 9067 String codename = dis.readUTF(); 9068 String build = dis.readUTF(); 9069 if (android.os.Build.VERSION.RELEASE.equals(vers) 9070 && android.os.Build.VERSION.CODENAME.equals(codename) 9071 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9072 int num = dis.readInt(); 9073 while (num > 0) { 9074 num--; 9075 String pkg = dis.readUTF(); 9076 String cls = dis.readUTF(); 9077 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9078 } 9079 } 9080 } 9081 } catch (FileNotFoundException e) { 9082 } catch (IOException e) { 9083 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9084 } finally { 9085 if (fis != null) { 9086 try { 9087 fis.close(); 9088 } catch (IOException e) { 9089 } 9090 } 9091 } 9092 return lastDoneReceivers; 9093 } 9094 9095 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9096 File file = getCalledPreBootReceiversFile(); 9097 FileOutputStream fos = null; 9098 DataOutputStream dos = null; 9099 try { 9100 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9101 fos = new FileOutputStream(file); 9102 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9103 dos.writeInt(LAST_DONE_VERSION); 9104 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9105 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9106 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9107 dos.writeInt(list.size()); 9108 for (int i=0; i<list.size(); i++) { 9109 dos.writeUTF(list.get(i).getPackageName()); 9110 dos.writeUTF(list.get(i).getClassName()); 9111 } 9112 } catch (IOException e) { 9113 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9114 file.delete(); 9115 } finally { 9116 FileUtils.sync(fos); 9117 if (dos != null) { 9118 try { 9119 dos.close(); 9120 } catch (IOException e) { 9121 // TODO Auto-generated catch block 9122 e.printStackTrace(); 9123 } 9124 } 9125 } 9126 } 9127 9128 public void systemReady(final Runnable goingCallback) { 9129 synchronized(this) { 9130 if (mSystemReady) { 9131 if (goingCallback != null) goingCallback.run(); 9132 return; 9133 } 9134 9135 // Check to see if there are any update receivers to run. 9136 if (!mDidUpdate) { 9137 if (mWaitingUpdate) { 9138 return; 9139 } 9140 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9141 List<ResolveInfo> ris = null; 9142 try { 9143 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9144 intent, null, 0, 0); 9145 } catch (RemoteException e) { 9146 } 9147 if (ris != null) { 9148 for (int i=ris.size()-1; i>=0; i--) { 9149 if ((ris.get(i).activityInfo.applicationInfo.flags 9150 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9151 ris.remove(i); 9152 } 9153 } 9154 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9155 9156 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9157 9158 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9159 for (int i=0; i<ris.size(); i++) { 9160 ActivityInfo ai = ris.get(i).activityInfo; 9161 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9162 if (lastDoneReceivers.contains(comp)) { 9163 ris.remove(i); 9164 i--; 9165 } 9166 } 9167 9168 final int[] users = getUsersLocked(); 9169 for (int i=0; i<ris.size(); i++) { 9170 ActivityInfo ai = ris.get(i).activityInfo; 9171 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9172 doneReceivers.add(comp); 9173 intent.setComponent(comp); 9174 for (int j=0; j<users.length; j++) { 9175 IIntentReceiver finisher = null; 9176 if (i == ris.size()-1 && j == users.length-1) { 9177 finisher = new IIntentReceiver.Stub() { 9178 public void performReceive(Intent intent, int resultCode, 9179 String data, Bundle extras, boolean ordered, 9180 boolean sticky, int sendingUser) { 9181 // The raw IIntentReceiver interface is called 9182 // with the AM lock held, so redispatch to 9183 // execute our code without the lock. 9184 mHandler.post(new Runnable() { 9185 public void run() { 9186 synchronized (ActivityManagerService.this) { 9187 mDidUpdate = true; 9188 } 9189 writeLastDonePreBootReceivers(doneReceivers); 9190 showBootMessage(mContext.getText( 9191 R.string.android_upgrading_complete), 9192 false); 9193 systemReady(goingCallback); 9194 } 9195 }); 9196 } 9197 }; 9198 } 9199 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9200 + " for user " + users[j]); 9201 broadcastIntentLocked(null, null, intent, null, finisher, 9202 0, null, null, null, AppOpsManager.OP_NONE, 9203 true, false, MY_PID, Process.SYSTEM_UID, 9204 users[j]); 9205 if (finisher != null) { 9206 mWaitingUpdate = true; 9207 } 9208 } 9209 } 9210 } 9211 if (mWaitingUpdate) { 9212 return; 9213 } 9214 mDidUpdate = true; 9215 } 9216 9217 mAppOpsService.systemReady(); 9218 mSystemReady = true; 9219 if (!mStartRunning) { 9220 return; 9221 } 9222 } 9223 9224 ArrayList<ProcessRecord> procsToKill = null; 9225 synchronized(mPidsSelfLocked) { 9226 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9227 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9228 if (!isAllowedWhileBooting(proc.info)){ 9229 if (procsToKill == null) { 9230 procsToKill = new ArrayList<ProcessRecord>(); 9231 } 9232 procsToKill.add(proc); 9233 } 9234 } 9235 } 9236 9237 synchronized(this) { 9238 if (procsToKill != null) { 9239 for (int i=procsToKill.size()-1; i>=0; i--) { 9240 ProcessRecord proc = procsToKill.get(i); 9241 Slog.i(TAG, "Removing system update proc: " + proc); 9242 removeProcessLocked(proc, true, false, "system update done"); 9243 } 9244 } 9245 9246 // Now that we have cleaned up any update processes, we 9247 // are ready to start launching real processes and know that 9248 // we won't trample on them any more. 9249 mProcessesReady = true; 9250 } 9251 9252 Slog.i(TAG, "System now ready"); 9253 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9254 SystemClock.uptimeMillis()); 9255 9256 synchronized(this) { 9257 // Make sure we have no pre-ready processes sitting around. 9258 9259 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 9260 ResolveInfo ri = mContext.getPackageManager() 9261 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9262 STOCK_PM_FLAGS); 9263 CharSequence errorMsg = null; 9264 if (ri != null) { 9265 ActivityInfo ai = ri.activityInfo; 9266 ApplicationInfo app = ai.applicationInfo; 9267 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9268 mTopAction = Intent.ACTION_FACTORY_TEST; 9269 mTopData = null; 9270 mTopComponent = new ComponentName(app.packageName, 9271 ai.name); 9272 } else { 9273 errorMsg = mContext.getResources().getText( 9274 com.android.internal.R.string.factorytest_not_system); 9275 } 9276 } else { 9277 errorMsg = mContext.getResources().getText( 9278 com.android.internal.R.string.factorytest_no_action); 9279 } 9280 if (errorMsg != null) { 9281 mTopAction = null; 9282 mTopData = null; 9283 mTopComponent = null; 9284 Message msg = Message.obtain(); 9285 msg.what = SHOW_FACTORY_ERROR_MSG; 9286 msg.getData().putCharSequence("msg", errorMsg); 9287 mHandler.sendMessage(msg); 9288 } 9289 } 9290 } 9291 9292 retrieveSettings(); 9293 9294 synchronized (this) { 9295 readGrantedUriPermissionsLocked(); 9296 } 9297 9298 if (goingCallback != null) goingCallback.run(); 9299 9300 synchronized (this) { 9301 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 9302 try { 9303 List apps = AppGlobals.getPackageManager(). 9304 getPersistentApplications(STOCK_PM_FLAGS); 9305 if (apps != null) { 9306 int N = apps.size(); 9307 int i; 9308 for (i=0; i<N; i++) { 9309 ApplicationInfo info 9310 = (ApplicationInfo)apps.get(i); 9311 if (info != null && 9312 !info.packageName.equals("android")) { 9313 addAppLocked(info, false); 9314 } 9315 } 9316 } 9317 } catch (RemoteException ex) { 9318 // pm is in same process, this will never happen. 9319 } 9320 } 9321 9322 // Start up initial activity. 9323 mBooting = true; 9324 9325 try { 9326 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9327 Message msg = Message.obtain(); 9328 msg.what = SHOW_UID_ERROR_MSG; 9329 mHandler.sendMessage(msg); 9330 } 9331 } catch (RemoteException e) { 9332 } 9333 9334 long ident = Binder.clearCallingIdentity(); 9335 try { 9336 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9337 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9338 | Intent.FLAG_RECEIVER_FOREGROUND); 9339 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9340 broadcastIntentLocked(null, null, intent, 9341 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9342 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9343 intent = new Intent(Intent.ACTION_USER_STARTING); 9344 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9345 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9346 broadcastIntentLocked(null, null, intent, 9347 null, new IIntentReceiver.Stub() { 9348 @Override 9349 public void performReceive(Intent intent, int resultCode, String data, 9350 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9351 throws RemoteException { 9352 } 9353 }, 0, null, null, 9354 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9355 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9356 } finally { 9357 Binder.restoreCallingIdentity(ident); 9358 } 9359 mStackSupervisor.resumeTopActivitiesLocked(); 9360 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9361 } 9362 } 9363 9364 private boolean makeAppCrashingLocked(ProcessRecord app, 9365 String shortMsg, String longMsg, String stackTrace) { 9366 app.crashing = true; 9367 app.crashingReport = generateProcessError(app, 9368 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9369 startAppProblemLocked(app); 9370 app.stopFreezingAllLocked(); 9371 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9372 } 9373 9374 private void makeAppNotRespondingLocked(ProcessRecord app, 9375 String activity, String shortMsg, String longMsg) { 9376 app.notResponding = true; 9377 app.notRespondingReport = generateProcessError(app, 9378 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9379 activity, shortMsg, longMsg, null); 9380 startAppProblemLocked(app); 9381 app.stopFreezingAllLocked(); 9382 } 9383 9384 /** 9385 * Generate a process error record, suitable for attachment to a ProcessRecord. 9386 * 9387 * @param app The ProcessRecord in which the error occurred. 9388 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9389 * ActivityManager.AppErrorStateInfo 9390 * @param activity The activity associated with the crash, if known. 9391 * @param shortMsg Short message describing the crash. 9392 * @param longMsg Long message describing the crash. 9393 * @param stackTrace Full crash stack trace, may be null. 9394 * 9395 * @return Returns a fully-formed AppErrorStateInfo record. 9396 */ 9397 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9398 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9399 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9400 9401 report.condition = condition; 9402 report.processName = app.processName; 9403 report.pid = app.pid; 9404 report.uid = app.info.uid; 9405 report.tag = activity; 9406 report.shortMsg = shortMsg; 9407 report.longMsg = longMsg; 9408 report.stackTrace = stackTrace; 9409 9410 return report; 9411 } 9412 9413 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9414 synchronized (this) { 9415 app.crashing = false; 9416 app.crashingReport = null; 9417 app.notResponding = false; 9418 app.notRespondingReport = null; 9419 if (app.anrDialog == fromDialog) { 9420 app.anrDialog = null; 9421 } 9422 if (app.waitDialog == fromDialog) { 9423 app.waitDialog = null; 9424 } 9425 if (app.pid > 0 && app.pid != MY_PID) { 9426 handleAppCrashLocked(app, null, null, null); 9427 killUnneededProcessLocked(app, "user request after error"); 9428 } 9429 } 9430 } 9431 9432 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9433 String stackTrace) { 9434 long now = SystemClock.uptimeMillis(); 9435 9436 Long crashTime; 9437 if (!app.isolated) { 9438 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9439 } else { 9440 crashTime = null; 9441 } 9442 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9443 // This process loses! 9444 Slog.w(TAG, "Process " + app.info.processName 9445 + " has crashed too many times: killing!"); 9446 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9447 app.userId, app.info.processName, app.uid); 9448 mStackSupervisor.handleAppCrashLocked(app); 9449 if (!app.persistent) { 9450 // We don't want to start this process again until the user 9451 // explicitly does so... but for persistent process, we really 9452 // need to keep it running. If a persistent process is actually 9453 // repeatedly crashing, then badness for everyone. 9454 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9455 app.info.processName); 9456 if (!app.isolated) { 9457 // XXX We don't have a way to mark isolated processes 9458 // as bad, since they don't have a peristent identity. 9459 mBadProcesses.put(app.info.processName, app.uid, 9460 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9461 mProcessCrashTimes.remove(app.info.processName, app.uid); 9462 } 9463 app.bad = true; 9464 app.removed = true; 9465 // Don't let services in this process be restarted and potentially 9466 // annoy the user repeatedly. Unless it is persistent, since those 9467 // processes run critical code. 9468 removeProcessLocked(app, false, false, "crash"); 9469 mStackSupervisor.resumeTopActivitiesLocked(); 9470 return false; 9471 } 9472 mStackSupervisor.resumeTopActivitiesLocked(); 9473 } else { 9474 mStackSupervisor.finishTopRunningActivityLocked(app); 9475 } 9476 9477 // Bump up the crash count of any services currently running in the proc. 9478 for (int i=app.services.size()-1; i>=0; i--) { 9479 // Any services running in the application need to be placed 9480 // back in the pending list. 9481 ServiceRecord sr = app.services.valueAt(i); 9482 sr.crashCount++; 9483 } 9484 9485 // If the crashing process is what we consider to be the "home process" and it has been 9486 // replaced by a third-party app, clear the package preferred activities from packages 9487 // with a home activity running in the process to prevent a repeatedly crashing app 9488 // from blocking the user to manually clear the list. 9489 final ArrayList<ActivityRecord> activities = app.activities; 9490 if (app == mHomeProcess && activities.size() > 0 9491 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9492 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9493 final ActivityRecord r = activities.get(activityNdx); 9494 if (r.isHomeActivity()) { 9495 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9496 try { 9497 ActivityThread.getPackageManager() 9498 .clearPackagePreferredActivities(r.packageName); 9499 } catch (RemoteException c) { 9500 // pm is in same process, this will never happen. 9501 } 9502 } 9503 } 9504 } 9505 9506 if (!app.isolated) { 9507 // XXX Can't keep track of crash times for isolated processes, 9508 // because they don't have a perisistent identity. 9509 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9510 } 9511 9512 return true; 9513 } 9514 9515 void startAppProblemLocked(ProcessRecord app) { 9516 if (app.userId == mCurrentUserId) { 9517 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9518 mContext, app.info.packageName, app.info.flags); 9519 } else { 9520 // If this app is not running under the current user, then we 9521 // can't give it a report button because that would require 9522 // launching the report UI under a different user. 9523 app.errorReportReceiver = null; 9524 } 9525 skipCurrentReceiverLocked(app); 9526 } 9527 9528 void skipCurrentReceiverLocked(ProcessRecord app) { 9529 for (BroadcastQueue queue : mBroadcastQueues) { 9530 queue.skipCurrentReceiverLocked(app); 9531 } 9532 } 9533 9534 /** 9535 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9536 * The application process will exit immediately after this call returns. 9537 * @param app object of the crashing app, null for the system server 9538 * @param crashInfo describing the exception 9539 */ 9540 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9541 ProcessRecord r = findAppProcess(app, "Crash"); 9542 final String processName = app == null ? "system_server" 9543 : (r == null ? "unknown" : r.processName); 9544 9545 handleApplicationCrashInner("crash", r, processName, crashInfo); 9546 } 9547 9548 /* Native crash reporting uses this inner version because it needs to be somewhat 9549 * decoupled from the AM-managed cleanup lifecycle 9550 */ 9551 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9552 ApplicationErrorReport.CrashInfo crashInfo) { 9553 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9554 UserHandle.getUserId(Binder.getCallingUid()), processName, 9555 r == null ? -1 : r.info.flags, 9556 crashInfo.exceptionClassName, 9557 crashInfo.exceptionMessage, 9558 crashInfo.throwFileName, 9559 crashInfo.throwLineNumber); 9560 9561 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9562 9563 crashApplication(r, crashInfo); 9564 } 9565 9566 public void handleApplicationStrictModeViolation( 9567 IBinder app, 9568 int violationMask, 9569 StrictMode.ViolationInfo info) { 9570 ProcessRecord r = findAppProcess(app, "StrictMode"); 9571 if (r == null) { 9572 return; 9573 } 9574 9575 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9576 Integer stackFingerprint = info.hashCode(); 9577 boolean logIt = true; 9578 synchronized (mAlreadyLoggedViolatedStacks) { 9579 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9580 logIt = false; 9581 // TODO: sub-sample into EventLog for these, with 9582 // the info.durationMillis? Then we'd get 9583 // the relative pain numbers, without logging all 9584 // the stack traces repeatedly. We'd want to do 9585 // likewise in the client code, which also does 9586 // dup suppression, before the Binder call. 9587 } else { 9588 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9589 mAlreadyLoggedViolatedStacks.clear(); 9590 } 9591 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9592 } 9593 } 9594 if (logIt) { 9595 logStrictModeViolationToDropBox(r, info); 9596 } 9597 } 9598 9599 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9600 AppErrorResult result = new AppErrorResult(); 9601 synchronized (this) { 9602 final long origId = Binder.clearCallingIdentity(); 9603 9604 Message msg = Message.obtain(); 9605 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9606 HashMap<String, Object> data = new HashMap<String, Object>(); 9607 data.put("result", result); 9608 data.put("app", r); 9609 data.put("violationMask", violationMask); 9610 data.put("info", info); 9611 msg.obj = data; 9612 mHandler.sendMessage(msg); 9613 9614 Binder.restoreCallingIdentity(origId); 9615 } 9616 int res = result.get(); 9617 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9618 } 9619 } 9620 9621 // Depending on the policy in effect, there could be a bunch of 9622 // these in quick succession so we try to batch these together to 9623 // minimize disk writes, number of dropbox entries, and maximize 9624 // compression, by having more fewer, larger records. 9625 private void logStrictModeViolationToDropBox( 9626 ProcessRecord process, 9627 StrictMode.ViolationInfo info) { 9628 if (info == null) { 9629 return; 9630 } 9631 final boolean isSystemApp = process == null || 9632 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9633 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9634 final String processName = process == null ? "unknown" : process.processName; 9635 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9636 final DropBoxManager dbox = (DropBoxManager) 9637 mContext.getSystemService(Context.DROPBOX_SERVICE); 9638 9639 // Exit early if the dropbox isn't configured to accept this report type. 9640 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9641 9642 boolean bufferWasEmpty; 9643 boolean needsFlush; 9644 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9645 synchronized (sb) { 9646 bufferWasEmpty = sb.length() == 0; 9647 appendDropBoxProcessHeaders(process, processName, sb); 9648 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9649 sb.append("System-App: ").append(isSystemApp).append("\n"); 9650 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9651 if (info.violationNumThisLoop != 0) { 9652 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9653 } 9654 if (info.numAnimationsRunning != 0) { 9655 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9656 } 9657 if (info.broadcastIntentAction != null) { 9658 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9659 } 9660 if (info.durationMillis != -1) { 9661 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9662 } 9663 if (info.numInstances != -1) { 9664 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9665 } 9666 if (info.tags != null) { 9667 for (String tag : info.tags) { 9668 sb.append("Span-Tag: ").append(tag).append("\n"); 9669 } 9670 } 9671 sb.append("\n"); 9672 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9673 sb.append(info.crashInfo.stackTrace); 9674 } 9675 sb.append("\n"); 9676 9677 // Only buffer up to ~64k. Various logging bits truncate 9678 // things at 128k. 9679 needsFlush = (sb.length() > 64 * 1024); 9680 } 9681 9682 // Flush immediately if the buffer's grown too large, or this 9683 // is a non-system app. Non-system apps are isolated with a 9684 // different tag & policy and not batched. 9685 // 9686 // Batching is useful during internal testing with 9687 // StrictMode settings turned up high. Without batching, 9688 // thousands of separate files could be created on boot. 9689 if (!isSystemApp || needsFlush) { 9690 new Thread("Error dump: " + dropboxTag) { 9691 @Override 9692 public void run() { 9693 String report; 9694 synchronized (sb) { 9695 report = sb.toString(); 9696 sb.delete(0, sb.length()); 9697 sb.trimToSize(); 9698 } 9699 if (report.length() != 0) { 9700 dbox.addText(dropboxTag, report); 9701 } 9702 } 9703 }.start(); 9704 return; 9705 } 9706 9707 // System app batching: 9708 if (!bufferWasEmpty) { 9709 // An existing dropbox-writing thread is outstanding, so 9710 // we don't need to start it up. The existing thread will 9711 // catch the buffer appends we just did. 9712 return; 9713 } 9714 9715 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9716 // (After this point, we shouldn't access AMS internal data structures.) 9717 new Thread("Error dump: " + dropboxTag) { 9718 @Override 9719 public void run() { 9720 // 5 second sleep to let stacks arrive and be batched together 9721 try { 9722 Thread.sleep(5000); // 5 seconds 9723 } catch (InterruptedException e) {} 9724 9725 String errorReport; 9726 synchronized (mStrictModeBuffer) { 9727 errorReport = mStrictModeBuffer.toString(); 9728 if (errorReport.length() == 0) { 9729 return; 9730 } 9731 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9732 mStrictModeBuffer.trimToSize(); 9733 } 9734 dbox.addText(dropboxTag, errorReport); 9735 } 9736 }.start(); 9737 } 9738 9739 /** 9740 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9741 * @param app object of the crashing app, null for the system server 9742 * @param tag reported by the caller 9743 * @param crashInfo describing the context of the error 9744 * @return true if the process should exit immediately (WTF is fatal) 9745 */ 9746 public boolean handleApplicationWtf(IBinder app, String tag, 9747 ApplicationErrorReport.CrashInfo crashInfo) { 9748 ProcessRecord r = findAppProcess(app, "WTF"); 9749 final String processName = app == null ? "system_server" 9750 : (r == null ? "unknown" : r.processName); 9751 9752 EventLog.writeEvent(EventLogTags.AM_WTF, 9753 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9754 processName, 9755 r == null ? -1 : r.info.flags, 9756 tag, crashInfo.exceptionMessage); 9757 9758 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9759 9760 if (r != null && r.pid != Process.myPid() && 9761 Settings.Global.getInt(mContext.getContentResolver(), 9762 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9763 crashApplication(r, crashInfo); 9764 return true; 9765 } else { 9766 return false; 9767 } 9768 } 9769 9770 /** 9771 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9772 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9773 */ 9774 private ProcessRecord findAppProcess(IBinder app, String reason) { 9775 if (app == null) { 9776 return null; 9777 } 9778 9779 synchronized (this) { 9780 final int NP = mProcessNames.getMap().size(); 9781 for (int ip=0; ip<NP; ip++) { 9782 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9783 final int NA = apps.size(); 9784 for (int ia=0; ia<NA; ia++) { 9785 ProcessRecord p = apps.valueAt(ia); 9786 if (p.thread != null && p.thread.asBinder() == app) { 9787 return p; 9788 } 9789 } 9790 } 9791 9792 Slog.w(TAG, "Can't find mystery application for " + reason 9793 + " from pid=" + Binder.getCallingPid() 9794 + " uid=" + Binder.getCallingUid() + ": " + app); 9795 return null; 9796 } 9797 } 9798 9799 /** 9800 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9801 * to append various headers to the dropbox log text. 9802 */ 9803 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9804 StringBuilder sb) { 9805 // Watchdog thread ends up invoking this function (with 9806 // a null ProcessRecord) to add the stack file to dropbox. 9807 // Do not acquire a lock on this (am) in such cases, as it 9808 // could cause a potential deadlock, if and when watchdog 9809 // is invoked due to unavailability of lock on am and it 9810 // would prevent watchdog from killing system_server. 9811 if (process == null) { 9812 sb.append("Process: ").append(processName).append("\n"); 9813 return; 9814 } 9815 // Note: ProcessRecord 'process' is guarded by the service 9816 // instance. (notably process.pkgList, which could otherwise change 9817 // concurrently during execution of this method) 9818 synchronized (this) { 9819 sb.append("Process: ").append(processName).append("\n"); 9820 int flags = process.info.flags; 9821 IPackageManager pm = AppGlobals.getPackageManager(); 9822 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 9823 for (int ip=0; ip<process.pkgList.size(); ip++) { 9824 String pkg = process.pkgList.keyAt(ip); 9825 sb.append("Package: ").append(pkg); 9826 try { 9827 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 9828 if (pi != null) { 9829 sb.append(" v").append(pi.versionCode); 9830 if (pi.versionName != null) { 9831 sb.append(" (").append(pi.versionName).append(")"); 9832 } 9833 } 9834 } catch (RemoteException e) { 9835 Slog.e(TAG, "Error getting package info: " + pkg, e); 9836 } 9837 sb.append("\n"); 9838 } 9839 } 9840 } 9841 9842 private static String processClass(ProcessRecord process) { 9843 if (process == null || process.pid == MY_PID) { 9844 return "system_server"; 9845 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9846 return "system_app"; 9847 } else { 9848 return "data_app"; 9849 } 9850 } 9851 9852 /** 9853 * Write a description of an error (crash, WTF, ANR) to the drop box. 9854 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 9855 * @param process which caused the error, null means the system server 9856 * @param activity which triggered the error, null if unknown 9857 * @param parent activity related to the error, null if unknown 9858 * @param subject line related to the error, null if absent 9859 * @param report in long form describing the error, null if absent 9860 * @param logFile to include in the report, null if none 9861 * @param crashInfo giving an application stack trace, null if absent 9862 */ 9863 public void addErrorToDropBox(String eventType, 9864 ProcessRecord process, String processName, ActivityRecord activity, 9865 ActivityRecord parent, String subject, 9866 final String report, final File logFile, 9867 final ApplicationErrorReport.CrashInfo crashInfo) { 9868 // NOTE -- this must never acquire the ActivityManagerService lock, 9869 // otherwise the watchdog may be prevented from resetting the system. 9870 9871 final String dropboxTag = processClass(process) + "_" + eventType; 9872 final DropBoxManager dbox = (DropBoxManager) 9873 mContext.getSystemService(Context.DROPBOX_SERVICE); 9874 9875 // Exit early if the dropbox isn't configured to accept this report type. 9876 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9877 9878 final StringBuilder sb = new StringBuilder(1024); 9879 appendDropBoxProcessHeaders(process, processName, sb); 9880 if (activity != null) { 9881 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 9882 } 9883 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 9884 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 9885 } 9886 if (parent != null && parent != activity) { 9887 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 9888 } 9889 if (subject != null) { 9890 sb.append("Subject: ").append(subject).append("\n"); 9891 } 9892 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9893 if (Debug.isDebuggerConnected()) { 9894 sb.append("Debugger: Connected\n"); 9895 } 9896 sb.append("\n"); 9897 9898 // Do the rest in a worker thread to avoid blocking the caller on I/O 9899 // (After this point, we shouldn't access AMS internal data structures.) 9900 Thread worker = new Thread("Error dump: " + dropboxTag) { 9901 @Override 9902 public void run() { 9903 if (report != null) { 9904 sb.append(report); 9905 } 9906 if (logFile != null) { 9907 try { 9908 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 9909 "\n\n[[TRUNCATED]]")); 9910 } catch (IOException e) { 9911 Slog.e(TAG, "Error reading " + logFile, e); 9912 } 9913 } 9914 if (crashInfo != null && crashInfo.stackTrace != null) { 9915 sb.append(crashInfo.stackTrace); 9916 } 9917 9918 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 9919 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 9920 if (lines > 0) { 9921 sb.append("\n"); 9922 9923 // Merge several logcat streams, and take the last N lines 9924 InputStreamReader input = null; 9925 try { 9926 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 9927 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 9928 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 9929 9930 try { logcat.getOutputStream().close(); } catch (IOException e) {} 9931 try { logcat.getErrorStream().close(); } catch (IOException e) {} 9932 input = new InputStreamReader(logcat.getInputStream()); 9933 9934 int num; 9935 char[] buf = new char[8192]; 9936 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 9937 } catch (IOException e) { 9938 Slog.e(TAG, "Error running logcat", e); 9939 } finally { 9940 if (input != null) try { input.close(); } catch (IOException e) {} 9941 } 9942 } 9943 9944 dbox.addText(dropboxTag, sb.toString()); 9945 } 9946 }; 9947 9948 if (process == null) { 9949 // If process is null, we are being called from some internal code 9950 // and may be about to die -- run this synchronously. 9951 worker.run(); 9952 } else { 9953 worker.start(); 9954 } 9955 } 9956 9957 /** 9958 * Bring up the "unexpected error" dialog box for a crashing app. 9959 * Deal with edge cases (intercepts from instrumented applications, 9960 * ActivityController, error intent receivers, that sort of thing). 9961 * @param r the application crashing 9962 * @param crashInfo describing the failure 9963 */ 9964 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 9965 long timeMillis = System.currentTimeMillis(); 9966 String shortMsg = crashInfo.exceptionClassName; 9967 String longMsg = crashInfo.exceptionMessage; 9968 String stackTrace = crashInfo.stackTrace; 9969 if (shortMsg != null && longMsg != null) { 9970 longMsg = shortMsg + ": " + longMsg; 9971 } else if (shortMsg != null) { 9972 longMsg = shortMsg; 9973 } 9974 9975 AppErrorResult result = new AppErrorResult(); 9976 synchronized (this) { 9977 if (mController != null) { 9978 try { 9979 String name = r != null ? r.processName : null; 9980 int pid = r != null ? r.pid : Binder.getCallingPid(); 9981 if (!mController.appCrashed(name, pid, 9982 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 9983 Slog.w(TAG, "Force-killing crashed app " + name 9984 + " at watcher's request"); 9985 Process.killProcess(pid); 9986 return; 9987 } 9988 } catch (RemoteException e) { 9989 mController = null; 9990 Watchdog.getInstance().setActivityController(null); 9991 } 9992 } 9993 9994 final long origId = Binder.clearCallingIdentity(); 9995 9996 // If this process is running instrumentation, finish it. 9997 if (r != null && r.instrumentationClass != null) { 9998 Slog.w(TAG, "Error in app " + r.processName 9999 + " running instrumentation " + r.instrumentationClass + ":"); 10000 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10001 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10002 Bundle info = new Bundle(); 10003 info.putString("shortMsg", shortMsg); 10004 info.putString("longMsg", longMsg); 10005 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10006 Binder.restoreCallingIdentity(origId); 10007 return; 10008 } 10009 10010 // If we can't identify the process or it's already exceeded its crash quota, 10011 // quit right away without showing a crash dialog. 10012 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10013 Binder.restoreCallingIdentity(origId); 10014 return; 10015 } 10016 10017 Message msg = Message.obtain(); 10018 msg.what = SHOW_ERROR_MSG; 10019 HashMap data = new HashMap(); 10020 data.put("result", result); 10021 data.put("app", r); 10022 msg.obj = data; 10023 mHandler.sendMessage(msg); 10024 10025 Binder.restoreCallingIdentity(origId); 10026 } 10027 10028 int res = result.get(); 10029 10030 Intent appErrorIntent = null; 10031 synchronized (this) { 10032 if (r != null && !r.isolated) { 10033 // XXX Can't keep track of crash time for isolated processes, 10034 // since they don't have a persistent identity. 10035 mProcessCrashTimes.put(r.info.processName, r.uid, 10036 SystemClock.uptimeMillis()); 10037 } 10038 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10039 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10040 } 10041 } 10042 10043 if (appErrorIntent != null) { 10044 try { 10045 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10046 } catch (ActivityNotFoundException e) { 10047 Slog.w(TAG, "bug report receiver dissappeared", e); 10048 } 10049 } 10050 } 10051 10052 Intent createAppErrorIntentLocked(ProcessRecord r, 10053 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10054 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10055 if (report == null) { 10056 return null; 10057 } 10058 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10059 result.setComponent(r.errorReportReceiver); 10060 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10061 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10062 return result; 10063 } 10064 10065 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10066 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10067 if (r.errorReportReceiver == null) { 10068 return null; 10069 } 10070 10071 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10072 return null; 10073 } 10074 10075 ApplicationErrorReport report = new ApplicationErrorReport(); 10076 report.packageName = r.info.packageName; 10077 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10078 report.processName = r.processName; 10079 report.time = timeMillis; 10080 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10081 10082 if (r.crashing || r.forceCrashReport) { 10083 report.type = ApplicationErrorReport.TYPE_CRASH; 10084 report.crashInfo = crashInfo; 10085 } else if (r.notResponding) { 10086 report.type = ApplicationErrorReport.TYPE_ANR; 10087 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10088 10089 report.anrInfo.activity = r.notRespondingReport.tag; 10090 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10091 report.anrInfo.info = r.notRespondingReport.longMsg; 10092 } 10093 10094 return report; 10095 } 10096 10097 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10098 enforceNotIsolatedCaller("getProcessesInErrorState"); 10099 // assume our apps are happy - lazy create the list 10100 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10101 10102 final boolean allUsers = ActivityManager.checkUidPermission( 10103 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10104 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10105 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10106 10107 synchronized (this) { 10108 10109 // iterate across all processes 10110 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10111 ProcessRecord app = mLruProcesses.get(i); 10112 if (!allUsers && app.userId != userId) { 10113 continue; 10114 } 10115 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10116 // This one's in trouble, so we'll generate a report for it 10117 // crashes are higher priority (in case there's a crash *and* an anr) 10118 ActivityManager.ProcessErrorStateInfo report = null; 10119 if (app.crashing) { 10120 report = app.crashingReport; 10121 } else if (app.notResponding) { 10122 report = app.notRespondingReport; 10123 } 10124 10125 if (report != null) { 10126 if (errList == null) { 10127 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10128 } 10129 errList.add(report); 10130 } else { 10131 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10132 " crashing = " + app.crashing + 10133 " notResponding = " + app.notResponding); 10134 } 10135 } 10136 } 10137 } 10138 10139 return errList; 10140 } 10141 10142 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10143 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10144 if (currApp != null) { 10145 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10146 } 10147 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10148 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10149 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10150 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10151 if (currApp != null) { 10152 currApp.lru = 0; 10153 } 10154 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10155 } else if (adj >= ProcessList.SERVICE_ADJ) { 10156 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10157 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10158 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10159 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10160 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10161 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10162 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10163 } else { 10164 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10165 } 10166 } 10167 10168 private void fillInProcMemInfo(ProcessRecord app, 10169 ActivityManager.RunningAppProcessInfo outInfo) { 10170 outInfo.pid = app.pid; 10171 outInfo.uid = app.info.uid; 10172 if (mHeavyWeightProcess == app) { 10173 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10174 } 10175 if (app.persistent) { 10176 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10177 } 10178 if (app.activities.size() > 0) { 10179 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10180 } 10181 outInfo.lastTrimLevel = app.trimMemoryLevel; 10182 int adj = app.curAdj; 10183 outInfo.importance = oomAdjToImportance(adj, outInfo); 10184 outInfo.importanceReasonCode = app.adjTypeCode; 10185 } 10186 10187 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10188 enforceNotIsolatedCaller("getRunningAppProcesses"); 10189 // Lazy instantiation of list 10190 List<ActivityManager.RunningAppProcessInfo> runList = null; 10191 final boolean allUsers = ActivityManager.checkUidPermission( 10192 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10193 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10194 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10195 synchronized (this) { 10196 // Iterate across all processes 10197 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10198 ProcessRecord app = mLruProcesses.get(i); 10199 if (!allUsers && app.userId != userId) { 10200 continue; 10201 } 10202 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10203 // Generate process state info for running application 10204 ActivityManager.RunningAppProcessInfo currApp = 10205 new ActivityManager.RunningAppProcessInfo(app.processName, 10206 app.pid, app.getPackageList()); 10207 fillInProcMemInfo(app, currApp); 10208 if (app.adjSource instanceof ProcessRecord) { 10209 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10210 currApp.importanceReasonImportance = oomAdjToImportance( 10211 app.adjSourceOom, null); 10212 } else if (app.adjSource instanceof ActivityRecord) { 10213 ActivityRecord r = (ActivityRecord)app.adjSource; 10214 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10215 } 10216 if (app.adjTarget instanceof ComponentName) { 10217 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10218 } 10219 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10220 // + " lru=" + currApp.lru); 10221 if (runList == null) { 10222 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10223 } 10224 runList.add(currApp); 10225 } 10226 } 10227 } 10228 return runList; 10229 } 10230 10231 public List<ApplicationInfo> getRunningExternalApplications() { 10232 enforceNotIsolatedCaller("getRunningExternalApplications"); 10233 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10234 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10235 if (runningApps != null && runningApps.size() > 0) { 10236 Set<String> extList = new HashSet<String>(); 10237 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10238 if (app.pkgList != null) { 10239 for (String pkg : app.pkgList) { 10240 extList.add(pkg); 10241 } 10242 } 10243 } 10244 IPackageManager pm = AppGlobals.getPackageManager(); 10245 for (String pkg : extList) { 10246 try { 10247 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10248 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10249 retList.add(info); 10250 } 10251 } catch (RemoteException e) { 10252 } 10253 } 10254 } 10255 return retList; 10256 } 10257 10258 @Override 10259 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10260 enforceNotIsolatedCaller("getMyMemoryState"); 10261 synchronized (this) { 10262 ProcessRecord proc; 10263 synchronized (mPidsSelfLocked) { 10264 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10265 } 10266 fillInProcMemInfo(proc, outInfo); 10267 } 10268 } 10269 10270 @Override 10271 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10272 if (checkCallingPermission(android.Manifest.permission.DUMP) 10273 != PackageManager.PERMISSION_GRANTED) { 10274 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10275 + Binder.getCallingPid() 10276 + ", uid=" + Binder.getCallingUid() 10277 + " without permission " 10278 + android.Manifest.permission.DUMP); 10279 return; 10280 } 10281 10282 boolean dumpAll = false; 10283 boolean dumpClient = false; 10284 String dumpPackage = null; 10285 10286 int opti = 0; 10287 while (opti < args.length) { 10288 String opt = args[opti]; 10289 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10290 break; 10291 } 10292 opti++; 10293 if ("-a".equals(opt)) { 10294 dumpAll = true; 10295 } else if ("-c".equals(opt)) { 10296 dumpClient = true; 10297 } else if ("-h".equals(opt)) { 10298 pw.println("Activity manager dump options:"); 10299 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10300 pw.println(" cmd may be one of:"); 10301 pw.println(" a[ctivities]: activity stack state"); 10302 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10303 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10304 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10305 pw.println(" o[om]: out of memory management"); 10306 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10307 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10308 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10309 pw.println(" service [COMP_SPEC]: service client-side state"); 10310 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10311 pw.println(" all: dump all activities"); 10312 pw.println(" top: dump the top activity"); 10313 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10314 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10315 pw.println(" a partial substring in a component name, a"); 10316 pw.println(" hex object identifier."); 10317 pw.println(" -a: include all available server state."); 10318 pw.println(" -c: include client state."); 10319 return; 10320 } else { 10321 pw.println("Unknown argument: " + opt + "; use -h for help"); 10322 } 10323 } 10324 10325 long origId = Binder.clearCallingIdentity(); 10326 boolean more = false; 10327 // Is the caller requesting to dump a particular piece of data? 10328 if (opti < args.length) { 10329 String cmd = args[opti]; 10330 opti++; 10331 if ("activities".equals(cmd) || "a".equals(cmd)) { 10332 synchronized (this) { 10333 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10334 } 10335 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10336 String[] newArgs; 10337 String name; 10338 if (opti >= args.length) { 10339 name = null; 10340 newArgs = EMPTY_STRING_ARRAY; 10341 } else { 10342 name = args[opti]; 10343 opti++; 10344 newArgs = new String[args.length - opti]; 10345 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10346 args.length - opti); 10347 } 10348 synchronized (this) { 10349 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10350 } 10351 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10352 String[] newArgs; 10353 String name; 10354 if (opti >= args.length) { 10355 name = null; 10356 newArgs = EMPTY_STRING_ARRAY; 10357 } else { 10358 name = args[opti]; 10359 opti++; 10360 newArgs = new String[args.length - opti]; 10361 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10362 args.length - opti); 10363 } 10364 synchronized (this) { 10365 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10366 } 10367 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10368 String[] newArgs; 10369 String name; 10370 if (opti >= args.length) { 10371 name = null; 10372 newArgs = EMPTY_STRING_ARRAY; 10373 } else { 10374 name = args[opti]; 10375 opti++; 10376 newArgs = new String[args.length - opti]; 10377 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10378 args.length - opti); 10379 } 10380 synchronized (this) { 10381 dumpProcessesLocked(fd, pw, args, opti, true, name); 10382 } 10383 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10384 synchronized (this) { 10385 dumpOomLocked(fd, pw, args, opti, true); 10386 } 10387 } else if ("provider".equals(cmd)) { 10388 String[] newArgs; 10389 String name; 10390 if (opti >= args.length) { 10391 name = null; 10392 newArgs = EMPTY_STRING_ARRAY; 10393 } else { 10394 name = args[opti]; 10395 opti++; 10396 newArgs = new String[args.length - opti]; 10397 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10398 } 10399 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10400 pw.println("No providers match: " + name); 10401 pw.println("Use -h for help."); 10402 } 10403 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10404 synchronized (this) { 10405 dumpProvidersLocked(fd, pw, args, opti, true, null); 10406 } 10407 } else if ("service".equals(cmd)) { 10408 String[] newArgs; 10409 String name; 10410 if (opti >= args.length) { 10411 name = null; 10412 newArgs = EMPTY_STRING_ARRAY; 10413 } else { 10414 name = args[opti]; 10415 opti++; 10416 newArgs = new String[args.length - opti]; 10417 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10418 args.length - opti); 10419 } 10420 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10421 pw.println("No services match: " + name); 10422 pw.println("Use -h for help."); 10423 } 10424 } else if ("package".equals(cmd)) { 10425 String[] newArgs; 10426 if (opti >= args.length) { 10427 pw.println("package: no package name specified"); 10428 pw.println("Use -h for help."); 10429 } else { 10430 dumpPackage = args[opti]; 10431 opti++; 10432 newArgs = new String[args.length - opti]; 10433 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10434 args.length - opti); 10435 args = newArgs; 10436 opti = 0; 10437 more = true; 10438 } 10439 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10440 synchronized (this) { 10441 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10442 } 10443 } else { 10444 // Dumping a single activity? 10445 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10446 pw.println("Bad activity command, or no activities match: " + cmd); 10447 pw.println("Use -h for help."); 10448 } 10449 } 10450 if (!more) { 10451 Binder.restoreCallingIdentity(origId); 10452 return; 10453 } 10454 } 10455 10456 // No piece of data specified, dump everything. 10457 synchronized (this) { 10458 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10459 pw.println(); 10460 if (dumpAll) { 10461 pw.println("-------------------------------------------------------------------------------"); 10462 } 10463 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10464 pw.println(); 10465 if (dumpAll) { 10466 pw.println("-------------------------------------------------------------------------------"); 10467 } 10468 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10469 pw.println(); 10470 if (dumpAll) { 10471 pw.println("-------------------------------------------------------------------------------"); 10472 } 10473 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10474 pw.println(); 10475 if (dumpAll) { 10476 pw.println("-------------------------------------------------------------------------------"); 10477 } 10478 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10479 pw.println(); 10480 if (dumpAll) { 10481 pw.println("-------------------------------------------------------------------------------"); 10482 } 10483 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10484 } 10485 Binder.restoreCallingIdentity(origId); 10486 } 10487 10488 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10489 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10490 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10491 10492 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10493 dumpPackage); 10494 boolean needSep = printedAnything; 10495 10496 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10497 dumpPackage, needSep, " mFocusedActivity: "); 10498 if (printed) { 10499 printedAnything = true; 10500 needSep = false; 10501 } 10502 10503 if (dumpPackage == null) { 10504 if (needSep) { 10505 pw.println(); 10506 } 10507 needSep = true; 10508 printedAnything = true; 10509 mStackSupervisor.dump(pw, " "); 10510 } 10511 10512 if (mRecentTasks.size() > 0) { 10513 boolean printedHeader = false; 10514 10515 final int N = mRecentTasks.size(); 10516 for (int i=0; i<N; i++) { 10517 TaskRecord tr = mRecentTasks.get(i); 10518 if (dumpPackage != null) { 10519 if (tr.realActivity == null || 10520 !dumpPackage.equals(tr.realActivity)) { 10521 continue; 10522 } 10523 } 10524 if (!printedHeader) { 10525 if (needSep) { 10526 pw.println(); 10527 } 10528 pw.println(" Recent tasks:"); 10529 printedHeader = true; 10530 printedAnything = true; 10531 } 10532 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10533 pw.println(tr); 10534 if (dumpAll) { 10535 mRecentTasks.get(i).dump(pw, " "); 10536 } 10537 } 10538 } 10539 10540 if (!printedAnything) { 10541 pw.println(" (nothing)"); 10542 } 10543 } 10544 10545 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10546 int opti, boolean dumpAll, String dumpPackage) { 10547 boolean needSep = false; 10548 boolean printedAnything = false; 10549 int numPers = 0; 10550 10551 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10552 10553 if (dumpAll) { 10554 final int NP = mProcessNames.getMap().size(); 10555 for (int ip=0; ip<NP; ip++) { 10556 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10557 final int NA = procs.size(); 10558 for (int ia=0; ia<NA; ia++) { 10559 ProcessRecord r = procs.valueAt(ia); 10560 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10561 continue; 10562 } 10563 if (!needSep) { 10564 pw.println(" All known processes:"); 10565 needSep = true; 10566 printedAnything = true; 10567 } 10568 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10569 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10570 pw.print(" "); pw.println(r); 10571 r.dump(pw, " "); 10572 if (r.persistent) { 10573 numPers++; 10574 } 10575 } 10576 } 10577 } 10578 10579 if (mIsolatedProcesses.size() > 0) { 10580 boolean printed = false; 10581 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10582 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10583 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10584 continue; 10585 } 10586 if (!printed) { 10587 if (needSep) { 10588 pw.println(); 10589 } 10590 pw.println(" Isolated process list (sorted by uid):"); 10591 printedAnything = true; 10592 printed = true; 10593 needSep = true; 10594 } 10595 pw.println(String.format("%sIsolated #%2d: %s", 10596 " ", i, r.toString())); 10597 } 10598 } 10599 10600 if (mLruProcesses.size() > 0) { 10601 if (needSep) { 10602 pw.println(); 10603 } 10604 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10605 pw.print(" total, non-act at "); 10606 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10607 pw.print(", non-svc at "); 10608 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10609 pw.println("):"); 10610 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10611 needSep = true; 10612 printedAnything = true; 10613 } 10614 10615 if (dumpAll || dumpPackage != null) { 10616 synchronized (mPidsSelfLocked) { 10617 boolean printed = false; 10618 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10619 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10620 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10621 continue; 10622 } 10623 if (!printed) { 10624 if (needSep) pw.println(); 10625 needSep = true; 10626 pw.println(" PID mappings:"); 10627 printed = true; 10628 printedAnything = true; 10629 } 10630 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10631 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10632 } 10633 } 10634 } 10635 10636 if (mForegroundProcesses.size() > 0) { 10637 synchronized (mPidsSelfLocked) { 10638 boolean printed = false; 10639 for (int i=0; i<mForegroundProcesses.size(); i++) { 10640 ProcessRecord r = mPidsSelfLocked.get( 10641 mForegroundProcesses.valueAt(i).pid); 10642 if (dumpPackage != null && (r == null 10643 || !r.pkgList.containsKey(dumpPackage))) { 10644 continue; 10645 } 10646 if (!printed) { 10647 if (needSep) pw.println(); 10648 needSep = true; 10649 pw.println(" Foreground Processes:"); 10650 printed = true; 10651 printedAnything = true; 10652 } 10653 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10654 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10655 } 10656 } 10657 } 10658 10659 if (mPersistentStartingProcesses.size() > 0) { 10660 if (needSep) pw.println(); 10661 needSep = true; 10662 printedAnything = true; 10663 pw.println(" Persisent processes that are starting:"); 10664 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10665 "Starting Norm", "Restarting PERS", dumpPackage); 10666 } 10667 10668 if (mRemovedProcesses.size() > 0) { 10669 if (needSep) pw.println(); 10670 needSep = true; 10671 printedAnything = true; 10672 pw.println(" Processes that are being removed:"); 10673 dumpProcessList(pw, this, mRemovedProcesses, " ", 10674 "Removed Norm", "Removed PERS", dumpPackage); 10675 } 10676 10677 if (mProcessesOnHold.size() > 0) { 10678 if (needSep) pw.println(); 10679 needSep = true; 10680 printedAnything = true; 10681 pw.println(" Processes that are on old until the system is ready:"); 10682 dumpProcessList(pw, this, mProcessesOnHold, " ", 10683 "OnHold Norm", "OnHold PERS", dumpPackage); 10684 } 10685 10686 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10687 10688 if (mProcessCrashTimes.getMap().size() > 0) { 10689 boolean printed = false; 10690 long now = SystemClock.uptimeMillis(); 10691 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10692 final int NP = pmap.size(); 10693 for (int ip=0; ip<NP; ip++) { 10694 String pname = pmap.keyAt(ip); 10695 SparseArray<Long> uids = pmap.valueAt(ip); 10696 final int N = uids.size(); 10697 for (int i=0; i<N; i++) { 10698 int puid = uids.keyAt(i); 10699 ProcessRecord r = mProcessNames.get(pname, puid); 10700 if (dumpPackage != null && (r == null 10701 || !r.pkgList.containsKey(dumpPackage))) { 10702 continue; 10703 } 10704 if (!printed) { 10705 if (needSep) pw.println(); 10706 needSep = true; 10707 pw.println(" Time since processes crashed:"); 10708 printed = true; 10709 printedAnything = true; 10710 } 10711 pw.print(" Process "); pw.print(pname); 10712 pw.print(" uid "); pw.print(puid); 10713 pw.print(": last crashed "); 10714 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10715 pw.println(" ago"); 10716 } 10717 } 10718 } 10719 10720 if (mBadProcesses.getMap().size() > 0) { 10721 boolean printed = false; 10722 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10723 final int NP = pmap.size(); 10724 for (int ip=0; ip<NP; ip++) { 10725 String pname = pmap.keyAt(ip); 10726 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10727 final int N = uids.size(); 10728 for (int i=0; i<N; i++) { 10729 int puid = uids.keyAt(i); 10730 ProcessRecord r = mProcessNames.get(pname, puid); 10731 if (dumpPackage != null && (r == null 10732 || !r.pkgList.containsKey(dumpPackage))) { 10733 continue; 10734 } 10735 if (!printed) { 10736 if (needSep) pw.println(); 10737 needSep = true; 10738 pw.println(" Bad processes:"); 10739 printedAnything = true; 10740 } 10741 BadProcessInfo info = uids.valueAt(i); 10742 pw.print(" Bad process "); pw.print(pname); 10743 pw.print(" uid "); pw.print(puid); 10744 pw.print(": crashed at time "); pw.println(info.time); 10745 if (info.shortMsg != null) { 10746 pw.print(" Short msg: "); pw.println(info.shortMsg); 10747 } 10748 if (info.longMsg != null) { 10749 pw.print(" Long msg: "); pw.println(info.longMsg); 10750 } 10751 if (info.stack != null) { 10752 pw.println(" Stack:"); 10753 int lastPos = 0; 10754 for (int pos=0; pos<info.stack.length(); pos++) { 10755 if (info.stack.charAt(pos) == '\n') { 10756 pw.print(" "); 10757 pw.write(info.stack, lastPos, pos-lastPos); 10758 pw.println(); 10759 lastPos = pos+1; 10760 } 10761 } 10762 if (lastPos < info.stack.length()) { 10763 pw.print(" "); 10764 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10765 pw.println(); 10766 } 10767 } 10768 } 10769 } 10770 } 10771 10772 if (dumpPackage == null) { 10773 pw.println(); 10774 needSep = false; 10775 pw.println(" mStartedUsers:"); 10776 for (int i=0; i<mStartedUsers.size(); i++) { 10777 UserStartedState uss = mStartedUsers.valueAt(i); 10778 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10779 pw.print(": "); uss.dump("", pw); 10780 } 10781 pw.print(" mStartedUserArray: ["); 10782 for (int i=0; i<mStartedUserArray.length; i++) { 10783 if (i > 0) pw.print(", "); 10784 pw.print(mStartedUserArray[i]); 10785 } 10786 pw.println("]"); 10787 pw.print(" mUserLru: ["); 10788 for (int i=0; i<mUserLru.size(); i++) { 10789 if (i > 0) pw.print(", "); 10790 pw.print(mUserLru.get(i)); 10791 } 10792 pw.println("]"); 10793 if (dumpAll) { 10794 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10795 } 10796 } 10797 if (mHomeProcess != null && (dumpPackage == null 10798 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10799 if (needSep) { 10800 pw.println(); 10801 needSep = false; 10802 } 10803 pw.println(" mHomeProcess: " + mHomeProcess); 10804 } 10805 if (mPreviousProcess != null && (dumpPackage == null 10806 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 10807 if (needSep) { 10808 pw.println(); 10809 needSep = false; 10810 } 10811 pw.println(" mPreviousProcess: " + mPreviousProcess); 10812 } 10813 if (dumpAll) { 10814 StringBuilder sb = new StringBuilder(128); 10815 sb.append(" mPreviousProcessVisibleTime: "); 10816 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 10817 pw.println(sb); 10818 } 10819 if (mHeavyWeightProcess != null && (dumpPackage == null 10820 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 10821 if (needSep) { 10822 pw.println(); 10823 needSep = false; 10824 } 10825 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10826 } 10827 if (dumpPackage == null) { 10828 pw.println(" mConfiguration: " + mConfiguration); 10829 } 10830 if (dumpAll) { 10831 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 10832 if (mCompatModePackages.getPackages().size() > 0) { 10833 boolean printed = false; 10834 for (Map.Entry<String, Integer> entry 10835 : mCompatModePackages.getPackages().entrySet()) { 10836 String pkg = entry.getKey(); 10837 int mode = entry.getValue(); 10838 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 10839 continue; 10840 } 10841 if (!printed) { 10842 pw.println(" mScreenCompatPackages:"); 10843 printed = true; 10844 } 10845 pw.print(" "); pw.print(pkg); pw.print(": "); 10846 pw.print(mode); pw.println(); 10847 } 10848 } 10849 } 10850 if (dumpPackage == null) { 10851 if (mSleeping || mWentToSleep || mLockScreenShown) { 10852 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 10853 + " mLockScreenShown " + mLockScreenShown); 10854 } 10855 if (mShuttingDown) { 10856 pw.println(" mShuttingDown=" + mShuttingDown); 10857 } 10858 } 10859 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 10860 || mOrigWaitForDebugger) { 10861 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 10862 || dumpPackage.equals(mOrigDebugApp)) { 10863 if (needSep) { 10864 pw.println(); 10865 needSep = false; 10866 } 10867 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 10868 + " mDebugTransient=" + mDebugTransient 10869 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 10870 } 10871 } 10872 if (mOpenGlTraceApp != null) { 10873 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 10874 if (needSep) { 10875 pw.println(); 10876 needSep = false; 10877 } 10878 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 10879 } 10880 } 10881 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 10882 || mProfileFd != null) { 10883 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 10884 if (needSep) { 10885 pw.println(); 10886 needSep = false; 10887 } 10888 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 10889 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 10890 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 10891 + mAutoStopProfiler); 10892 } 10893 } 10894 if (dumpPackage == null) { 10895 if (mAlwaysFinishActivities || mController != null) { 10896 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 10897 + " mController=" + mController); 10898 } 10899 if (dumpAll) { 10900 pw.println(" Total persistent processes: " + numPers); 10901 pw.println(" mStartRunning=" + mStartRunning 10902 + " mProcessesReady=" + mProcessesReady 10903 + " mSystemReady=" + mSystemReady); 10904 pw.println(" mBooting=" + mBooting 10905 + " mBooted=" + mBooted 10906 + " mFactoryTest=" + mFactoryTest); 10907 pw.print(" mLastPowerCheckRealtime="); 10908 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 10909 pw.println(""); 10910 pw.print(" mLastPowerCheckUptime="); 10911 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 10912 pw.println(""); 10913 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 10914 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 10915 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 10916 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 10917 + " (" + mLruProcesses.size() + " total)" 10918 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 10919 + " mNumServiceProcs=" + mNumServiceProcs 10920 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 10921 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 10922 + " mLastMemoryLevel" + mLastMemoryLevel 10923 + " mLastNumProcesses" + mLastNumProcesses); 10924 long now = SystemClock.uptimeMillis(); 10925 pw.print(" mLastIdleTime="); 10926 TimeUtils.formatDuration(now, mLastIdleTime, pw); 10927 pw.print(" mLowRamSinceLastIdle="); 10928 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 10929 pw.println(); 10930 } 10931 } 10932 10933 if (!printedAnything) { 10934 pw.println(" (nothing)"); 10935 } 10936 } 10937 10938 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 10939 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 10940 if (mProcessesToGc.size() > 0) { 10941 boolean printed = false; 10942 long now = SystemClock.uptimeMillis(); 10943 for (int i=0; i<mProcessesToGc.size(); i++) { 10944 ProcessRecord proc = mProcessesToGc.get(i); 10945 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 10946 continue; 10947 } 10948 if (!printed) { 10949 if (needSep) pw.println(); 10950 needSep = true; 10951 pw.println(" Processes that are waiting to GC:"); 10952 printed = true; 10953 } 10954 pw.print(" Process "); pw.println(proc); 10955 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 10956 pw.print(", last gced="); 10957 pw.print(now-proc.lastRequestedGc); 10958 pw.print(" ms ago, last lowMem="); 10959 pw.print(now-proc.lastLowMemory); 10960 pw.println(" ms ago"); 10961 10962 } 10963 } 10964 return needSep; 10965 } 10966 10967 void printOomLevel(PrintWriter pw, String name, int adj) { 10968 pw.print(" "); 10969 if (adj >= 0) { 10970 pw.print(' '); 10971 if (adj < 10) pw.print(' '); 10972 } else { 10973 if (adj > -10) pw.print(' '); 10974 } 10975 pw.print(adj); 10976 pw.print(": "); 10977 pw.print(name); 10978 pw.print(" ("); 10979 pw.print(mProcessList.getMemLevel(adj)/1024); 10980 pw.println(" kB)"); 10981 } 10982 10983 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10984 int opti, boolean dumpAll) { 10985 boolean needSep = false; 10986 10987 if (mLruProcesses.size() > 0) { 10988 if (needSep) pw.println(); 10989 needSep = true; 10990 pw.println(" OOM levels:"); 10991 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 10992 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 10993 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 10994 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 10995 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 10996 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 10997 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 10998 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 10999 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11000 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11001 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11002 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11003 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11004 11005 if (needSep) pw.println(); 11006 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11007 pw.print(" total, non-act at "); 11008 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11009 pw.print(", non-svc at "); 11010 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11011 pw.println("):"); 11012 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11013 needSep = true; 11014 } 11015 11016 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11017 11018 pw.println(); 11019 pw.println(" mHomeProcess: " + mHomeProcess); 11020 pw.println(" mPreviousProcess: " + mPreviousProcess); 11021 if (mHeavyWeightProcess != null) { 11022 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11023 } 11024 11025 return true; 11026 } 11027 11028 /** 11029 * There are three ways to call this: 11030 * - no provider specified: dump all the providers 11031 * - a flattened component name that matched an existing provider was specified as the 11032 * first arg: dump that one provider 11033 * - the first arg isn't the flattened component name of an existing provider: 11034 * dump all providers whose component contains the first arg as a substring 11035 */ 11036 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11037 int opti, boolean dumpAll) { 11038 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11039 } 11040 11041 static class ItemMatcher { 11042 ArrayList<ComponentName> components; 11043 ArrayList<String> strings; 11044 ArrayList<Integer> objects; 11045 boolean all; 11046 11047 ItemMatcher() { 11048 all = true; 11049 } 11050 11051 void build(String name) { 11052 ComponentName componentName = ComponentName.unflattenFromString(name); 11053 if (componentName != null) { 11054 if (components == null) { 11055 components = new ArrayList<ComponentName>(); 11056 } 11057 components.add(componentName); 11058 all = false; 11059 } else { 11060 int objectId = 0; 11061 // Not a '/' separated full component name; maybe an object ID? 11062 try { 11063 objectId = Integer.parseInt(name, 16); 11064 if (objects == null) { 11065 objects = new ArrayList<Integer>(); 11066 } 11067 objects.add(objectId); 11068 all = false; 11069 } catch (RuntimeException e) { 11070 // Not an integer; just do string match. 11071 if (strings == null) { 11072 strings = new ArrayList<String>(); 11073 } 11074 strings.add(name); 11075 all = false; 11076 } 11077 } 11078 } 11079 11080 int build(String[] args, int opti) { 11081 for (; opti<args.length; opti++) { 11082 String name = args[opti]; 11083 if ("--".equals(name)) { 11084 return opti+1; 11085 } 11086 build(name); 11087 } 11088 return opti; 11089 } 11090 11091 boolean match(Object object, ComponentName comp) { 11092 if (all) { 11093 return true; 11094 } 11095 if (components != null) { 11096 for (int i=0; i<components.size(); i++) { 11097 if (components.get(i).equals(comp)) { 11098 return true; 11099 } 11100 } 11101 } 11102 if (objects != null) { 11103 for (int i=0; i<objects.size(); i++) { 11104 if (System.identityHashCode(object) == objects.get(i)) { 11105 return true; 11106 } 11107 } 11108 } 11109 if (strings != null) { 11110 String flat = comp.flattenToString(); 11111 for (int i=0; i<strings.size(); i++) { 11112 if (flat.contains(strings.get(i))) { 11113 return true; 11114 } 11115 } 11116 } 11117 return false; 11118 } 11119 } 11120 11121 /** 11122 * There are three things that cmd can be: 11123 * - a flattened component name that matches an existing activity 11124 * - the cmd arg isn't the flattened component name of an existing activity: 11125 * dump all activity whose component contains the cmd as a substring 11126 * - A hex number of the ActivityRecord object instance. 11127 */ 11128 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11129 int opti, boolean dumpAll) { 11130 ArrayList<ActivityRecord> activities; 11131 11132 synchronized (this) { 11133 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11134 } 11135 11136 if (activities.size() <= 0) { 11137 return false; 11138 } 11139 11140 String[] newArgs = new String[args.length - opti]; 11141 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11142 11143 TaskRecord lastTask = null; 11144 boolean needSep = false; 11145 for (int i=activities.size()-1; i>=0; i--) { 11146 ActivityRecord r = activities.get(i); 11147 if (needSep) { 11148 pw.println(); 11149 } 11150 needSep = true; 11151 synchronized (this) { 11152 if (lastTask != r.task) { 11153 lastTask = r.task; 11154 pw.print("TASK "); pw.print(lastTask.affinity); 11155 pw.print(" id="); pw.println(lastTask.taskId); 11156 if (dumpAll) { 11157 lastTask.dump(pw, " "); 11158 } 11159 } 11160 } 11161 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11162 } 11163 return true; 11164 } 11165 11166 /** 11167 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11168 * there is a thread associated with the activity. 11169 */ 11170 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11171 final ActivityRecord r, String[] args, boolean dumpAll) { 11172 String innerPrefix = prefix + " "; 11173 synchronized (this) { 11174 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11175 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11176 pw.print(" pid="); 11177 if (r.app != null) pw.println(r.app.pid); 11178 else pw.println("(not running)"); 11179 if (dumpAll) { 11180 r.dump(pw, innerPrefix); 11181 } 11182 } 11183 if (r.app != null && r.app.thread != null) { 11184 // flush anything that is already in the PrintWriter since the thread is going 11185 // to write to the file descriptor directly 11186 pw.flush(); 11187 try { 11188 TransferPipe tp = new TransferPipe(); 11189 try { 11190 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11191 r.appToken, innerPrefix, args); 11192 tp.go(fd); 11193 } finally { 11194 tp.kill(); 11195 } 11196 } catch (IOException e) { 11197 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11198 } catch (RemoteException e) { 11199 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11200 } 11201 } 11202 } 11203 11204 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11205 int opti, boolean dumpAll, String dumpPackage) { 11206 boolean needSep = false; 11207 boolean onlyHistory = false; 11208 boolean printedAnything = false; 11209 11210 if ("history".equals(dumpPackage)) { 11211 if (opti < args.length && "-s".equals(args[opti])) { 11212 dumpAll = false; 11213 } 11214 onlyHistory = true; 11215 dumpPackage = null; 11216 } 11217 11218 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11219 if (!onlyHistory && dumpAll) { 11220 if (mRegisteredReceivers.size() > 0) { 11221 boolean printed = false; 11222 Iterator it = mRegisteredReceivers.values().iterator(); 11223 while (it.hasNext()) { 11224 ReceiverList r = (ReceiverList)it.next(); 11225 if (dumpPackage != null && (r.app == null || 11226 !dumpPackage.equals(r.app.info.packageName))) { 11227 continue; 11228 } 11229 if (!printed) { 11230 pw.println(" Registered Receivers:"); 11231 needSep = true; 11232 printed = true; 11233 printedAnything = true; 11234 } 11235 pw.print(" * "); pw.println(r); 11236 r.dump(pw, " "); 11237 } 11238 } 11239 11240 if (mReceiverResolver.dump(pw, needSep ? 11241 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11242 " ", dumpPackage, false)) { 11243 needSep = true; 11244 printedAnything = true; 11245 } 11246 } 11247 11248 for (BroadcastQueue q : mBroadcastQueues) { 11249 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11250 printedAnything |= needSep; 11251 } 11252 11253 needSep = true; 11254 11255 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11256 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11257 if (needSep) { 11258 pw.println(); 11259 } 11260 needSep = true; 11261 printedAnything = true; 11262 pw.print(" Sticky broadcasts for user "); 11263 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11264 StringBuilder sb = new StringBuilder(128); 11265 for (Map.Entry<String, ArrayList<Intent>> ent 11266 : mStickyBroadcasts.valueAt(user).entrySet()) { 11267 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11268 if (dumpAll) { 11269 pw.println(":"); 11270 ArrayList<Intent> intents = ent.getValue(); 11271 final int N = intents.size(); 11272 for (int i=0; i<N; i++) { 11273 sb.setLength(0); 11274 sb.append(" Intent: "); 11275 intents.get(i).toShortString(sb, false, true, false, false); 11276 pw.println(sb.toString()); 11277 Bundle bundle = intents.get(i).getExtras(); 11278 if (bundle != null) { 11279 pw.print(" "); 11280 pw.println(bundle.toString()); 11281 } 11282 } 11283 } else { 11284 pw.println(""); 11285 } 11286 } 11287 } 11288 } 11289 11290 if (!onlyHistory && dumpAll) { 11291 pw.println(); 11292 for (BroadcastQueue queue : mBroadcastQueues) { 11293 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11294 + queue.mBroadcastsScheduled); 11295 } 11296 pw.println(" mHandler:"); 11297 mHandler.dump(new PrintWriterPrinter(pw), " "); 11298 needSep = true; 11299 printedAnything = true; 11300 } 11301 11302 if (!printedAnything) { 11303 pw.println(" (nothing)"); 11304 } 11305 } 11306 11307 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11308 int opti, boolean dumpAll, String dumpPackage) { 11309 boolean needSep; 11310 boolean printedAnything = false; 11311 11312 ItemMatcher matcher = new ItemMatcher(); 11313 matcher.build(args, opti); 11314 11315 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11316 11317 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11318 printedAnything |= needSep; 11319 11320 if (mLaunchingProviders.size() > 0) { 11321 boolean printed = false; 11322 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11323 ContentProviderRecord r = mLaunchingProviders.get(i); 11324 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11325 continue; 11326 } 11327 if (!printed) { 11328 if (needSep) pw.println(); 11329 needSep = true; 11330 pw.println(" Launching content providers:"); 11331 printed = true; 11332 printedAnything = true; 11333 } 11334 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11335 pw.println(r); 11336 } 11337 } 11338 11339 if (mGrantedUriPermissions.size() > 0) { 11340 boolean printed = false; 11341 int dumpUid = -2; 11342 if (dumpPackage != null) { 11343 try { 11344 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11345 } catch (NameNotFoundException e) { 11346 dumpUid = -1; 11347 } 11348 } 11349 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11350 int uid = mGrantedUriPermissions.keyAt(i); 11351 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11352 continue; 11353 } 11354 ArrayMap<Uri, UriPermission> perms 11355 = mGrantedUriPermissions.valueAt(i); 11356 if (!printed) { 11357 if (needSep) pw.println(); 11358 needSep = true; 11359 pw.println(" Granted Uri Permissions:"); 11360 printed = true; 11361 printedAnything = true; 11362 } 11363 pw.print(" * UID "); pw.print(uid); 11364 pw.println(" holds:"); 11365 for (UriPermission perm : perms.values()) { 11366 pw.print(" "); pw.println(perm); 11367 if (dumpAll) { 11368 perm.dump(pw, " "); 11369 } 11370 } 11371 } 11372 } 11373 11374 if (!printedAnything) { 11375 pw.println(" (nothing)"); 11376 } 11377 } 11378 11379 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11380 int opti, boolean dumpAll, String dumpPackage) { 11381 boolean printed = false; 11382 11383 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11384 11385 if (mIntentSenderRecords.size() > 0) { 11386 Iterator<WeakReference<PendingIntentRecord>> it 11387 = mIntentSenderRecords.values().iterator(); 11388 while (it.hasNext()) { 11389 WeakReference<PendingIntentRecord> ref = it.next(); 11390 PendingIntentRecord rec = ref != null ? ref.get(): null; 11391 if (dumpPackage != null && (rec == null 11392 || !dumpPackage.equals(rec.key.packageName))) { 11393 continue; 11394 } 11395 printed = true; 11396 if (rec != null) { 11397 pw.print(" * "); pw.println(rec); 11398 if (dumpAll) { 11399 rec.dump(pw, " "); 11400 } 11401 } else { 11402 pw.print(" * "); pw.println(ref); 11403 } 11404 } 11405 } 11406 11407 if (!printed) { 11408 pw.println(" (nothing)"); 11409 } 11410 } 11411 11412 private static final int dumpProcessList(PrintWriter pw, 11413 ActivityManagerService service, List list, 11414 String prefix, String normalLabel, String persistentLabel, 11415 String dumpPackage) { 11416 int numPers = 0; 11417 final int N = list.size()-1; 11418 for (int i=N; i>=0; i--) { 11419 ProcessRecord r = (ProcessRecord)list.get(i); 11420 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11421 continue; 11422 } 11423 pw.println(String.format("%s%s #%2d: %s", 11424 prefix, (r.persistent ? persistentLabel : normalLabel), 11425 i, r.toString())); 11426 if (r.persistent) { 11427 numPers++; 11428 } 11429 } 11430 return numPers; 11431 } 11432 11433 private static final boolean dumpProcessOomList(PrintWriter pw, 11434 ActivityManagerService service, List<ProcessRecord> origList, 11435 String prefix, String normalLabel, String persistentLabel, 11436 boolean inclDetails, String dumpPackage) { 11437 11438 ArrayList<Pair<ProcessRecord, Integer>> list 11439 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11440 for (int i=0; i<origList.size(); i++) { 11441 ProcessRecord r = origList.get(i); 11442 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11443 continue; 11444 } 11445 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11446 } 11447 11448 if (list.size() <= 0) { 11449 return false; 11450 } 11451 11452 Comparator<Pair<ProcessRecord, Integer>> comparator 11453 = new Comparator<Pair<ProcessRecord, Integer>>() { 11454 @Override 11455 public int compare(Pair<ProcessRecord, Integer> object1, 11456 Pair<ProcessRecord, Integer> object2) { 11457 if (object1.first.setAdj != object2.first.setAdj) { 11458 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11459 } 11460 if (object1.second.intValue() != object2.second.intValue()) { 11461 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11462 } 11463 return 0; 11464 } 11465 }; 11466 11467 Collections.sort(list, comparator); 11468 11469 final long curRealtime = SystemClock.elapsedRealtime(); 11470 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11471 final long curUptime = SystemClock.uptimeMillis(); 11472 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11473 11474 for (int i=list.size()-1; i>=0; i--) { 11475 ProcessRecord r = list.get(i).first; 11476 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11477 char schedGroup; 11478 switch (r.setSchedGroup) { 11479 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11480 schedGroup = 'B'; 11481 break; 11482 case Process.THREAD_GROUP_DEFAULT: 11483 schedGroup = 'F'; 11484 break; 11485 default: 11486 schedGroup = '?'; 11487 break; 11488 } 11489 char foreground; 11490 if (r.foregroundActivities) { 11491 foreground = 'A'; 11492 } else if (r.foregroundServices) { 11493 foreground = 'S'; 11494 } else { 11495 foreground = ' '; 11496 } 11497 String procState = ProcessList.makeProcStateString(r.curProcState); 11498 pw.print(prefix); 11499 pw.print(r.persistent ? persistentLabel : normalLabel); 11500 pw.print(" #"); 11501 int num = (origList.size()-1)-list.get(i).second; 11502 if (num < 10) pw.print(' '); 11503 pw.print(num); 11504 pw.print(": "); 11505 pw.print(oomAdj); 11506 pw.print(' '); 11507 pw.print(schedGroup); 11508 pw.print('/'); 11509 pw.print(foreground); 11510 pw.print('/'); 11511 pw.print(procState); 11512 pw.print(" trm:"); 11513 if (r.trimMemoryLevel < 10) pw.print(' '); 11514 pw.print(r.trimMemoryLevel); 11515 pw.print(' '); 11516 pw.print(r.toShortString()); 11517 pw.print(" ("); 11518 pw.print(r.adjType); 11519 pw.println(')'); 11520 if (r.adjSource != null || r.adjTarget != null) { 11521 pw.print(prefix); 11522 pw.print(" "); 11523 if (r.adjTarget instanceof ComponentName) { 11524 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11525 } else if (r.adjTarget != null) { 11526 pw.print(r.adjTarget.toString()); 11527 } else { 11528 pw.print("{null}"); 11529 } 11530 pw.print("<="); 11531 if (r.adjSource instanceof ProcessRecord) { 11532 pw.print("Proc{"); 11533 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11534 pw.println("}"); 11535 } else if (r.adjSource != null) { 11536 pw.println(r.adjSource.toString()); 11537 } else { 11538 pw.println("{null}"); 11539 } 11540 } 11541 if (inclDetails) { 11542 pw.print(prefix); 11543 pw.print(" "); 11544 pw.print("oom: max="); pw.print(r.maxAdj); 11545 pw.print(" curRaw="); pw.print(r.curRawAdj); 11546 pw.print(" setRaw="); pw.print(r.setRawAdj); 11547 pw.print(" cur="); pw.print(r.curAdj); 11548 pw.print(" set="); pw.println(r.setAdj); 11549 pw.print(prefix); 11550 pw.print(" "); 11551 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11552 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11553 pw.print(" lastPss="); pw.print(r.lastPss); 11554 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11555 pw.print(prefix); 11556 pw.print(" "); 11557 pw.print("keeping="); pw.print(r.keeping); 11558 pw.print(" cached="); pw.print(r.cached); 11559 pw.print(" empty="); pw.print(r.empty); 11560 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11561 11562 if (!r.keeping) { 11563 if (r.lastWakeTime != 0) { 11564 long wtime; 11565 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11566 synchronized (stats) { 11567 wtime = stats.getProcessWakeTime(r.info.uid, 11568 r.pid, curRealtime); 11569 } 11570 long timeUsed = wtime - r.lastWakeTime; 11571 pw.print(prefix); 11572 pw.print(" "); 11573 pw.print("keep awake over "); 11574 TimeUtils.formatDuration(realtimeSince, pw); 11575 pw.print(" used "); 11576 TimeUtils.formatDuration(timeUsed, pw); 11577 pw.print(" ("); 11578 pw.print((timeUsed*100)/realtimeSince); 11579 pw.println("%)"); 11580 } 11581 if (r.lastCpuTime != 0) { 11582 long timeUsed = r.curCpuTime - r.lastCpuTime; 11583 pw.print(prefix); 11584 pw.print(" "); 11585 pw.print("run cpu over "); 11586 TimeUtils.formatDuration(uptimeSince, pw); 11587 pw.print(" used "); 11588 TimeUtils.formatDuration(timeUsed, pw); 11589 pw.print(" ("); 11590 pw.print((timeUsed*100)/uptimeSince); 11591 pw.println("%)"); 11592 } 11593 } 11594 } 11595 } 11596 return true; 11597 } 11598 11599 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11600 ArrayList<ProcessRecord> procs; 11601 synchronized (this) { 11602 if (args != null && args.length > start 11603 && args[start].charAt(0) != '-') { 11604 procs = new ArrayList<ProcessRecord>(); 11605 int pid = -1; 11606 try { 11607 pid = Integer.parseInt(args[start]); 11608 } catch (NumberFormatException e) { 11609 } 11610 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11611 ProcessRecord proc = mLruProcesses.get(i); 11612 if (proc.pid == pid) { 11613 procs.add(proc); 11614 } else if (proc.processName.equals(args[start])) { 11615 procs.add(proc); 11616 } 11617 } 11618 if (procs.size() <= 0) { 11619 return null; 11620 } 11621 } else { 11622 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11623 } 11624 } 11625 return procs; 11626 } 11627 11628 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11629 PrintWriter pw, String[] args) { 11630 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11631 if (procs == null) { 11632 pw.println("No process found for: " + args[0]); 11633 return; 11634 } 11635 11636 long uptime = SystemClock.uptimeMillis(); 11637 long realtime = SystemClock.elapsedRealtime(); 11638 pw.println("Applications Graphics Acceleration Info:"); 11639 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11640 11641 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11642 ProcessRecord r = procs.get(i); 11643 if (r.thread != null) { 11644 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11645 pw.flush(); 11646 try { 11647 TransferPipe tp = new TransferPipe(); 11648 try { 11649 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11650 tp.go(fd); 11651 } finally { 11652 tp.kill(); 11653 } 11654 } catch (IOException e) { 11655 pw.println("Failure while dumping the app: " + r); 11656 pw.flush(); 11657 } catch (RemoteException e) { 11658 pw.println("Got a RemoteException while dumping the app " + r); 11659 pw.flush(); 11660 } 11661 } 11662 } 11663 } 11664 11665 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11666 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11667 if (procs == null) { 11668 pw.println("No process found for: " + args[0]); 11669 return; 11670 } 11671 11672 pw.println("Applications Database Info:"); 11673 11674 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11675 ProcessRecord r = procs.get(i); 11676 if (r.thread != null) { 11677 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11678 pw.flush(); 11679 try { 11680 TransferPipe tp = new TransferPipe(); 11681 try { 11682 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11683 tp.go(fd); 11684 } finally { 11685 tp.kill(); 11686 } 11687 } catch (IOException e) { 11688 pw.println("Failure while dumping the app: " + r); 11689 pw.flush(); 11690 } catch (RemoteException e) { 11691 pw.println("Got a RemoteException while dumping the app " + r); 11692 pw.flush(); 11693 } 11694 } 11695 } 11696 } 11697 11698 final static class MemItem { 11699 final boolean isProc; 11700 final String label; 11701 final String shortLabel; 11702 final long pss; 11703 final int id; 11704 final boolean hasActivities; 11705 ArrayList<MemItem> subitems; 11706 11707 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11708 boolean _hasActivities) { 11709 isProc = true; 11710 label = _label; 11711 shortLabel = _shortLabel; 11712 pss = _pss; 11713 id = _id; 11714 hasActivities = _hasActivities; 11715 } 11716 11717 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11718 isProc = false; 11719 label = _label; 11720 shortLabel = _shortLabel; 11721 pss = _pss; 11722 id = _id; 11723 hasActivities = false; 11724 } 11725 } 11726 11727 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11728 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11729 if (sort && !isCompact) { 11730 Collections.sort(items, new Comparator<MemItem>() { 11731 @Override 11732 public int compare(MemItem lhs, MemItem rhs) { 11733 if (lhs.pss < rhs.pss) { 11734 return 1; 11735 } else if (lhs.pss > rhs.pss) { 11736 return -1; 11737 } 11738 return 0; 11739 } 11740 }); 11741 } 11742 11743 for (int i=0; i<items.size(); i++) { 11744 MemItem mi = items.get(i); 11745 if (!isCompact) { 11746 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11747 } else if (mi.isProc) { 11748 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11749 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11750 pw.println(mi.hasActivities ? ",a" : ",e"); 11751 } else { 11752 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11753 pw.println(mi.pss); 11754 } 11755 if (mi.subitems != null) { 11756 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11757 true, isCompact); 11758 } 11759 } 11760 } 11761 11762 // These are in KB. 11763 static final long[] DUMP_MEM_BUCKETS = new long[] { 11764 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11765 120*1024, 160*1024, 200*1024, 11766 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11767 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11768 }; 11769 11770 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11771 boolean stackLike) { 11772 int start = label.lastIndexOf('.'); 11773 if (start >= 0) start++; 11774 else start = 0; 11775 int end = label.length(); 11776 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11777 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11778 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11779 out.append(bucket); 11780 out.append(stackLike ? "MB." : "MB "); 11781 out.append(label, start, end); 11782 return; 11783 } 11784 } 11785 out.append(memKB/1024); 11786 out.append(stackLike ? "MB." : "MB "); 11787 out.append(label, start, end); 11788 } 11789 11790 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11791 ProcessList.NATIVE_ADJ, 11792 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11793 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11794 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11795 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11796 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11797 }; 11798 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11799 "Native", 11800 "System", "Persistent", "Foreground", 11801 "Visible", "Perceptible", 11802 "Heavy Weight", "Backup", 11803 "A Services", "Home", 11804 "Previous", "B Services", "Cached" 11805 }; 11806 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 11807 "native", 11808 "sys", "pers", "fore", 11809 "vis", "percept", 11810 "heavy", "backup", 11811 "servicea", "home", 11812 "prev", "serviceb", "cached" 11813 }; 11814 11815 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 11816 long realtime, boolean isCheckinRequest, boolean isCompact) { 11817 if (isCheckinRequest || isCompact) { 11818 // short checkin version 11819 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 11820 } else { 11821 pw.println("Applications Memory Usage (kB):"); 11822 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11823 } 11824 } 11825 11826 final void dumpApplicationMemoryUsage(FileDescriptor fd, 11827 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 11828 boolean dumpDetails = false; 11829 boolean dumpFullDetails = false; 11830 boolean dumpDalvik = false; 11831 boolean oomOnly = false; 11832 boolean isCompact = false; 11833 boolean localOnly = false; 11834 11835 int opti = 0; 11836 while (opti < args.length) { 11837 String opt = args[opti]; 11838 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11839 break; 11840 } 11841 opti++; 11842 if ("-a".equals(opt)) { 11843 dumpDetails = true; 11844 dumpFullDetails = true; 11845 dumpDalvik = true; 11846 } else if ("-d".equals(opt)) { 11847 dumpDalvik = true; 11848 } else if ("-c".equals(opt)) { 11849 isCompact = true; 11850 } else if ("--oom".equals(opt)) { 11851 oomOnly = true; 11852 } else if ("--local".equals(opt)) { 11853 localOnly = true; 11854 } else if ("-h".equals(opt)) { 11855 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 11856 pw.println(" -a: include all available information for each process."); 11857 pw.println(" -d: include dalvik details when dumping process details."); 11858 pw.println(" -c: dump in a compact machine-parseable representation."); 11859 pw.println(" --oom: only show processes organized by oom adj."); 11860 pw.println(" --local: only collect details locally, don't call process."); 11861 pw.println("If [process] is specified it can be the name or "); 11862 pw.println("pid of a specific process to dump."); 11863 return; 11864 } else { 11865 pw.println("Unknown argument: " + opt + "; use -h for help"); 11866 } 11867 } 11868 11869 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 11870 long uptime = SystemClock.uptimeMillis(); 11871 long realtime = SystemClock.elapsedRealtime(); 11872 final long[] tmpLong = new long[1]; 11873 11874 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 11875 if (procs == null) { 11876 // No Java processes. Maybe they want to print a native process. 11877 if (args != null && args.length > opti 11878 && args[opti].charAt(0) != '-') { 11879 ArrayList<ProcessCpuTracker.Stats> nativeProcs 11880 = new ArrayList<ProcessCpuTracker.Stats>(); 11881 updateCpuStatsNow(); 11882 int findPid = -1; 11883 try { 11884 findPid = Integer.parseInt(args[opti]); 11885 } catch (NumberFormatException e) { 11886 } 11887 synchronized (mProcessCpuThread) { 11888 final int N = mProcessCpuTracker.countStats(); 11889 for (int i=0; i<N; i++) { 11890 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 11891 if (st.pid == findPid || (st.baseName != null 11892 && st.baseName.equals(args[opti]))) { 11893 nativeProcs.add(st); 11894 } 11895 } 11896 } 11897 if (nativeProcs.size() > 0) { 11898 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 11899 isCompact); 11900 Debug.MemoryInfo mi = null; 11901 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 11902 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 11903 final int pid = r.pid; 11904 if (!isCheckinRequest && dumpDetails) { 11905 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 11906 } 11907 if (mi == null) { 11908 mi = new Debug.MemoryInfo(); 11909 } 11910 if (dumpDetails || (!brief && !oomOnly)) { 11911 Debug.getMemoryInfo(pid, mi); 11912 } else { 11913 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11914 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11915 } 11916 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11917 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 11918 if (isCheckinRequest) { 11919 pw.println(); 11920 } 11921 } 11922 return; 11923 } 11924 } 11925 pw.println("No process found for: " + args[opti]); 11926 return; 11927 } 11928 11929 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 11930 dumpDetails = true; 11931 } 11932 11933 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 11934 11935 String[] innerArgs = new String[args.length-opti]; 11936 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 11937 11938 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 11939 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 11940 long nativePss=0, dalvikPss=0, otherPss=0; 11941 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 11942 11943 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 11944 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 11945 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 11946 11947 long totalPss = 0; 11948 long cachedPss = 0; 11949 11950 Debug.MemoryInfo mi = null; 11951 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11952 final ProcessRecord r = procs.get(i); 11953 final IApplicationThread thread; 11954 final int pid; 11955 final int oomAdj; 11956 final boolean hasActivities; 11957 synchronized (this) { 11958 thread = r.thread; 11959 pid = r.pid; 11960 oomAdj = r.getSetAdjWithServices(); 11961 hasActivities = r.activities.size() > 0; 11962 } 11963 if (thread != null) { 11964 if (!isCheckinRequest && dumpDetails) { 11965 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 11966 } 11967 if (mi == null) { 11968 mi = new Debug.MemoryInfo(); 11969 } 11970 if (dumpDetails || (!brief && !oomOnly)) { 11971 Debug.getMemoryInfo(pid, mi); 11972 } else { 11973 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11974 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11975 } 11976 if (dumpDetails) { 11977 if (localOnly) { 11978 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11979 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 11980 if (isCheckinRequest) { 11981 pw.println(); 11982 } 11983 } else { 11984 try { 11985 pw.flush(); 11986 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 11987 dumpDalvik, innerArgs); 11988 } catch (RemoteException e) { 11989 if (!isCheckinRequest) { 11990 pw.println("Got RemoteException!"); 11991 pw.flush(); 11992 } 11993 } 11994 } 11995 } 11996 11997 final long myTotalPss = mi.getTotalPss(); 11998 final long myTotalUss = mi.getTotalUss(); 11999 12000 synchronized (this) { 12001 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12002 // Record this for posterity if the process has been stable. 12003 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12004 } 12005 } 12006 12007 if (!isCheckinRequest && mi != null) { 12008 totalPss += myTotalPss; 12009 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12010 (hasActivities ? " / activities)" : ")"), 12011 r.processName, myTotalPss, pid, hasActivities); 12012 procMems.add(pssItem); 12013 procMemsMap.put(pid, pssItem); 12014 12015 nativePss += mi.nativePss; 12016 dalvikPss += mi.dalvikPss; 12017 otherPss += mi.otherPss; 12018 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12019 long mem = mi.getOtherPss(j); 12020 miscPss[j] += mem; 12021 otherPss -= mem; 12022 } 12023 12024 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12025 cachedPss += myTotalPss; 12026 } 12027 12028 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12029 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12030 || oomIndex == (oomPss.length-1)) { 12031 oomPss[oomIndex] += myTotalPss; 12032 if (oomProcs[oomIndex] == null) { 12033 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12034 } 12035 oomProcs[oomIndex].add(pssItem); 12036 break; 12037 } 12038 } 12039 } 12040 } 12041 } 12042 12043 if (!isCheckinRequest && procs.size() > 1) { 12044 // If we are showing aggregations, also look for native processes to 12045 // include so that our aggregations are more accurate. 12046 updateCpuStatsNow(); 12047 synchronized (mProcessCpuThread) { 12048 final int N = mProcessCpuTracker.countStats(); 12049 for (int i=0; i<N; i++) { 12050 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12051 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12052 if (mi == null) { 12053 mi = new Debug.MemoryInfo(); 12054 } 12055 if (!brief && !oomOnly) { 12056 Debug.getMemoryInfo(st.pid, mi); 12057 } else { 12058 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12059 mi.nativePrivateDirty = (int)tmpLong[0]; 12060 } 12061 12062 final long myTotalPss = mi.getTotalPss(); 12063 totalPss += myTotalPss; 12064 12065 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12066 st.name, myTotalPss, st.pid, false); 12067 procMems.add(pssItem); 12068 12069 nativePss += mi.nativePss; 12070 dalvikPss += mi.dalvikPss; 12071 otherPss += mi.otherPss; 12072 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12073 long mem = mi.getOtherPss(j); 12074 miscPss[j] += mem; 12075 otherPss -= mem; 12076 } 12077 oomPss[0] += myTotalPss; 12078 if (oomProcs[0] == null) { 12079 oomProcs[0] = new ArrayList<MemItem>(); 12080 } 12081 oomProcs[0].add(pssItem); 12082 } 12083 } 12084 } 12085 12086 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12087 12088 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12089 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12090 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12091 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12092 String label = Debug.MemoryInfo.getOtherLabel(j); 12093 catMems.add(new MemItem(label, label, miscPss[j], j)); 12094 } 12095 12096 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12097 for (int j=0; j<oomPss.length; j++) { 12098 if (oomPss[j] != 0) { 12099 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12100 : DUMP_MEM_OOM_LABEL[j]; 12101 MemItem item = new MemItem(label, label, oomPss[j], 12102 DUMP_MEM_OOM_ADJ[j]); 12103 item.subitems = oomProcs[j]; 12104 oomMems.add(item); 12105 } 12106 } 12107 12108 if (!brief && !oomOnly && !isCompact) { 12109 pw.println(); 12110 pw.println("Total PSS by process:"); 12111 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12112 pw.println(); 12113 } 12114 if (!isCompact) { 12115 pw.println("Total PSS by OOM adjustment:"); 12116 } 12117 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12118 if (!brief && !oomOnly) { 12119 PrintWriter out = categoryPw != null ? categoryPw : pw; 12120 if (!isCompact) { 12121 out.println(); 12122 out.println("Total PSS by category:"); 12123 } 12124 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12125 } 12126 if (!isCompact) { 12127 pw.println(); 12128 } 12129 MemInfoReader memInfo = new MemInfoReader(); 12130 memInfo.readMemInfo(); 12131 if (!brief) { 12132 if (!isCompact) { 12133 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12134 pw.println(" kB"); 12135 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12136 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12137 pw.print(cachedPss); pw.print(" cached pss + "); 12138 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12139 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12140 } else { 12141 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12142 pw.print(cachedPss + memInfo.getCachedSizeKb() 12143 + memInfo.getFreeSizeKb()); pw.print(","); 12144 pw.println(totalPss - cachedPss); 12145 } 12146 } 12147 if (!isCompact) { 12148 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12149 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12150 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12151 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12152 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12153 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12154 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12155 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12156 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12157 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12158 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12159 } 12160 if (!brief) { 12161 if (memInfo.getZramTotalSizeKb() != 0) { 12162 if (!isCompact) { 12163 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12164 pw.print(" kB physical used for "); 12165 pw.print(memInfo.getSwapTotalSizeKb() 12166 - memInfo.getSwapFreeSizeKb()); 12167 pw.print(" kB in swap ("); 12168 pw.print(memInfo.getSwapTotalSizeKb()); 12169 pw.println(" kB total swap)"); 12170 } else { 12171 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12172 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12173 pw.println(memInfo.getSwapFreeSizeKb()); 12174 } 12175 } 12176 final int[] SINGLE_LONG_FORMAT = new int[] { 12177 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12178 }; 12179 long[] longOut = new long[1]; 12180 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12181 SINGLE_LONG_FORMAT, null, longOut, null); 12182 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12183 longOut[0] = 0; 12184 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12185 SINGLE_LONG_FORMAT, null, longOut, null); 12186 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12187 longOut[0] = 0; 12188 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12189 SINGLE_LONG_FORMAT, null, longOut, null); 12190 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12191 longOut[0] = 0; 12192 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12193 SINGLE_LONG_FORMAT, null, longOut, null); 12194 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12195 if (!isCompact) { 12196 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12197 pw.print(" KSM: "); pw.print(sharing); 12198 pw.print(" kB saved from shared "); 12199 pw.print(shared); pw.println(" kB"); 12200 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12201 pw.print(voltile); pw.println(" kB volatile"); 12202 } 12203 pw.print(" Tuning: "); 12204 pw.print(ActivityManager.staticGetMemoryClass()); 12205 pw.print(" (large "); 12206 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12207 pw.print("), oom "); 12208 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12209 pw.print(" kB"); 12210 pw.print(", restore limit "); 12211 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12212 pw.print(" kB"); 12213 if (ActivityManager.isLowRamDeviceStatic()) { 12214 pw.print(" (low-ram)"); 12215 } 12216 if (ActivityManager.isHighEndGfx()) { 12217 pw.print(" (high-end-gfx)"); 12218 } 12219 pw.println(); 12220 } else { 12221 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12222 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12223 pw.println(voltile); 12224 pw.print("tuning,"); 12225 pw.print(ActivityManager.staticGetMemoryClass()); 12226 pw.print(','); 12227 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12228 pw.print(','); 12229 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12230 if (ActivityManager.isLowRamDeviceStatic()) { 12231 pw.print(",low-ram"); 12232 } 12233 if (ActivityManager.isHighEndGfx()) { 12234 pw.print(",high-end-gfx"); 12235 } 12236 pw.println(); 12237 } 12238 } 12239 } 12240 } 12241 12242 /** 12243 * Searches array of arguments for the specified string 12244 * @param args array of argument strings 12245 * @param value value to search for 12246 * @return true if the value is contained in the array 12247 */ 12248 private static boolean scanArgs(String[] args, String value) { 12249 if (args != null) { 12250 for (String arg : args) { 12251 if (value.equals(arg)) { 12252 return true; 12253 } 12254 } 12255 } 12256 return false; 12257 } 12258 12259 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12260 ContentProviderRecord cpr, boolean always) { 12261 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12262 12263 if (!inLaunching || always) { 12264 synchronized (cpr) { 12265 cpr.launchingApp = null; 12266 cpr.notifyAll(); 12267 } 12268 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12269 String names[] = cpr.info.authority.split(";"); 12270 for (int j = 0; j < names.length; j++) { 12271 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12272 } 12273 } 12274 12275 for (int i=0; i<cpr.connections.size(); i++) { 12276 ContentProviderConnection conn = cpr.connections.get(i); 12277 if (conn.waiting) { 12278 // If this connection is waiting for the provider, then we don't 12279 // need to mess with its process unless we are always removing 12280 // or for some reason the provider is not currently launching. 12281 if (inLaunching && !always) { 12282 continue; 12283 } 12284 } 12285 ProcessRecord capp = conn.client; 12286 conn.dead = true; 12287 if (conn.stableCount > 0) { 12288 if (!capp.persistent && capp.thread != null 12289 && capp.pid != 0 12290 && capp.pid != MY_PID) { 12291 killUnneededProcessLocked(capp, "depends on provider " 12292 + cpr.name.flattenToShortString() 12293 + " in dying proc " + (proc != null ? proc.processName : "??")); 12294 } 12295 } else if (capp.thread != null && conn.provider.provider != null) { 12296 try { 12297 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12298 } catch (RemoteException e) { 12299 } 12300 // In the protocol here, we don't expect the client to correctly 12301 // clean up this connection, we'll just remove it. 12302 cpr.connections.remove(i); 12303 conn.client.conProviders.remove(conn); 12304 } 12305 } 12306 12307 if (inLaunching && always) { 12308 mLaunchingProviders.remove(cpr); 12309 } 12310 return inLaunching; 12311 } 12312 12313 /** 12314 * Main code for cleaning up a process when it has gone away. This is 12315 * called both as a result of the process dying, or directly when stopping 12316 * a process when running in single process mode. 12317 */ 12318 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12319 boolean restarting, boolean allowRestart, int index) { 12320 if (index >= 0) { 12321 removeLruProcessLocked(app); 12322 } 12323 12324 mProcessesToGc.remove(app); 12325 mPendingPssProcesses.remove(app); 12326 12327 // Dismiss any open dialogs. 12328 if (app.crashDialog != null && !app.forceCrashReport) { 12329 app.crashDialog.dismiss(); 12330 app.crashDialog = null; 12331 } 12332 if (app.anrDialog != null) { 12333 app.anrDialog.dismiss(); 12334 app.anrDialog = null; 12335 } 12336 if (app.waitDialog != null) { 12337 app.waitDialog.dismiss(); 12338 app.waitDialog = null; 12339 } 12340 12341 app.crashing = false; 12342 app.notResponding = false; 12343 12344 app.resetPackageList(mProcessStats); 12345 app.unlinkDeathRecipient(); 12346 app.makeInactive(mProcessStats); 12347 app.forcingToForeground = null; 12348 app.foregroundServices = false; 12349 app.foregroundActivities = false; 12350 app.hasShownUi = false; 12351 app.hasAboveClient = false; 12352 12353 mServices.killServicesLocked(app, allowRestart); 12354 12355 boolean restart = false; 12356 12357 // Remove published content providers. 12358 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12359 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12360 final boolean always = app.bad || !allowRestart; 12361 if (removeDyingProviderLocked(app, cpr, always) || always) { 12362 // We left the provider in the launching list, need to 12363 // restart it. 12364 restart = true; 12365 } 12366 12367 cpr.provider = null; 12368 cpr.proc = null; 12369 } 12370 app.pubProviders.clear(); 12371 12372 // Take care of any launching providers waiting for this process. 12373 if (checkAppInLaunchingProvidersLocked(app, false)) { 12374 restart = true; 12375 } 12376 12377 // Unregister from connected content providers. 12378 if (!app.conProviders.isEmpty()) { 12379 for (int i=0; i<app.conProviders.size(); i++) { 12380 ContentProviderConnection conn = app.conProviders.get(i); 12381 conn.provider.connections.remove(conn); 12382 } 12383 app.conProviders.clear(); 12384 } 12385 12386 // At this point there may be remaining entries in mLaunchingProviders 12387 // where we were the only one waiting, so they are no longer of use. 12388 // Look for these and clean up if found. 12389 // XXX Commented out for now. Trying to figure out a way to reproduce 12390 // the actual situation to identify what is actually going on. 12391 if (false) { 12392 for (int i=0; i<mLaunchingProviders.size(); i++) { 12393 ContentProviderRecord cpr = (ContentProviderRecord) 12394 mLaunchingProviders.get(i); 12395 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12396 synchronized (cpr) { 12397 cpr.launchingApp = null; 12398 cpr.notifyAll(); 12399 } 12400 } 12401 } 12402 } 12403 12404 skipCurrentReceiverLocked(app); 12405 12406 // Unregister any receivers. 12407 for (int i=app.receivers.size()-1; i>=0; i--) { 12408 removeReceiverLocked(app.receivers.valueAt(i)); 12409 } 12410 app.receivers.clear(); 12411 12412 // If the app is undergoing backup, tell the backup manager about it 12413 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12414 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12415 + mBackupTarget.appInfo + " died during backup"); 12416 try { 12417 IBackupManager bm = IBackupManager.Stub.asInterface( 12418 ServiceManager.getService(Context.BACKUP_SERVICE)); 12419 bm.agentDisconnected(app.info.packageName); 12420 } catch (RemoteException e) { 12421 // can't happen; backup manager is local 12422 } 12423 } 12424 12425 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12426 ProcessChangeItem item = mPendingProcessChanges.get(i); 12427 if (item.pid == app.pid) { 12428 mPendingProcessChanges.remove(i); 12429 mAvailProcessChanges.add(item); 12430 } 12431 } 12432 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12433 12434 // If the caller is restarting this app, then leave it in its 12435 // current lists and let the caller take care of it. 12436 if (restarting) { 12437 return; 12438 } 12439 12440 if (!app.persistent || app.isolated) { 12441 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12442 "Removing non-persistent process during cleanup: " + app); 12443 mProcessNames.remove(app.processName, app.uid); 12444 mIsolatedProcesses.remove(app.uid); 12445 if (mHeavyWeightProcess == app) { 12446 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12447 mHeavyWeightProcess.userId, 0)); 12448 mHeavyWeightProcess = null; 12449 } 12450 } else if (!app.removed) { 12451 // This app is persistent, so we need to keep its record around. 12452 // If it is not already on the pending app list, add it there 12453 // and start a new process for it. 12454 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12455 mPersistentStartingProcesses.add(app); 12456 restart = true; 12457 } 12458 } 12459 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12460 "Clean-up removing on hold: " + app); 12461 mProcessesOnHold.remove(app); 12462 12463 if (app == mHomeProcess) { 12464 mHomeProcess = null; 12465 } 12466 if (app == mPreviousProcess) { 12467 mPreviousProcess = null; 12468 } 12469 12470 if (restart && !app.isolated) { 12471 // We have components that still need to be running in the 12472 // process, so re-launch it. 12473 mProcessNames.put(app.processName, app.uid, app); 12474 startProcessLocked(app, "restart", app.processName); 12475 } else if (app.pid > 0 && app.pid != MY_PID) { 12476 // Goodbye! 12477 synchronized (mPidsSelfLocked) { 12478 mPidsSelfLocked.remove(app.pid); 12479 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12480 } 12481 app.setPid(0); 12482 } 12483 } 12484 12485 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12486 // Look through the content providers we are waiting to have launched, 12487 // and if any run in this process then either schedule a restart of 12488 // the process or kill the client waiting for it if this process has 12489 // gone bad. 12490 int NL = mLaunchingProviders.size(); 12491 boolean restart = false; 12492 for (int i=0; i<NL; i++) { 12493 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12494 if (cpr.launchingApp == app) { 12495 if (!alwaysBad && !app.bad) { 12496 restart = true; 12497 } else { 12498 removeDyingProviderLocked(app, cpr, true); 12499 // cpr should have been removed from mLaunchingProviders 12500 NL = mLaunchingProviders.size(); 12501 i--; 12502 } 12503 } 12504 } 12505 return restart; 12506 } 12507 12508 // ========================================================= 12509 // SERVICES 12510 // ========================================================= 12511 12512 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12513 int flags) { 12514 enforceNotIsolatedCaller("getServices"); 12515 synchronized (this) { 12516 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12517 } 12518 } 12519 12520 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12521 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12522 synchronized (this) { 12523 return mServices.getRunningServiceControlPanelLocked(name); 12524 } 12525 } 12526 12527 public ComponentName startService(IApplicationThread caller, Intent service, 12528 String resolvedType, int userId) { 12529 enforceNotIsolatedCaller("startService"); 12530 // Refuse possible leaked file descriptors 12531 if (service != null && service.hasFileDescriptors() == true) { 12532 throw new IllegalArgumentException("File descriptors passed in Intent"); 12533 } 12534 12535 if (DEBUG_SERVICE) 12536 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12537 synchronized(this) { 12538 final int callingPid = Binder.getCallingPid(); 12539 final int callingUid = Binder.getCallingUid(); 12540 final long origId = Binder.clearCallingIdentity(); 12541 ComponentName res = mServices.startServiceLocked(caller, service, 12542 resolvedType, callingPid, callingUid, userId); 12543 Binder.restoreCallingIdentity(origId); 12544 return res; 12545 } 12546 } 12547 12548 ComponentName startServiceInPackage(int uid, 12549 Intent service, String resolvedType, int userId) { 12550 synchronized(this) { 12551 if (DEBUG_SERVICE) 12552 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12553 final long origId = Binder.clearCallingIdentity(); 12554 ComponentName res = mServices.startServiceLocked(null, service, 12555 resolvedType, -1, uid, userId); 12556 Binder.restoreCallingIdentity(origId); 12557 return res; 12558 } 12559 } 12560 12561 public int stopService(IApplicationThread caller, Intent service, 12562 String resolvedType, int userId) { 12563 enforceNotIsolatedCaller("stopService"); 12564 // Refuse possible leaked file descriptors 12565 if (service != null && service.hasFileDescriptors() == true) { 12566 throw new IllegalArgumentException("File descriptors passed in Intent"); 12567 } 12568 12569 synchronized(this) { 12570 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12571 } 12572 } 12573 12574 public IBinder peekService(Intent service, String resolvedType) { 12575 enforceNotIsolatedCaller("peekService"); 12576 // Refuse possible leaked file descriptors 12577 if (service != null && service.hasFileDescriptors() == true) { 12578 throw new IllegalArgumentException("File descriptors passed in Intent"); 12579 } 12580 synchronized(this) { 12581 return mServices.peekServiceLocked(service, resolvedType); 12582 } 12583 } 12584 12585 public boolean stopServiceToken(ComponentName className, IBinder token, 12586 int startId) { 12587 synchronized(this) { 12588 return mServices.stopServiceTokenLocked(className, token, startId); 12589 } 12590 } 12591 12592 public void setServiceForeground(ComponentName className, IBinder token, 12593 int id, Notification notification, boolean removeNotification) { 12594 synchronized(this) { 12595 mServices.setServiceForegroundLocked(className, token, id, notification, 12596 removeNotification); 12597 } 12598 } 12599 12600 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12601 boolean requireFull, String name, String callerPackage) { 12602 final int callingUserId = UserHandle.getUserId(callingUid); 12603 if (callingUserId != userId) { 12604 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12605 if ((requireFull || checkComponentPermission( 12606 android.Manifest.permission.INTERACT_ACROSS_USERS, 12607 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12608 && checkComponentPermission( 12609 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12610 callingPid, callingUid, -1, true) 12611 != PackageManager.PERMISSION_GRANTED) { 12612 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12613 // In this case, they would like to just execute as their 12614 // owner user instead of failing. 12615 userId = callingUserId; 12616 } else { 12617 StringBuilder builder = new StringBuilder(128); 12618 builder.append("Permission Denial: "); 12619 builder.append(name); 12620 if (callerPackage != null) { 12621 builder.append(" from "); 12622 builder.append(callerPackage); 12623 } 12624 builder.append(" asks to run as user "); 12625 builder.append(userId); 12626 builder.append(" but is calling from user "); 12627 builder.append(UserHandle.getUserId(callingUid)); 12628 builder.append("; this requires "); 12629 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12630 if (!requireFull) { 12631 builder.append(" or "); 12632 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12633 } 12634 String msg = builder.toString(); 12635 Slog.w(TAG, msg); 12636 throw new SecurityException(msg); 12637 } 12638 } 12639 } 12640 if (userId == UserHandle.USER_CURRENT 12641 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12642 // Note that we may be accessing this outside of a lock... 12643 // shouldn't be a big deal, if this is being called outside 12644 // of a locked context there is intrinsically a race with 12645 // the value the caller will receive and someone else changing it. 12646 userId = mCurrentUserId; 12647 } 12648 if (!allowAll && userId < 0) { 12649 throw new IllegalArgumentException( 12650 "Call does not support special user #" + userId); 12651 } 12652 } 12653 return userId; 12654 } 12655 12656 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12657 String className, int flags) { 12658 boolean result = false; 12659 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12660 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12661 if (ActivityManager.checkUidPermission( 12662 android.Manifest.permission.INTERACT_ACROSS_USERS, 12663 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12664 ComponentName comp = new ComponentName(aInfo.packageName, className); 12665 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12666 + " requests FLAG_SINGLE_USER, but app does not hold " 12667 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12668 Slog.w(TAG, msg); 12669 throw new SecurityException(msg); 12670 } 12671 result = true; 12672 } 12673 } else if (componentProcessName == aInfo.packageName) { 12674 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12675 } else if ("system".equals(componentProcessName)) { 12676 result = true; 12677 } 12678 if (DEBUG_MU) { 12679 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12680 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12681 } 12682 return result; 12683 } 12684 12685 public int bindService(IApplicationThread caller, IBinder token, 12686 Intent service, String resolvedType, 12687 IServiceConnection connection, int flags, int userId) { 12688 enforceNotIsolatedCaller("bindService"); 12689 // Refuse possible leaked file descriptors 12690 if (service != null && service.hasFileDescriptors() == true) { 12691 throw new IllegalArgumentException("File descriptors passed in Intent"); 12692 } 12693 12694 synchronized(this) { 12695 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12696 connection, flags, userId); 12697 } 12698 } 12699 12700 public boolean unbindService(IServiceConnection connection) { 12701 synchronized (this) { 12702 return mServices.unbindServiceLocked(connection); 12703 } 12704 } 12705 12706 public void publishService(IBinder token, Intent intent, IBinder service) { 12707 // Refuse possible leaked file descriptors 12708 if (intent != null && intent.hasFileDescriptors() == true) { 12709 throw new IllegalArgumentException("File descriptors passed in Intent"); 12710 } 12711 12712 synchronized(this) { 12713 if (!(token instanceof ServiceRecord)) { 12714 throw new IllegalArgumentException("Invalid service token"); 12715 } 12716 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12717 } 12718 } 12719 12720 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12721 // Refuse possible leaked file descriptors 12722 if (intent != null && intent.hasFileDescriptors() == true) { 12723 throw new IllegalArgumentException("File descriptors passed in Intent"); 12724 } 12725 12726 synchronized(this) { 12727 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12728 } 12729 } 12730 12731 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12732 synchronized(this) { 12733 if (!(token instanceof ServiceRecord)) { 12734 throw new IllegalArgumentException("Invalid service token"); 12735 } 12736 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12737 } 12738 } 12739 12740 // ========================================================= 12741 // BACKUP AND RESTORE 12742 // ========================================================= 12743 12744 // Cause the target app to be launched if necessary and its backup agent 12745 // instantiated. The backup agent will invoke backupAgentCreated() on the 12746 // activity manager to announce its creation. 12747 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12748 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12749 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12750 12751 synchronized(this) { 12752 // !!! TODO: currently no check here that we're already bound 12753 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12754 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12755 synchronized (stats) { 12756 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12757 } 12758 12759 // Backup agent is now in use, its package can't be stopped. 12760 try { 12761 AppGlobals.getPackageManager().setPackageStoppedState( 12762 app.packageName, false, UserHandle.getUserId(app.uid)); 12763 } catch (RemoteException e) { 12764 } catch (IllegalArgumentException e) { 12765 Slog.w(TAG, "Failed trying to unstop package " 12766 + app.packageName + ": " + e); 12767 } 12768 12769 BackupRecord r = new BackupRecord(ss, app, backupMode); 12770 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12771 ? new ComponentName(app.packageName, app.backupAgentName) 12772 : new ComponentName("android", "FullBackupAgent"); 12773 // startProcessLocked() returns existing proc's record if it's already running 12774 ProcessRecord proc = startProcessLocked(app.processName, app, 12775 false, 0, "backup", hostingName, false, false, false); 12776 if (proc == null) { 12777 Slog.e(TAG, "Unable to start backup agent process " + r); 12778 return false; 12779 } 12780 12781 r.app = proc; 12782 mBackupTarget = r; 12783 mBackupAppName = app.packageName; 12784 12785 // Try not to kill the process during backup 12786 updateOomAdjLocked(proc); 12787 12788 // If the process is already attached, schedule the creation of the backup agent now. 12789 // If it is not yet live, this will be done when it attaches to the framework. 12790 if (proc.thread != null) { 12791 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12792 try { 12793 proc.thread.scheduleCreateBackupAgent(app, 12794 compatibilityInfoForPackageLocked(app), backupMode); 12795 } catch (RemoteException e) { 12796 // Will time out on the backup manager side 12797 } 12798 } else { 12799 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12800 } 12801 // Invariants: at this point, the target app process exists and the application 12802 // is either already running or in the process of coming up. mBackupTarget and 12803 // mBackupAppName describe the app, so that when it binds back to the AM we 12804 // know that it's scheduled for a backup-agent operation. 12805 } 12806 12807 return true; 12808 } 12809 12810 @Override 12811 public void clearPendingBackup() { 12812 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 12813 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 12814 12815 synchronized (this) { 12816 mBackupTarget = null; 12817 mBackupAppName = null; 12818 } 12819 } 12820 12821 // A backup agent has just come up 12822 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12823 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12824 + " = " + agent); 12825 12826 synchronized(this) { 12827 if (!agentPackageName.equals(mBackupAppName)) { 12828 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12829 return; 12830 } 12831 } 12832 12833 long oldIdent = Binder.clearCallingIdentity(); 12834 try { 12835 IBackupManager bm = IBackupManager.Stub.asInterface( 12836 ServiceManager.getService(Context.BACKUP_SERVICE)); 12837 bm.agentConnected(agentPackageName, agent); 12838 } catch (RemoteException e) { 12839 // can't happen; the backup manager service is local 12840 } catch (Exception e) { 12841 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12842 e.printStackTrace(); 12843 } finally { 12844 Binder.restoreCallingIdentity(oldIdent); 12845 } 12846 } 12847 12848 // done with this agent 12849 public void unbindBackupAgent(ApplicationInfo appInfo) { 12850 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12851 if (appInfo == null) { 12852 Slog.w(TAG, "unbind backup agent for null app"); 12853 return; 12854 } 12855 12856 synchronized(this) { 12857 try { 12858 if (mBackupAppName == null) { 12859 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12860 return; 12861 } 12862 12863 if (!mBackupAppName.equals(appInfo.packageName)) { 12864 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12865 return; 12866 } 12867 12868 // Not backing this app up any more; reset its OOM adjustment 12869 final ProcessRecord proc = mBackupTarget.app; 12870 updateOomAdjLocked(proc); 12871 12872 // If the app crashed during backup, 'thread' will be null here 12873 if (proc.thread != null) { 12874 try { 12875 proc.thread.scheduleDestroyBackupAgent(appInfo, 12876 compatibilityInfoForPackageLocked(appInfo)); 12877 } catch (Exception e) { 12878 Slog.e(TAG, "Exception when unbinding backup agent:"); 12879 e.printStackTrace(); 12880 } 12881 } 12882 } finally { 12883 mBackupTarget = null; 12884 mBackupAppName = null; 12885 } 12886 } 12887 } 12888 // ========================================================= 12889 // BROADCASTS 12890 // ========================================================= 12891 12892 private final List getStickiesLocked(String action, IntentFilter filter, 12893 List cur, int userId) { 12894 final ContentResolver resolver = mContext.getContentResolver(); 12895 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12896 if (stickies == null) { 12897 return cur; 12898 } 12899 final ArrayList<Intent> list = stickies.get(action); 12900 if (list == null) { 12901 return cur; 12902 } 12903 int N = list.size(); 12904 for (int i=0; i<N; i++) { 12905 Intent intent = list.get(i); 12906 if (filter.match(resolver, intent, true, TAG) >= 0) { 12907 if (cur == null) { 12908 cur = new ArrayList<Intent>(); 12909 } 12910 cur.add(intent); 12911 } 12912 } 12913 return cur; 12914 } 12915 12916 boolean isPendingBroadcastProcessLocked(int pid) { 12917 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12918 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12919 } 12920 12921 void skipPendingBroadcastLocked(int pid) { 12922 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 12923 for (BroadcastQueue queue : mBroadcastQueues) { 12924 queue.skipPendingBroadcastLocked(pid); 12925 } 12926 } 12927 12928 // The app just attached; send any pending broadcasts that it should receive 12929 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 12930 boolean didSomething = false; 12931 for (BroadcastQueue queue : mBroadcastQueues) { 12932 didSomething |= queue.sendPendingBroadcastsLocked(app); 12933 } 12934 return didSomething; 12935 } 12936 12937 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 12938 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 12939 enforceNotIsolatedCaller("registerReceiver"); 12940 int callingUid; 12941 int callingPid; 12942 synchronized(this) { 12943 ProcessRecord callerApp = null; 12944 if (caller != null) { 12945 callerApp = getRecordForAppLocked(caller); 12946 if (callerApp == null) { 12947 throw new SecurityException( 12948 "Unable to find app for caller " + caller 12949 + " (pid=" + Binder.getCallingPid() 12950 + ") when registering receiver " + receiver); 12951 } 12952 if (callerApp.info.uid != Process.SYSTEM_UID && 12953 !callerApp.pkgList.containsKey(callerPackage) && 12954 !"android".equals(callerPackage)) { 12955 throw new SecurityException("Given caller package " + callerPackage 12956 + " is not running in process " + callerApp); 12957 } 12958 callingUid = callerApp.info.uid; 12959 callingPid = callerApp.pid; 12960 } else { 12961 callerPackage = null; 12962 callingUid = Binder.getCallingUid(); 12963 callingPid = Binder.getCallingPid(); 12964 } 12965 12966 userId = this.handleIncomingUser(callingPid, callingUid, userId, 12967 true, true, "registerReceiver", callerPackage); 12968 12969 List allSticky = null; 12970 12971 // Look for any matching sticky broadcasts... 12972 Iterator actions = filter.actionsIterator(); 12973 if (actions != null) { 12974 while (actions.hasNext()) { 12975 String action = (String)actions.next(); 12976 allSticky = getStickiesLocked(action, filter, allSticky, 12977 UserHandle.USER_ALL); 12978 allSticky = getStickiesLocked(action, filter, allSticky, 12979 UserHandle.getUserId(callingUid)); 12980 } 12981 } else { 12982 allSticky = getStickiesLocked(null, filter, allSticky, 12983 UserHandle.USER_ALL); 12984 allSticky = getStickiesLocked(null, filter, allSticky, 12985 UserHandle.getUserId(callingUid)); 12986 } 12987 12988 // The first sticky in the list is returned directly back to 12989 // the client. 12990 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 12991 12992 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 12993 + ": " + sticky); 12994 12995 if (receiver == null) { 12996 return sticky; 12997 } 12998 12999 ReceiverList rl 13000 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13001 if (rl == null) { 13002 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13003 userId, receiver); 13004 if (rl.app != null) { 13005 rl.app.receivers.add(rl); 13006 } else { 13007 try { 13008 receiver.asBinder().linkToDeath(rl, 0); 13009 } catch (RemoteException e) { 13010 return sticky; 13011 } 13012 rl.linkedToDeath = true; 13013 } 13014 mRegisteredReceivers.put(receiver.asBinder(), rl); 13015 } else if (rl.uid != callingUid) { 13016 throw new IllegalArgumentException( 13017 "Receiver requested to register for uid " + callingUid 13018 + " was previously registered for uid " + rl.uid); 13019 } else if (rl.pid != callingPid) { 13020 throw new IllegalArgumentException( 13021 "Receiver requested to register for pid " + callingPid 13022 + " was previously registered for pid " + rl.pid); 13023 } else if (rl.userId != userId) { 13024 throw new IllegalArgumentException( 13025 "Receiver requested to register for user " + userId 13026 + " was previously registered for user " + rl.userId); 13027 } 13028 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13029 permission, callingUid, userId); 13030 rl.add(bf); 13031 if (!bf.debugCheck()) { 13032 Slog.w(TAG, "==> For Dynamic broadast"); 13033 } 13034 mReceiverResolver.addFilter(bf); 13035 13036 // Enqueue broadcasts for all existing stickies that match 13037 // this filter. 13038 if (allSticky != null) { 13039 ArrayList receivers = new ArrayList(); 13040 receivers.add(bf); 13041 13042 int N = allSticky.size(); 13043 for (int i=0; i<N; i++) { 13044 Intent intent = (Intent)allSticky.get(i); 13045 BroadcastQueue queue = broadcastQueueForIntent(intent); 13046 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13047 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13048 null, null, false, true, true, -1); 13049 queue.enqueueParallelBroadcastLocked(r); 13050 queue.scheduleBroadcastsLocked(); 13051 } 13052 } 13053 13054 return sticky; 13055 } 13056 } 13057 13058 public void unregisterReceiver(IIntentReceiver receiver) { 13059 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13060 13061 final long origId = Binder.clearCallingIdentity(); 13062 try { 13063 boolean doTrim = false; 13064 13065 synchronized(this) { 13066 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13067 if (rl != null) { 13068 if (rl.curBroadcast != null) { 13069 BroadcastRecord r = rl.curBroadcast; 13070 final boolean doNext = finishReceiverLocked( 13071 receiver.asBinder(), r.resultCode, r.resultData, 13072 r.resultExtras, r.resultAbort); 13073 if (doNext) { 13074 doTrim = true; 13075 r.queue.processNextBroadcast(false); 13076 } 13077 } 13078 13079 if (rl.app != null) { 13080 rl.app.receivers.remove(rl); 13081 } 13082 removeReceiverLocked(rl); 13083 if (rl.linkedToDeath) { 13084 rl.linkedToDeath = false; 13085 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13086 } 13087 } 13088 } 13089 13090 // If we actually concluded any broadcasts, we might now be able 13091 // to trim the recipients' apps from our working set 13092 if (doTrim) { 13093 trimApplications(); 13094 return; 13095 } 13096 13097 } finally { 13098 Binder.restoreCallingIdentity(origId); 13099 } 13100 } 13101 13102 void removeReceiverLocked(ReceiverList rl) { 13103 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13104 int N = rl.size(); 13105 for (int i=0; i<N; i++) { 13106 mReceiverResolver.removeFilter(rl.get(i)); 13107 } 13108 } 13109 13110 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13111 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13112 ProcessRecord r = mLruProcesses.get(i); 13113 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13114 try { 13115 r.thread.dispatchPackageBroadcast(cmd, packages); 13116 } catch (RemoteException ex) { 13117 } 13118 } 13119 } 13120 } 13121 13122 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13123 int[] users) { 13124 List<ResolveInfo> receivers = null; 13125 try { 13126 HashSet<ComponentName> singleUserReceivers = null; 13127 boolean scannedFirstReceivers = false; 13128 for (int user : users) { 13129 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13130 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13131 if (user != 0 && newReceivers != null) { 13132 // If this is not the primary user, we need to check for 13133 // any receivers that should be filtered out. 13134 for (int i=0; i<newReceivers.size(); i++) { 13135 ResolveInfo ri = newReceivers.get(i); 13136 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13137 newReceivers.remove(i); 13138 i--; 13139 } 13140 } 13141 } 13142 if (newReceivers != null && newReceivers.size() == 0) { 13143 newReceivers = null; 13144 } 13145 if (receivers == null) { 13146 receivers = newReceivers; 13147 } else if (newReceivers != null) { 13148 // We need to concatenate the additional receivers 13149 // found with what we have do far. This would be easy, 13150 // but we also need to de-dup any receivers that are 13151 // singleUser. 13152 if (!scannedFirstReceivers) { 13153 // Collect any single user receivers we had already retrieved. 13154 scannedFirstReceivers = true; 13155 for (int i=0; i<receivers.size(); i++) { 13156 ResolveInfo ri = receivers.get(i); 13157 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13158 ComponentName cn = new ComponentName( 13159 ri.activityInfo.packageName, ri.activityInfo.name); 13160 if (singleUserReceivers == null) { 13161 singleUserReceivers = new HashSet<ComponentName>(); 13162 } 13163 singleUserReceivers.add(cn); 13164 } 13165 } 13166 } 13167 // Add the new results to the existing results, tracking 13168 // and de-dupping single user receivers. 13169 for (int i=0; i<newReceivers.size(); i++) { 13170 ResolveInfo ri = newReceivers.get(i); 13171 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13172 ComponentName cn = new ComponentName( 13173 ri.activityInfo.packageName, ri.activityInfo.name); 13174 if (singleUserReceivers == null) { 13175 singleUserReceivers = new HashSet<ComponentName>(); 13176 } 13177 if (!singleUserReceivers.contains(cn)) { 13178 singleUserReceivers.add(cn); 13179 receivers.add(ri); 13180 } 13181 } else { 13182 receivers.add(ri); 13183 } 13184 } 13185 } 13186 } 13187 } catch (RemoteException ex) { 13188 // pm is in same process, this will never happen. 13189 } 13190 return receivers; 13191 } 13192 13193 private final int broadcastIntentLocked(ProcessRecord callerApp, 13194 String callerPackage, Intent intent, String resolvedType, 13195 IIntentReceiver resultTo, int resultCode, String resultData, 13196 Bundle map, String requiredPermission, int appOp, 13197 boolean ordered, boolean sticky, int callingPid, int callingUid, 13198 int userId) { 13199 intent = new Intent(intent); 13200 13201 // By default broadcasts do not go to stopped apps. 13202 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13203 13204 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13205 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13206 + " ordered=" + ordered + " userid=" + userId); 13207 if ((resultTo != null) && !ordered) { 13208 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13209 } 13210 13211 userId = handleIncomingUser(callingPid, callingUid, userId, 13212 true, false, "broadcast", callerPackage); 13213 13214 // Make sure that the user who is receiving this broadcast is started. 13215 // If not, we will just skip it. 13216 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13217 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13218 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13219 Slog.w(TAG, "Skipping broadcast of " + intent 13220 + ": user " + userId + " is stopped"); 13221 return ActivityManager.BROADCAST_SUCCESS; 13222 } 13223 } 13224 13225 /* 13226 * Prevent non-system code (defined here to be non-persistent 13227 * processes) from sending protected broadcasts. 13228 */ 13229 int callingAppId = UserHandle.getAppId(callingUid); 13230 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13231 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13232 callingUid == 0) { 13233 // Always okay. 13234 } else if (callerApp == null || !callerApp.persistent) { 13235 try { 13236 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13237 intent.getAction())) { 13238 String msg = "Permission Denial: not allowed to send broadcast " 13239 + intent.getAction() + " from pid=" 13240 + callingPid + ", uid=" + callingUid; 13241 Slog.w(TAG, msg); 13242 throw new SecurityException(msg); 13243 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13244 // Special case for compatibility: we don't want apps to send this, 13245 // but historically it has not been protected and apps may be using it 13246 // to poke their own app widget. So, instead of making it protected, 13247 // just limit it to the caller. 13248 if (callerApp == null) { 13249 String msg = "Permission Denial: not allowed to send broadcast " 13250 + intent.getAction() + " from unknown caller."; 13251 Slog.w(TAG, msg); 13252 throw new SecurityException(msg); 13253 } else if (intent.getComponent() != null) { 13254 // They are good enough to send to an explicit component... verify 13255 // it is being sent to the calling app. 13256 if (!intent.getComponent().getPackageName().equals( 13257 callerApp.info.packageName)) { 13258 String msg = "Permission Denial: not allowed to send broadcast " 13259 + intent.getAction() + " to " 13260 + intent.getComponent().getPackageName() + " from " 13261 + callerApp.info.packageName; 13262 Slog.w(TAG, msg); 13263 throw new SecurityException(msg); 13264 } 13265 } else { 13266 // Limit broadcast to their own package. 13267 intent.setPackage(callerApp.info.packageName); 13268 } 13269 } 13270 } catch (RemoteException e) { 13271 Slog.w(TAG, "Remote exception", e); 13272 return ActivityManager.BROADCAST_SUCCESS; 13273 } 13274 } 13275 13276 // Handle special intents: if this broadcast is from the package 13277 // manager about a package being removed, we need to remove all of 13278 // its activities from the history stack. 13279 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13280 intent.getAction()); 13281 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13282 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13283 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13284 || uidRemoved) { 13285 if (checkComponentPermission( 13286 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13287 callingPid, callingUid, -1, true) 13288 == PackageManager.PERMISSION_GRANTED) { 13289 if (uidRemoved) { 13290 final Bundle intentExtras = intent.getExtras(); 13291 final int uid = intentExtras != null 13292 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13293 if (uid >= 0) { 13294 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13295 synchronized (bs) { 13296 bs.removeUidStatsLocked(uid); 13297 } 13298 mAppOpsService.uidRemoved(uid); 13299 } 13300 } else { 13301 // If resources are unavailable just force stop all 13302 // those packages and flush the attribute cache as well. 13303 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13304 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13305 if (list != null && (list.length > 0)) { 13306 for (String pkg : list) { 13307 forceStopPackageLocked(pkg, -1, false, true, true, false, userId, 13308 "storage unmount"); 13309 } 13310 sendPackageBroadcastLocked( 13311 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13312 } 13313 } else { 13314 Uri data = intent.getData(); 13315 String ssp; 13316 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13317 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13318 intent.getAction()); 13319 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13320 forceStopPackageLocked(ssp, UserHandle.getAppId( 13321 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13322 false, userId, removed ? "pkg removed" : "pkg changed"); 13323 } 13324 if (removed) { 13325 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13326 new String[] {ssp}, userId); 13327 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13328 mAppOpsService.packageRemoved( 13329 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13330 13331 // Remove all permissions granted from/to this package 13332 removeUriPermissionsForPackageLocked(ssp, userId, true); 13333 } 13334 } 13335 } 13336 } 13337 } 13338 } else { 13339 String msg = "Permission Denial: " + intent.getAction() 13340 + " broadcast from " + callerPackage + " (pid=" + callingPid 13341 + ", uid=" + callingUid + ")" 13342 + " requires " 13343 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13344 Slog.w(TAG, msg); 13345 throw new SecurityException(msg); 13346 } 13347 13348 // Special case for adding a package: by default turn on compatibility 13349 // mode. 13350 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13351 Uri data = intent.getData(); 13352 String ssp; 13353 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13354 mCompatModePackages.handlePackageAddedLocked(ssp, 13355 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13356 } 13357 } 13358 13359 /* 13360 * If this is the time zone changed action, queue up a message that will reset the timezone 13361 * of all currently running processes. This message will get queued up before the broadcast 13362 * happens. 13363 */ 13364 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13365 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13366 } 13367 13368 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13369 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13370 } 13371 13372 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13373 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13374 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13375 } 13376 13377 // Add to the sticky list if requested. 13378 if (sticky) { 13379 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13380 callingPid, callingUid) 13381 != PackageManager.PERMISSION_GRANTED) { 13382 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13383 + callingPid + ", uid=" + callingUid 13384 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13385 Slog.w(TAG, msg); 13386 throw new SecurityException(msg); 13387 } 13388 if (requiredPermission != null) { 13389 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13390 + " and enforce permission " + requiredPermission); 13391 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13392 } 13393 if (intent.getComponent() != null) { 13394 throw new SecurityException( 13395 "Sticky broadcasts can't target a specific component"); 13396 } 13397 // We use userId directly here, since the "all" target is maintained 13398 // as a separate set of sticky broadcasts. 13399 if (userId != UserHandle.USER_ALL) { 13400 // But first, if this is not a broadcast to all users, then 13401 // make sure it doesn't conflict with an existing broadcast to 13402 // all users. 13403 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13404 UserHandle.USER_ALL); 13405 if (stickies != null) { 13406 ArrayList<Intent> list = stickies.get(intent.getAction()); 13407 if (list != null) { 13408 int N = list.size(); 13409 int i; 13410 for (i=0; i<N; i++) { 13411 if (intent.filterEquals(list.get(i))) { 13412 throw new IllegalArgumentException( 13413 "Sticky broadcast " + intent + " for user " 13414 + userId + " conflicts with existing global broadcast"); 13415 } 13416 } 13417 } 13418 } 13419 } 13420 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13421 if (stickies == null) { 13422 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13423 mStickyBroadcasts.put(userId, stickies); 13424 } 13425 ArrayList<Intent> list = stickies.get(intent.getAction()); 13426 if (list == null) { 13427 list = new ArrayList<Intent>(); 13428 stickies.put(intent.getAction(), list); 13429 } 13430 int N = list.size(); 13431 int i; 13432 for (i=0; i<N; i++) { 13433 if (intent.filterEquals(list.get(i))) { 13434 // This sticky already exists, replace it. 13435 list.set(i, new Intent(intent)); 13436 break; 13437 } 13438 } 13439 if (i >= N) { 13440 list.add(new Intent(intent)); 13441 } 13442 } 13443 13444 int[] users; 13445 if (userId == UserHandle.USER_ALL) { 13446 // Caller wants broadcast to go to all started users. 13447 users = mStartedUserArray; 13448 } else { 13449 // Caller wants broadcast to go to one specific user. 13450 users = new int[] {userId}; 13451 } 13452 13453 // Figure out who all will receive this broadcast. 13454 List receivers = null; 13455 List<BroadcastFilter> registeredReceivers = null; 13456 // Need to resolve the intent to interested receivers... 13457 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13458 == 0) { 13459 receivers = collectReceiverComponents(intent, resolvedType, users); 13460 } 13461 if (intent.getComponent() == null) { 13462 registeredReceivers = mReceiverResolver.queryIntent(intent, 13463 resolvedType, false, userId); 13464 } 13465 13466 final boolean replacePending = 13467 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13468 13469 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13470 + " replacePending=" + replacePending); 13471 13472 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13473 if (!ordered && NR > 0) { 13474 // If we are not serializing this broadcast, then send the 13475 // registered receivers separately so they don't wait for the 13476 // components to be launched. 13477 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13478 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13479 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13480 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13481 ordered, sticky, false, userId); 13482 if (DEBUG_BROADCAST) Slog.v( 13483 TAG, "Enqueueing parallel broadcast " + r); 13484 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13485 if (!replaced) { 13486 queue.enqueueParallelBroadcastLocked(r); 13487 queue.scheduleBroadcastsLocked(); 13488 } 13489 registeredReceivers = null; 13490 NR = 0; 13491 } 13492 13493 // Merge into one list. 13494 int ir = 0; 13495 if (receivers != null) { 13496 // A special case for PACKAGE_ADDED: do not allow the package 13497 // being added to see this broadcast. This prevents them from 13498 // using this as a back door to get run as soon as they are 13499 // installed. Maybe in the future we want to have a special install 13500 // broadcast or such for apps, but we'd like to deliberately make 13501 // this decision. 13502 String skipPackages[] = null; 13503 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13504 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13505 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13506 Uri data = intent.getData(); 13507 if (data != null) { 13508 String pkgName = data.getSchemeSpecificPart(); 13509 if (pkgName != null) { 13510 skipPackages = new String[] { pkgName }; 13511 } 13512 } 13513 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13514 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13515 } 13516 if (skipPackages != null && (skipPackages.length > 0)) { 13517 for (String skipPackage : skipPackages) { 13518 if (skipPackage != null) { 13519 int NT = receivers.size(); 13520 for (int it=0; it<NT; it++) { 13521 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13522 if (curt.activityInfo.packageName.equals(skipPackage)) { 13523 receivers.remove(it); 13524 it--; 13525 NT--; 13526 } 13527 } 13528 } 13529 } 13530 } 13531 13532 int NT = receivers != null ? receivers.size() : 0; 13533 int it = 0; 13534 ResolveInfo curt = null; 13535 BroadcastFilter curr = null; 13536 while (it < NT && ir < NR) { 13537 if (curt == null) { 13538 curt = (ResolveInfo)receivers.get(it); 13539 } 13540 if (curr == null) { 13541 curr = registeredReceivers.get(ir); 13542 } 13543 if (curr.getPriority() >= curt.priority) { 13544 // Insert this broadcast record into the final list. 13545 receivers.add(it, curr); 13546 ir++; 13547 curr = null; 13548 it++; 13549 NT++; 13550 } else { 13551 // Skip to the next ResolveInfo in the final list. 13552 it++; 13553 curt = null; 13554 } 13555 } 13556 } 13557 while (ir < NR) { 13558 if (receivers == null) { 13559 receivers = new ArrayList(); 13560 } 13561 receivers.add(registeredReceivers.get(ir)); 13562 ir++; 13563 } 13564 13565 if ((receivers != null && receivers.size() > 0) 13566 || resultTo != null) { 13567 BroadcastQueue queue = broadcastQueueForIntent(intent); 13568 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13569 callerPackage, callingPid, callingUid, resolvedType, 13570 requiredPermission, appOp, receivers, resultTo, resultCode, 13571 resultData, map, ordered, sticky, false, userId); 13572 if (DEBUG_BROADCAST) Slog.v( 13573 TAG, "Enqueueing ordered broadcast " + r 13574 + ": prev had " + queue.mOrderedBroadcasts.size()); 13575 if (DEBUG_BROADCAST) { 13576 int seq = r.intent.getIntExtra("seq", -1); 13577 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13578 } 13579 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13580 if (!replaced) { 13581 queue.enqueueOrderedBroadcastLocked(r); 13582 queue.scheduleBroadcastsLocked(); 13583 } 13584 } 13585 13586 return ActivityManager.BROADCAST_SUCCESS; 13587 } 13588 13589 final Intent verifyBroadcastLocked(Intent intent) { 13590 // Refuse possible leaked file descriptors 13591 if (intent != null && intent.hasFileDescriptors() == true) { 13592 throw new IllegalArgumentException("File descriptors passed in Intent"); 13593 } 13594 13595 int flags = intent.getFlags(); 13596 13597 if (!mProcessesReady) { 13598 // if the caller really truly claims to know what they're doing, go 13599 // ahead and allow the broadcast without launching any receivers 13600 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13601 intent = new Intent(intent); 13602 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13603 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13604 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13605 + " before boot completion"); 13606 throw new IllegalStateException("Cannot broadcast before boot completed"); 13607 } 13608 } 13609 13610 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13611 throw new IllegalArgumentException( 13612 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13613 } 13614 13615 return intent; 13616 } 13617 13618 public final int broadcastIntent(IApplicationThread caller, 13619 Intent intent, String resolvedType, IIntentReceiver resultTo, 13620 int resultCode, String resultData, Bundle map, 13621 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13622 enforceNotIsolatedCaller("broadcastIntent"); 13623 synchronized(this) { 13624 intent = verifyBroadcastLocked(intent); 13625 13626 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13627 final int callingPid = Binder.getCallingPid(); 13628 final int callingUid = Binder.getCallingUid(); 13629 final long origId = Binder.clearCallingIdentity(); 13630 int res = broadcastIntentLocked(callerApp, 13631 callerApp != null ? callerApp.info.packageName : null, 13632 intent, resolvedType, resultTo, 13633 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13634 callingPid, callingUid, userId); 13635 Binder.restoreCallingIdentity(origId); 13636 return res; 13637 } 13638 } 13639 13640 int broadcastIntentInPackage(String packageName, int uid, 13641 Intent intent, String resolvedType, IIntentReceiver resultTo, 13642 int resultCode, String resultData, Bundle map, 13643 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13644 synchronized(this) { 13645 intent = verifyBroadcastLocked(intent); 13646 13647 final long origId = Binder.clearCallingIdentity(); 13648 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13649 resultTo, resultCode, resultData, map, requiredPermission, 13650 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13651 Binder.restoreCallingIdentity(origId); 13652 return res; 13653 } 13654 } 13655 13656 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13657 // Refuse possible leaked file descriptors 13658 if (intent != null && intent.hasFileDescriptors() == true) { 13659 throw new IllegalArgumentException("File descriptors passed in Intent"); 13660 } 13661 13662 userId = handleIncomingUser(Binder.getCallingPid(), 13663 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13664 13665 synchronized(this) { 13666 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13667 != PackageManager.PERMISSION_GRANTED) { 13668 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13669 + Binder.getCallingPid() 13670 + ", uid=" + Binder.getCallingUid() 13671 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13672 Slog.w(TAG, msg); 13673 throw new SecurityException(msg); 13674 } 13675 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13676 if (stickies != null) { 13677 ArrayList<Intent> list = stickies.get(intent.getAction()); 13678 if (list != null) { 13679 int N = list.size(); 13680 int i; 13681 for (i=0; i<N; i++) { 13682 if (intent.filterEquals(list.get(i))) { 13683 list.remove(i); 13684 break; 13685 } 13686 } 13687 if (list.size() <= 0) { 13688 stickies.remove(intent.getAction()); 13689 } 13690 } 13691 if (stickies.size() <= 0) { 13692 mStickyBroadcasts.remove(userId); 13693 } 13694 } 13695 } 13696 } 13697 13698 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13699 String resultData, Bundle resultExtras, boolean resultAbort) { 13700 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13701 if (r == null) { 13702 Slog.w(TAG, "finishReceiver called but not found on queue"); 13703 return false; 13704 } 13705 13706 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13707 } 13708 13709 void backgroundServicesFinishedLocked(int userId) { 13710 for (BroadcastQueue queue : mBroadcastQueues) { 13711 queue.backgroundServicesFinishedLocked(userId); 13712 } 13713 } 13714 13715 public void finishReceiver(IBinder who, int resultCode, String resultData, 13716 Bundle resultExtras, boolean resultAbort) { 13717 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13718 13719 // Refuse possible leaked file descriptors 13720 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13721 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13722 } 13723 13724 final long origId = Binder.clearCallingIdentity(); 13725 try { 13726 boolean doNext = false; 13727 BroadcastRecord r; 13728 13729 synchronized(this) { 13730 r = broadcastRecordForReceiverLocked(who); 13731 if (r != null) { 13732 doNext = r.queue.finishReceiverLocked(r, resultCode, 13733 resultData, resultExtras, resultAbort, true); 13734 } 13735 } 13736 13737 if (doNext) { 13738 r.queue.processNextBroadcast(false); 13739 } 13740 trimApplications(); 13741 } finally { 13742 Binder.restoreCallingIdentity(origId); 13743 } 13744 } 13745 13746 // ========================================================= 13747 // INSTRUMENTATION 13748 // ========================================================= 13749 13750 public boolean startInstrumentation(ComponentName className, 13751 String profileFile, int flags, Bundle arguments, 13752 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13753 int userId) { 13754 enforceNotIsolatedCaller("startInstrumentation"); 13755 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13756 userId, false, true, "startInstrumentation", null); 13757 // Refuse possible leaked file descriptors 13758 if (arguments != null && arguments.hasFileDescriptors()) { 13759 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13760 } 13761 13762 synchronized(this) { 13763 InstrumentationInfo ii = null; 13764 ApplicationInfo ai = null; 13765 try { 13766 ii = mContext.getPackageManager().getInstrumentationInfo( 13767 className, STOCK_PM_FLAGS); 13768 ai = AppGlobals.getPackageManager().getApplicationInfo( 13769 ii.targetPackage, STOCK_PM_FLAGS, userId); 13770 } catch (PackageManager.NameNotFoundException e) { 13771 } catch (RemoteException e) { 13772 } 13773 if (ii == null) { 13774 reportStartInstrumentationFailure(watcher, className, 13775 "Unable to find instrumentation info for: " + className); 13776 return false; 13777 } 13778 if (ai == null) { 13779 reportStartInstrumentationFailure(watcher, className, 13780 "Unable to find instrumentation target package: " + ii.targetPackage); 13781 return false; 13782 } 13783 13784 int match = mContext.getPackageManager().checkSignatures( 13785 ii.targetPackage, ii.packageName); 13786 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13787 String msg = "Permission Denial: starting instrumentation " 13788 + className + " from pid=" 13789 + Binder.getCallingPid() 13790 + ", uid=" + Binder.getCallingPid() 13791 + " not allowed because package " + ii.packageName 13792 + " does not have a signature matching the target " 13793 + ii.targetPackage; 13794 reportStartInstrumentationFailure(watcher, className, msg); 13795 throw new SecurityException(msg); 13796 } 13797 13798 final long origId = Binder.clearCallingIdentity(); 13799 // Instrumentation can kill and relaunch even persistent processes 13800 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId, 13801 "start instr"); 13802 ProcessRecord app = addAppLocked(ai, false); 13803 app.instrumentationClass = className; 13804 app.instrumentationInfo = ai; 13805 app.instrumentationProfileFile = profileFile; 13806 app.instrumentationArguments = arguments; 13807 app.instrumentationWatcher = watcher; 13808 app.instrumentationUiAutomationConnection = uiAutomationConnection; 13809 app.instrumentationResultClass = className; 13810 Binder.restoreCallingIdentity(origId); 13811 } 13812 13813 return true; 13814 } 13815 13816 /** 13817 * Report errors that occur while attempting to start Instrumentation. Always writes the 13818 * error to the logs, but if somebody is watching, send the report there too. This enables 13819 * the "am" command to report errors with more information. 13820 * 13821 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13822 * @param cn The component name of the instrumentation. 13823 * @param report The error report. 13824 */ 13825 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13826 ComponentName cn, String report) { 13827 Slog.w(TAG, report); 13828 try { 13829 if (watcher != null) { 13830 Bundle results = new Bundle(); 13831 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13832 results.putString("Error", report); 13833 watcher.instrumentationStatus(cn, -1, results); 13834 } 13835 } catch (RemoteException e) { 13836 Slog.w(TAG, e); 13837 } 13838 } 13839 13840 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13841 if (app.instrumentationWatcher != null) { 13842 try { 13843 // NOTE: IInstrumentationWatcher *must* be oneway here 13844 app.instrumentationWatcher.instrumentationFinished( 13845 app.instrumentationClass, 13846 resultCode, 13847 results); 13848 } catch (RemoteException e) { 13849 } 13850 } 13851 if (app.instrumentationUiAutomationConnection != null) { 13852 try { 13853 app.instrumentationUiAutomationConnection.shutdown(); 13854 } catch (RemoteException re) { 13855 /* ignore */ 13856 } 13857 // Only a UiAutomation can set this flag and now that 13858 // it is finished we make sure it is reset to its default. 13859 mUserIsMonkey = false; 13860 } 13861 app.instrumentationWatcher = null; 13862 app.instrumentationUiAutomationConnection = null; 13863 app.instrumentationClass = null; 13864 app.instrumentationInfo = null; 13865 app.instrumentationProfileFile = null; 13866 app.instrumentationArguments = null; 13867 13868 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId, 13869 "finished inst"); 13870 } 13871 13872 public void finishInstrumentation(IApplicationThread target, 13873 int resultCode, Bundle results) { 13874 int userId = UserHandle.getCallingUserId(); 13875 // Refuse possible leaked file descriptors 13876 if (results != null && results.hasFileDescriptors()) { 13877 throw new IllegalArgumentException("File descriptors passed in Intent"); 13878 } 13879 13880 synchronized(this) { 13881 ProcessRecord app = getRecordForAppLocked(target); 13882 if (app == null) { 13883 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13884 return; 13885 } 13886 final long origId = Binder.clearCallingIdentity(); 13887 finishInstrumentationLocked(app, resultCode, results); 13888 Binder.restoreCallingIdentity(origId); 13889 } 13890 } 13891 13892 // ========================================================= 13893 // CONFIGURATION 13894 // ========================================================= 13895 13896 public ConfigurationInfo getDeviceConfigurationInfo() { 13897 ConfigurationInfo config = new ConfigurationInfo(); 13898 synchronized (this) { 13899 config.reqTouchScreen = mConfiguration.touchscreen; 13900 config.reqKeyboardType = mConfiguration.keyboard; 13901 config.reqNavigation = mConfiguration.navigation; 13902 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13903 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13904 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13905 } 13906 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13907 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13908 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13909 } 13910 config.reqGlEsVersion = GL_ES_VERSION; 13911 } 13912 return config; 13913 } 13914 13915 ActivityStack getFocusedStack() { 13916 return mStackSupervisor.getFocusedStack(); 13917 } 13918 13919 public Configuration getConfiguration() { 13920 Configuration ci; 13921 synchronized(this) { 13922 ci = new Configuration(mConfiguration); 13923 } 13924 return ci; 13925 } 13926 13927 public void updatePersistentConfiguration(Configuration values) { 13928 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13929 "updateConfiguration()"); 13930 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 13931 "updateConfiguration()"); 13932 if (values == null) { 13933 throw new NullPointerException("Configuration must not be null"); 13934 } 13935 13936 synchronized(this) { 13937 final long origId = Binder.clearCallingIdentity(); 13938 updateConfigurationLocked(values, null, true, false); 13939 Binder.restoreCallingIdentity(origId); 13940 } 13941 } 13942 13943 public void updateConfiguration(Configuration values) { 13944 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13945 "updateConfiguration()"); 13946 13947 synchronized(this) { 13948 if (values == null && mWindowManager != null) { 13949 // sentinel: fetch the current configuration from the window manager 13950 values = mWindowManager.computeNewConfiguration(); 13951 } 13952 13953 if (mWindowManager != null) { 13954 mProcessList.applyDisplaySize(mWindowManager); 13955 } 13956 13957 final long origId = Binder.clearCallingIdentity(); 13958 if (values != null) { 13959 Settings.System.clearConfiguration(values); 13960 } 13961 updateConfigurationLocked(values, null, false, false); 13962 Binder.restoreCallingIdentity(origId); 13963 } 13964 } 13965 13966 /** 13967 * Do either or both things: (1) change the current configuration, and (2) 13968 * make sure the given activity is running with the (now) current 13969 * configuration. Returns true if the activity has been left running, or 13970 * false if <var>starting</var> is being destroyed to match the new 13971 * configuration. 13972 * @param persistent TODO 13973 */ 13974 boolean updateConfigurationLocked(Configuration values, 13975 ActivityRecord starting, boolean persistent, boolean initLocale) { 13976 int changes = 0; 13977 13978 if (values != null) { 13979 Configuration newConfig = new Configuration(mConfiguration); 13980 changes = newConfig.updateFrom(values); 13981 if (changes != 0) { 13982 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13983 Slog.i(TAG, "Updating configuration to: " + values); 13984 } 13985 13986 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 13987 13988 if (values.locale != null && !initLocale) { 13989 saveLocaleLocked(values.locale, 13990 !values.locale.equals(mConfiguration.locale), 13991 values.userSetLocale); 13992 } 13993 13994 mConfigurationSeq++; 13995 if (mConfigurationSeq <= 0) { 13996 mConfigurationSeq = 1; 13997 } 13998 newConfig.seq = mConfigurationSeq; 13999 mConfiguration = newConfig; 14000 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14001 14002 final Configuration configCopy = new Configuration(mConfiguration); 14003 14004 // TODO: If our config changes, should we auto dismiss any currently 14005 // showing dialogs? 14006 mShowDialogs = shouldShowDialogs(newConfig); 14007 14008 AttributeCache ac = AttributeCache.instance(); 14009 if (ac != null) { 14010 ac.updateConfiguration(configCopy); 14011 } 14012 14013 // Make sure all resources in our process are updated 14014 // right now, so that anyone who is going to retrieve 14015 // resource values after we return will be sure to get 14016 // the new ones. This is especially important during 14017 // boot, where the first config change needs to guarantee 14018 // all resources have that config before following boot 14019 // code is executed. 14020 mSystemThread.applyConfigurationToResources(configCopy); 14021 14022 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14023 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14024 msg.obj = new Configuration(configCopy); 14025 mHandler.sendMessage(msg); 14026 } 14027 14028 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14029 ProcessRecord app = mLruProcesses.get(i); 14030 try { 14031 if (app.thread != null) { 14032 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14033 + app.processName + " new config " + mConfiguration); 14034 app.thread.scheduleConfigurationChanged(configCopy); 14035 } 14036 } catch (Exception e) { 14037 } 14038 } 14039 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14040 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14041 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14042 | Intent.FLAG_RECEIVER_FOREGROUND); 14043 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14044 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14045 Process.SYSTEM_UID, UserHandle.USER_ALL); 14046 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14047 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14048 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14049 broadcastIntentLocked(null, null, intent, 14050 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14051 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14052 } 14053 } 14054 } 14055 14056 boolean kept = true; 14057 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14058 // mainStack is null during startup. 14059 if (mainStack != null) { 14060 if (changes != 0 && starting == null) { 14061 // If the configuration changed, and the caller is not already 14062 // in the process of starting an activity, then find the top 14063 // activity to check if its configuration needs to change. 14064 starting = mainStack.topRunningActivityLocked(null); 14065 } 14066 14067 if (starting != null) { 14068 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14069 // And we need to make sure at this point that all other activities 14070 // are made visible with the correct configuration. 14071 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14072 } 14073 } 14074 14075 if (values != null && mWindowManager != null) { 14076 mWindowManager.setNewConfiguration(mConfiguration); 14077 } 14078 14079 return kept; 14080 } 14081 14082 /** 14083 * Decide based on the configuration whether we should shouw the ANR, 14084 * crash, etc dialogs. The idea is that if there is no affordnace to 14085 * press the on-screen buttons, we shouldn't show the dialog. 14086 * 14087 * A thought: SystemUI might also want to get told about this, the Power 14088 * dialog / global actions also might want different behaviors. 14089 */ 14090 private static final boolean shouldShowDialogs(Configuration config) { 14091 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14092 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14093 } 14094 14095 /** 14096 * Save the locale. You must be inside a synchronized (this) block. 14097 */ 14098 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14099 if(isDiff) { 14100 SystemProperties.set("user.language", l.getLanguage()); 14101 SystemProperties.set("user.region", l.getCountry()); 14102 } 14103 14104 if(isPersist) { 14105 SystemProperties.set("persist.sys.language", l.getLanguage()); 14106 SystemProperties.set("persist.sys.country", l.getCountry()); 14107 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14108 } 14109 } 14110 14111 @Override 14112 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14113 ActivityRecord srec = ActivityRecord.forToken(token); 14114 return srec != null && srec.task.affinity != null && 14115 srec.task.affinity.equals(destAffinity); 14116 } 14117 14118 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14119 Intent resultData) { 14120 14121 synchronized (this) { 14122 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14123 if (stack != null) { 14124 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14125 } 14126 return false; 14127 } 14128 } 14129 14130 public int getLaunchedFromUid(IBinder activityToken) { 14131 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14132 if (srec == null) { 14133 return -1; 14134 } 14135 return srec.launchedFromUid; 14136 } 14137 14138 public String getLaunchedFromPackage(IBinder activityToken) { 14139 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14140 if (srec == null) { 14141 return null; 14142 } 14143 return srec.launchedFromPackage; 14144 } 14145 14146 // ========================================================= 14147 // LIFETIME MANAGEMENT 14148 // ========================================================= 14149 14150 // Returns which broadcast queue the app is the current [or imminent] receiver 14151 // on, or 'null' if the app is not an active broadcast recipient. 14152 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14153 BroadcastRecord r = app.curReceiver; 14154 if (r != null) { 14155 return r.queue; 14156 } 14157 14158 // It's not the current receiver, but it might be starting up to become one 14159 synchronized (this) { 14160 for (BroadcastQueue queue : mBroadcastQueues) { 14161 r = queue.mPendingBroadcast; 14162 if (r != null && r.curApp == app) { 14163 // found it; report which queue it's in 14164 return queue; 14165 } 14166 } 14167 } 14168 14169 return null; 14170 } 14171 14172 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14173 boolean doingAll, long now) { 14174 if (mAdjSeq == app.adjSeq) { 14175 // This adjustment has already been computed. 14176 return app.curRawAdj; 14177 } 14178 14179 if (app.thread == null) { 14180 app.adjSeq = mAdjSeq; 14181 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14182 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14183 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14184 } 14185 14186 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14187 app.adjSource = null; 14188 app.adjTarget = null; 14189 app.empty = false; 14190 app.cached = false; 14191 14192 final int activitiesSize = app.activities.size(); 14193 14194 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14195 // The max adjustment doesn't allow this app to be anything 14196 // below foreground, so it is not worth doing work for it. 14197 app.adjType = "fixed"; 14198 app.adjSeq = mAdjSeq; 14199 app.curRawAdj = app.maxAdj; 14200 app.foregroundActivities = false; 14201 app.keeping = true; 14202 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14203 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14204 // System process can do UI, and when they do we want to have 14205 // them trim their memory after the user leaves the UI. To 14206 // facilitate this, here we need to determine whether or not it 14207 // is currently showing UI. 14208 app.systemNoUi = true; 14209 if (app == TOP_APP) { 14210 app.systemNoUi = false; 14211 } else if (activitiesSize > 0) { 14212 for (int j = 0; j < activitiesSize; j++) { 14213 final ActivityRecord r = app.activities.get(j); 14214 if (r.visible) { 14215 app.systemNoUi = false; 14216 } 14217 } 14218 } 14219 if (!app.systemNoUi) { 14220 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14221 } 14222 return (app.curAdj=app.maxAdj); 14223 } 14224 14225 app.keeping = false; 14226 app.systemNoUi = false; 14227 14228 // Determine the importance of the process, starting with most 14229 // important to least, and assign an appropriate OOM adjustment. 14230 int adj; 14231 int schedGroup; 14232 int procState; 14233 boolean foregroundActivities = false; 14234 boolean interesting = false; 14235 BroadcastQueue queue; 14236 if (app == TOP_APP) { 14237 // The last app on the list is the foreground app. 14238 adj = ProcessList.FOREGROUND_APP_ADJ; 14239 schedGroup = Process.THREAD_GROUP_DEFAULT; 14240 app.adjType = "top-activity"; 14241 foregroundActivities = true; 14242 interesting = true; 14243 procState = ActivityManager.PROCESS_STATE_TOP; 14244 } else if (app.instrumentationClass != null) { 14245 // Don't want to kill running instrumentation. 14246 adj = ProcessList.FOREGROUND_APP_ADJ; 14247 schedGroup = Process.THREAD_GROUP_DEFAULT; 14248 app.adjType = "instrumentation"; 14249 interesting = true; 14250 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14251 } else if ((queue = isReceivingBroadcast(app)) != null) { 14252 // An app that is currently receiving a broadcast also 14253 // counts as being in the foreground for OOM killer purposes. 14254 // It's placed in a sched group based on the nature of the 14255 // broadcast as reflected by which queue it's active in. 14256 adj = ProcessList.FOREGROUND_APP_ADJ; 14257 schedGroup = (queue == mFgBroadcastQueue) 14258 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14259 app.adjType = "broadcast"; 14260 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14261 } else if (app.executingServices.size() > 0) { 14262 // An app that is currently executing a service callback also 14263 // counts as being in the foreground. 14264 adj = ProcessList.FOREGROUND_APP_ADJ; 14265 schedGroup = app.execServicesFg ? 14266 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14267 app.adjType = "exec-service"; 14268 procState = ActivityManager.PROCESS_STATE_SERVICE; 14269 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14270 } else { 14271 // As far as we know the process is empty. We may change our mind later. 14272 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14273 // At this point we don't actually know the adjustment. Use the cached adj 14274 // value that the caller wants us to. 14275 adj = cachedAdj; 14276 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14277 app.cached = true; 14278 app.empty = true; 14279 app.adjType = "cch-empty"; 14280 } 14281 14282 // Examine all activities if not already foreground. 14283 if (!foregroundActivities && activitiesSize > 0) { 14284 for (int j = 0; j < activitiesSize; j++) { 14285 final ActivityRecord r = app.activities.get(j); 14286 if (r.app != app) { 14287 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14288 + app + "?!?"); 14289 continue; 14290 } 14291 if (r.visible) { 14292 // App has a visible activity; only upgrade adjustment. 14293 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14294 adj = ProcessList.VISIBLE_APP_ADJ; 14295 app.adjType = "visible"; 14296 } 14297 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14298 procState = ActivityManager.PROCESS_STATE_TOP; 14299 } 14300 schedGroup = Process.THREAD_GROUP_DEFAULT; 14301 app.cached = false; 14302 app.empty = false; 14303 foregroundActivities = true; 14304 break; 14305 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14306 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14307 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14308 app.adjType = "pausing"; 14309 } 14310 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14311 procState = ActivityManager.PROCESS_STATE_TOP; 14312 } 14313 schedGroup = Process.THREAD_GROUP_DEFAULT; 14314 app.cached = false; 14315 app.empty = false; 14316 foregroundActivities = true; 14317 } else if (r.state == ActivityState.STOPPING) { 14318 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14319 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14320 app.adjType = "stopping"; 14321 } 14322 // For the process state, we will at this point consider the 14323 // process to be cached. It will be cached either as an activity 14324 // or empty depending on whether the activity is finishing. We do 14325 // this so that we can treat the process as cached for purposes of 14326 // memory trimming (determing current memory level, trim command to 14327 // send to process) since there can be an arbitrary number of stopping 14328 // processes and they should soon all go into the cached state. 14329 if (!r.finishing) { 14330 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14331 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14332 } 14333 } 14334 app.cached = false; 14335 app.empty = false; 14336 foregroundActivities = true; 14337 } else { 14338 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14339 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14340 app.adjType = "cch-act"; 14341 } 14342 } 14343 } 14344 } 14345 14346 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14347 if (app.foregroundServices) { 14348 // The user is aware of this app, so make it visible. 14349 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14350 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14351 app.cached = false; 14352 app.adjType = "fg-service"; 14353 schedGroup = Process.THREAD_GROUP_DEFAULT; 14354 } else if (app.forcingToForeground != null) { 14355 // The user is aware of this app, so make it visible. 14356 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14357 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14358 app.cached = false; 14359 app.adjType = "force-fg"; 14360 app.adjSource = app.forcingToForeground; 14361 schedGroup = Process.THREAD_GROUP_DEFAULT; 14362 } 14363 } 14364 14365 if (app.foregroundServices) { 14366 interesting = true; 14367 } 14368 14369 if (app == mHeavyWeightProcess) { 14370 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14371 // We don't want to kill the current heavy-weight process. 14372 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14373 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14374 app.cached = false; 14375 app.adjType = "heavy"; 14376 } 14377 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14378 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14379 } 14380 } 14381 14382 if (app == mHomeProcess) { 14383 if (adj > ProcessList.HOME_APP_ADJ) { 14384 // This process is hosting what we currently consider to be the 14385 // home app, so we don't want to let it go into the background. 14386 adj = ProcessList.HOME_APP_ADJ; 14387 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14388 app.cached = false; 14389 app.adjType = "home"; 14390 } 14391 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14392 procState = ActivityManager.PROCESS_STATE_HOME; 14393 } 14394 } 14395 14396 if (app == mPreviousProcess && app.activities.size() > 0) { 14397 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14398 // This was the previous process that showed UI to the user. 14399 // We want to try to keep it around more aggressively, to give 14400 // a good experience around switching between two apps. 14401 adj = ProcessList.PREVIOUS_APP_ADJ; 14402 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14403 app.cached = false; 14404 app.adjType = "previous"; 14405 } 14406 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14407 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14408 } 14409 } 14410 14411 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14412 + " reason=" + app.adjType); 14413 14414 // By default, we use the computed adjustment. It may be changed if 14415 // there are applications dependent on our services or providers, but 14416 // this gives us a baseline and makes sure we don't get into an 14417 // infinite recursion. 14418 app.adjSeq = mAdjSeq; 14419 app.curRawAdj = adj; 14420 app.hasStartedServices = false; 14421 14422 if (mBackupTarget != null && app == mBackupTarget.app) { 14423 // If possible we want to avoid killing apps while they're being backed up 14424 if (adj > ProcessList.BACKUP_APP_ADJ) { 14425 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14426 adj = ProcessList.BACKUP_APP_ADJ; 14427 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14428 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14429 } 14430 app.adjType = "backup"; 14431 app.cached = false; 14432 } 14433 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14434 procState = ActivityManager.PROCESS_STATE_BACKUP; 14435 } 14436 } 14437 14438 boolean mayBeTop = false; 14439 14440 for (int is = app.services.size()-1; 14441 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14442 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14443 || procState > ActivityManager.PROCESS_STATE_TOP); 14444 is--) { 14445 ServiceRecord s = app.services.valueAt(is); 14446 if (s.startRequested) { 14447 app.hasStartedServices = true; 14448 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14449 procState = ActivityManager.PROCESS_STATE_SERVICE; 14450 } 14451 if (app.hasShownUi && app != mHomeProcess) { 14452 // If this process has shown some UI, let it immediately 14453 // go to the LRU list because it may be pretty heavy with 14454 // UI stuff. We'll tag it with a label just to help 14455 // debug and understand what is going on. 14456 if (adj > ProcessList.SERVICE_ADJ) { 14457 app.adjType = "cch-started-ui-services"; 14458 } 14459 } else { 14460 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14461 // This service has seen some activity within 14462 // recent memory, so we will keep its process ahead 14463 // of the background processes. 14464 if (adj > ProcessList.SERVICE_ADJ) { 14465 adj = ProcessList.SERVICE_ADJ; 14466 app.adjType = "started-services"; 14467 app.cached = false; 14468 } 14469 } 14470 // If we have let the service slide into the background 14471 // state, still have some text describing what it is doing 14472 // even though the service no longer has an impact. 14473 if (adj > ProcessList.SERVICE_ADJ) { 14474 app.adjType = "cch-started-services"; 14475 } 14476 } 14477 // Don't kill this process because it is doing work; it 14478 // has said it is doing work. 14479 app.keeping = true; 14480 } 14481 for (int conni = s.connections.size()-1; 14482 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14483 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14484 || procState > ActivityManager.PROCESS_STATE_TOP); 14485 conni--) { 14486 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14487 for (int i = 0; 14488 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14489 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14490 || procState > ActivityManager.PROCESS_STATE_TOP); 14491 i++) { 14492 // XXX should compute this based on the max of 14493 // all connected clients. 14494 ConnectionRecord cr = clist.get(i); 14495 if (cr.binding.client == app) { 14496 // Binding to ourself is not interesting. 14497 continue; 14498 } 14499 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14500 ProcessRecord client = cr.binding.client; 14501 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14502 TOP_APP, doingAll, now); 14503 int clientProcState = client.curProcState; 14504 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14505 // If the other app is cached for any reason, for purposes here 14506 // we are going to consider it empty. The specific cached state 14507 // doesn't propagate except under certain conditions. 14508 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14509 } 14510 String adjType = null; 14511 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14512 // Not doing bind OOM management, so treat 14513 // this guy more like a started service. 14514 if (app.hasShownUi && app != mHomeProcess) { 14515 // If this process has shown some UI, let it immediately 14516 // go to the LRU list because it may be pretty heavy with 14517 // UI stuff. We'll tag it with a label just to help 14518 // debug and understand what is going on. 14519 if (adj > clientAdj) { 14520 adjType = "cch-bound-ui-services"; 14521 } 14522 app.cached = false; 14523 clientAdj = adj; 14524 clientProcState = procState; 14525 } else { 14526 if (now >= (s.lastActivity 14527 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14528 // This service has not seen activity within 14529 // recent memory, so allow it to drop to the 14530 // LRU list if there is no other reason to keep 14531 // it around. We'll also tag it with a label just 14532 // to help debug and undertand what is going on. 14533 if (adj > clientAdj) { 14534 adjType = "cch-bound-services"; 14535 } 14536 clientAdj = adj; 14537 } 14538 } 14539 } 14540 if (adj > clientAdj) { 14541 // If this process has recently shown UI, and 14542 // the process that is binding to it is less 14543 // important than being visible, then we don't 14544 // care about the binding as much as we care 14545 // about letting this process get into the LRU 14546 // list to be killed and restarted if needed for 14547 // memory. 14548 if (app.hasShownUi && app != mHomeProcess 14549 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14550 adjType = "cch-bound-ui-services"; 14551 } else { 14552 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14553 |Context.BIND_IMPORTANT)) != 0) { 14554 adj = clientAdj; 14555 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14556 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14557 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14558 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14559 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14560 adj = clientAdj; 14561 } else { 14562 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14563 adj = ProcessList.VISIBLE_APP_ADJ; 14564 } 14565 } 14566 if (!client.cached) { 14567 app.cached = false; 14568 } 14569 if (client.keeping) { 14570 app.keeping = true; 14571 } 14572 adjType = "service"; 14573 } 14574 } 14575 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14576 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14577 schedGroup = Process.THREAD_GROUP_DEFAULT; 14578 } 14579 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14580 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14581 // Special handling of clients who are in the top state. 14582 // We *may* want to consider this process to be in the 14583 // top state as well, but only if there is not another 14584 // reason for it to be running. Being on the top is a 14585 // special state, meaning you are specifically running 14586 // for the current top app. If the process is already 14587 // running in the background for some other reason, it 14588 // is more important to continue considering it to be 14589 // in the background state. 14590 mayBeTop = true; 14591 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14592 } else { 14593 // Special handling for above-top states (persistent 14594 // processes). These should not bring the current process 14595 // into the top state, since they are not on top. Instead 14596 // give them the best state after that. 14597 clientProcState = 14598 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14599 } 14600 } 14601 } else { 14602 if (clientProcState < 14603 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14604 clientProcState = 14605 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14606 } 14607 } 14608 if (procState > clientProcState) { 14609 procState = clientProcState; 14610 } 14611 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14612 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14613 app.pendingUiClean = true; 14614 } 14615 if (adjType != null) { 14616 app.adjType = adjType; 14617 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14618 .REASON_SERVICE_IN_USE; 14619 app.adjSource = cr.binding.client; 14620 app.adjSourceOom = clientAdj; 14621 app.adjTarget = s.name; 14622 } 14623 } 14624 final ActivityRecord a = cr.activity; 14625 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14626 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14627 (a.visible || a.state == ActivityState.RESUMED 14628 || a.state == ActivityState.PAUSING)) { 14629 adj = ProcessList.FOREGROUND_APP_ADJ; 14630 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14631 schedGroup = Process.THREAD_GROUP_DEFAULT; 14632 } 14633 app.cached = false; 14634 app.adjType = "service"; 14635 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14636 .REASON_SERVICE_IN_USE; 14637 app.adjSource = a; 14638 app.adjSourceOom = adj; 14639 app.adjTarget = s.name; 14640 } 14641 } 14642 } 14643 } 14644 } 14645 14646 for (int provi = app.pubProviders.size()-1; 14647 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14648 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14649 || procState > ActivityManager.PROCESS_STATE_TOP); 14650 provi--) { 14651 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14652 for (int i = cpr.connections.size()-1; 14653 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14654 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14655 || procState > ActivityManager.PROCESS_STATE_TOP); 14656 i--) { 14657 ContentProviderConnection conn = cpr.connections.get(i); 14658 ProcessRecord client = conn.client; 14659 if (client == app) { 14660 // Being our own client is not interesting. 14661 continue; 14662 } 14663 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14664 int clientProcState = client.curProcState; 14665 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14666 // If the other app is cached for any reason, for purposes here 14667 // we are going to consider it empty. 14668 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14669 } 14670 if (adj > clientAdj) { 14671 if (app.hasShownUi && app != mHomeProcess 14672 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14673 app.adjType = "cch-ui-provider"; 14674 } else { 14675 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14676 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14677 app.adjType = "provider"; 14678 } 14679 app.cached &= client.cached; 14680 app.keeping |= client.keeping; 14681 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14682 .REASON_PROVIDER_IN_USE; 14683 app.adjSource = client; 14684 app.adjSourceOom = clientAdj; 14685 app.adjTarget = cpr.name; 14686 } 14687 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14688 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14689 // Special handling of clients who are in the top state. 14690 // We *may* want to consider this process to be in the 14691 // top state as well, but only if there is not another 14692 // reason for it to be running. Being on the top is a 14693 // special state, meaning you are specifically running 14694 // for the current top app. If the process is already 14695 // running in the background for some other reason, it 14696 // is more important to continue considering it to be 14697 // in the background state. 14698 mayBeTop = true; 14699 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14700 } else { 14701 // Special handling for above-top states (persistent 14702 // processes). These should not bring the current process 14703 // into the top state, since they are not on top. Instead 14704 // give them the best state after that. 14705 clientProcState = 14706 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14707 } 14708 } 14709 if (procState > clientProcState) { 14710 procState = clientProcState; 14711 } 14712 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14713 schedGroup = Process.THREAD_GROUP_DEFAULT; 14714 } 14715 } 14716 // If the provider has external (non-framework) process 14717 // dependencies, ensure that its adjustment is at least 14718 // FOREGROUND_APP_ADJ. 14719 if (cpr.hasExternalProcessHandles()) { 14720 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14721 adj = ProcessList.FOREGROUND_APP_ADJ; 14722 schedGroup = Process.THREAD_GROUP_DEFAULT; 14723 app.cached = false; 14724 app.keeping = true; 14725 app.adjType = "provider"; 14726 app.adjTarget = cpr.name; 14727 } 14728 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14729 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14730 } 14731 } 14732 } 14733 14734 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14735 // A client of one of our services or providers is in the top state. We 14736 // *may* want to be in the top state, but not if we are already running in 14737 // the background for some other reason. For the decision here, we are going 14738 // to pick out a few specific states that we want to remain in when a client 14739 // is top (states that tend to be longer-term) and otherwise allow it to go 14740 // to the top state. 14741 switch (procState) { 14742 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14743 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14744 case ActivityManager.PROCESS_STATE_SERVICE: 14745 // These all are longer-term states, so pull them up to the top 14746 // of the background states, but not all the way to the top state. 14747 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14748 break; 14749 default: 14750 // Otherwise, top is a better choice, so take it. 14751 procState = ActivityManager.PROCESS_STATE_TOP; 14752 break; 14753 } 14754 } 14755 14756 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14757 // This is a cached process, but with client activities. Mark it so. 14758 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14759 app.adjType = "cch-client-act"; 14760 } 14761 14762 if (adj == ProcessList.SERVICE_ADJ) { 14763 if (doingAll) { 14764 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14765 mNewNumServiceProcs++; 14766 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14767 if (!app.serviceb) { 14768 // This service isn't far enough down on the LRU list to 14769 // normally be a B service, but if we are low on RAM and it 14770 // is large we want to force it down since we would prefer to 14771 // keep launcher over it. 14772 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 14773 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 14774 app.serviceHighRam = true; 14775 app.serviceb = true; 14776 //Slog.i(TAG, "ADJ " + app + " high ram!"); 14777 } else { 14778 mNewNumAServiceProcs++; 14779 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 14780 } 14781 } else { 14782 app.serviceHighRam = false; 14783 } 14784 } 14785 if (app.serviceb) { 14786 adj = ProcessList.SERVICE_B_ADJ; 14787 } 14788 } 14789 14790 app.curRawAdj = adj; 14791 14792 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14793 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14794 if (adj > app.maxAdj) { 14795 adj = app.maxAdj; 14796 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14797 schedGroup = Process.THREAD_GROUP_DEFAULT; 14798 } 14799 } 14800 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 14801 app.keeping = true; 14802 } 14803 14804 // Do final modification to adj. Everything we do between here and applying 14805 // the final setAdj must be done in this function, because we will also use 14806 // it when computing the final cached adj later. Note that we don't need to 14807 // worry about this for max adj above, since max adj will always be used to 14808 // keep it out of the cached vaues. 14809 adj = app.modifyRawOomAdj(adj); 14810 14811 app.curProcState = procState; 14812 14813 int importance = app.memImportance; 14814 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14815 app.curAdj = adj; 14816 app.curSchedGroup = schedGroup; 14817 if (!interesting) { 14818 // For this reporting, if there is not something explicitly 14819 // interesting in this process then we will push it to the 14820 // background importance. 14821 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14822 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 14823 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14824 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14825 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14826 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14827 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14828 } else if (adj >= ProcessList.SERVICE_ADJ) { 14829 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14830 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14831 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14832 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14833 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14834 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14835 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14836 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14837 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14838 } else { 14839 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14840 } 14841 } 14842 14843 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14844 if (foregroundActivities != app.foregroundActivities) { 14845 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14846 } 14847 if (changes != 0) { 14848 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14849 app.memImportance = importance; 14850 app.foregroundActivities = foregroundActivities; 14851 int i = mPendingProcessChanges.size()-1; 14852 ProcessChangeItem item = null; 14853 while (i >= 0) { 14854 item = mPendingProcessChanges.get(i); 14855 if (item.pid == app.pid) { 14856 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14857 break; 14858 } 14859 i--; 14860 } 14861 if (i < 0) { 14862 // No existing item in pending changes; need a new one. 14863 final int NA = mAvailProcessChanges.size(); 14864 if (NA > 0) { 14865 item = mAvailProcessChanges.remove(NA-1); 14866 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14867 } else { 14868 item = new ProcessChangeItem(); 14869 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14870 } 14871 item.changes = 0; 14872 item.pid = app.pid; 14873 item.uid = app.info.uid; 14874 if (mPendingProcessChanges.size() == 0) { 14875 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14876 "*** Enqueueing dispatch processes changed!"); 14877 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14878 } 14879 mPendingProcessChanges.add(item); 14880 } 14881 item.changes |= changes; 14882 item.importance = importance; 14883 item.foregroundActivities = foregroundActivities; 14884 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14885 + Integer.toHexString(System.identityHashCode(item)) 14886 + " " + app.toShortString() + ": changes=" + item.changes 14887 + " importance=" + item.importance 14888 + " foreground=" + item.foregroundActivities 14889 + " type=" + app.adjType + " source=" + app.adjSource 14890 + " target=" + app.adjTarget); 14891 } 14892 14893 return app.curRawAdj; 14894 } 14895 14896 /** 14897 * Schedule PSS collection of a process. 14898 */ 14899 void requestPssLocked(ProcessRecord proc, int procState) { 14900 if (mPendingPssProcesses.contains(proc)) { 14901 return; 14902 } 14903 if (mPendingPssProcesses.size() == 0) { 14904 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14905 } 14906 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 14907 proc.pssProcState = procState; 14908 mPendingPssProcesses.add(proc); 14909 } 14910 14911 /** 14912 * Schedule PSS collection of all processes. 14913 */ 14914 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 14915 if (!always) { 14916 if (now < (mLastFullPssTime + 14917 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 14918 return; 14919 } 14920 } 14921 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 14922 mLastFullPssTime = now; 14923 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 14924 mPendingPssProcesses.clear(); 14925 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14926 ProcessRecord app = mLruProcesses.get(i); 14927 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 14928 app.pssProcState = app.setProcState; 14929 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 14930 mSleeping, now); 14931 mPendingPssProcesses.add(app); 14932 } 14933 } 14934 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14935 } 14936 14937 /** 14938 * Ask a given process to GC right now. 14939 */ 14940 final void performAppGcLocked(ProcessRecord app) { 14941 try { 14942 app.lastRequestedGc = SystemClock.uptimeMillis(); 14943 if (app.thread != null) { 14944 if (app.reportLowMemory) { 14945 app.reportLowMemory = false; 14946 app.thread.scheduleLowMemory(); 14947 } else { 14948 app.thread.processInBackground(); 14949 } 14950 } 14951 } catch (Exception e) { 14952 // whatever. 14953 } 14954 } 14955 14956 /** 14957 * Returns true if things are idle enough to perform GCs. 14958 */ 14959 private final boolean canGcNowLocked() { 14960 boolean processingBroadcasts = false; 14961 for (BroadcastQueue q : mBroadcastQueues) { 14962 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 14963 processingBroadcasts = true; 14964 } 14965 } 14966 return !processingBroadcasts 14967 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 14968 } 14969 14970 /** 14971 * Perform GCs on all processes that are waiting for it, but only 14972 * if things are idle. 14973 */ 14974 final void performAppGcsLocked() { 14975 final int N = mProcessesToGc.size(); 14976 if (N <= 0) { 14977 return; 14978 } 14979 if (canGcNowLocked()) { 14980 while (mProcessesToGc.size() > 0) { 14981 ProcessRecord proc = mProcessesToGc.remove(0); 14982 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 14983 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 14984 <= SystemClock.uptimeMillis()) { 14985 // To avoid spamming the system, we will GC processes one 14986 // at a time, waiting a few seconds between each. 14987 performAppGcLocked(proc); 14988 scheduleAppGcsLocked(); 14989 return; 14990 } else { 14991 // It hasn't been long enough since we last GCed this 14992 // process... put it in the list to wait for its time. 14993 addProcessToGcListLocked(proc); 14994 break; 14995 } 14996 } 14997 } 14998 14999 scheduleAppGcsLocked(); 15000 } 15001 } 15002 15003 /** 15004 * If all looks good, perform GCs on all processes waiting for them. 15005 */ 15006 final void performAppGcsIfAppropriateLocked() { 15007 if (canGcNowLocked()) { 15008 performAppGcsLocked(); 15009 return; 15010 } 15011 // Still not idle, wait some more. 15012 scheduleAppGcsLocked(); 15013 } 15014 15015 /** 15016 * Schedule the execution of all pending app GCs. 15017 */ 15018 final void scheduleAppGcsLocked() { 15019 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15020 15021 if (mProcessesToGc.size() > 0) { 15022 // Schedule a GC for the time to the next process. 15023 ProcessRecord proc = mProcessesToGc.get(0); 15024 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15025 15026 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15027 long now = SystemClock.uptimeMillis(); 15028 if (when < (now+GC_TIMEOUT)) { 15029 when = now + GC_TIMEOUT; 15030 } 15031 mHandler.sendMessageAtTime(msg, when); 15032 } 15033 } 15034 15035 /** 15036 * Add a process to the array of processes waiting to be GCed. Keeps the 15037 * list in sorted order by the last GC time. The process can't already be 15038 * on the list. 15039 */ 15040 final void addProcessToGcListLocked(ProcessRecord proc) { 15041 boolean added = false; 15042 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15043 if (mProcessesToGc.get(i).lastRequestedGc < 15044 proc.lastRequestedGc) { 15045 added = true; 15046 mProcessesToGc.add(i+1, proc); 15047 break; 15048 } 15049 } 15050 if (!added) { 15051 mProcessesToGc.add(0, proc); 15052 } 15053 } 15054 15055 /** 15056 * Set up to ask a process to GC itself. This will either do it 15057 * immediately, or put it on the list of processes to gc the next 15058 * time things are idle. 15059 */ 15060 final void scheduleAppGcLocked(ProcessRecord app) { 15061 long now = SystemClock.uptimeMillis(); 15062 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15063 return; 15064 } 15065 if (!mProcessesToGc.contains(app)) { 15066 addProcessToGcListLocked(app); 15067 scheduleAppGcsLocked(); 15068 } 15069 } 15070 15071 final void checkExcessivePowerUsageLocked(boolean doKills) { 15072 updateCpuStatsNow(); 15073 15074 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15075 boolean doWakeKills = doKills; 15076 boolean doCpuKills = doKills; 15077 if (mLastPowerCheckRealtime == 0) { 15078 doWakeKills = false; 15079 } 15080 if (mLastPowerCheckUptime == 0) { 15081 doCpuKills = false; 15082 } 15083 if (stats.isScreenOn()) { 15084 doWakeKills = false; 15085 } 15086 final long curRealtime = SystemClock.elapsedRealtime(); 15087 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15088 final long curUptime = SystemClock.uptimeMillis(); 15089 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15090 mLastPowerCheckRealtime = curRealtime; 15091 mLastPowerCheckUptime = curUptime; 15092 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15093 doWakeKills = false; 15094 } 15095 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15096 doCpuKills = false; 15097 } 15098 int i = mLruProcesses.size(); 15099 while (i > 0) { 15100 i--; 15101 ProcessRecord app = mLruProcesses.get(i); 15102 if (!app.keeping) { 15103 long wtime; 15104 synchronized (stats) { 15105 wtime = stats.getProcessWakeTime(app.info.uid, 15106 app.pid, curRealtime); 15107 } 15108 long wtimeUsed = wtime - app.lastWakeTime; 15109 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15110 if (DEBUG_POWER) { 15111 StringBuilder sb = new StringBuilder(128); 15112 sb.append("Wake for "); 15113 app.toShortString(sb); 15114 sb.append(": over "); 15115 TimeUtils.formatDuration(realtimeSince, sb); 15116 sb.append(" used "); 15117 TimeUtils.formatDuration(wtimeUsed, sb); 15118 sb.append(" ("); 15119 sb.append((wtimeUsed*100)/realtimeSince); 15120 sb.append("%)"); 15121 Slog.i(TAG, sb.toString()); 15122 sb.setLength(0); 15123 sb.append("CPU for "); 15124 app.toShortString(sb); 15125 sb.append(": over "); 15126 TimeUtils.formatDuration(uptimeSince, sb); 15127 sb.append(" used "); 15128 TimeUtils.formatDuration(cputimeUsed, sb); 15129 sb.append(" ("); 15130 sb.append((cputimeUsed*100)/uptimeSince); 15131 sb.append("%)"); 15132 Slog.i(TAG, sb.toString()); 15133 } 15134 // If a process has held a wake lock for more 15135 // than 50% of the time during this period, 15136 // that sounds bad. Kill! 15137 if (doWakeKills && realtimeSince > 0 15138 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15139 synchronized (stats) { 15140 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15141 realtimeSince, wtimeUsed); 15142 } 15143 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15144 + " during " + realtimeSince); 15145 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15146 } else if (doCpuKills && uptimeSince > 0 15147 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15148 synchronized (stats) { 15149 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15150 uptimeSince, cputimeUsed); 15151 } 15152 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15153 + " during " + uptimeSince); 15154 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15155 } else { 15156 app.lastWakeTime = wtime; 15157 app.lastCpuTime = app.curCpuTime; 15158 } 15159 } 15160 } 15161 } 15162 15163 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15164 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15165 boolean success = true; 15166 15167 if (app.curRawAdj != app.setRawAdj) { 15168 if (wasKeeping && !app.keeping) { 15169 // This app is no longer something we want to keep. Note 15170 // its current wake lock time to later know to kill it if 15171 // it is not behaving well. 15172 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15173 synchronized (stats) { 15174 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15175 app.pid, SystemClock.elapsedRealtime()); 15176 } 15177 app.lastCpuTime = app.curCpuTime; 15178 } 15179 15180 app.setRawAdj = app.curRawAdj; 15181 } 15182 15183 if (app.curAdj != app.setAdj) { 15184 if (Process.setOomAdj(app.pid, app.curAdj)) { 15185 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15186 TAG, "Set " + app.pid + " " + app.processName + 15187 " adj " + app.curAdj + ": " + app.adjType); 15188 app.setAdj = app.curAdj; 15189 } else { 15190 success = false; 15191 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 15192 } 15193 } 15194 if (app.setSchedGroup != app.curSchedGroup) { 15195 app.setSchedGroup = app.curSchedGroup; 15196 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15197 "Setting process group of " + app.processName 15198 + " to " + app.curSchedGroup); 15199 if (app.waitingToKill != null && 15200 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15201 killUnneededProcessLocked(app, app.waitingToKill); 15202 success = false; 15203 } else { 15204 if (true) { 15205 long oldId = Binder.clearCallingIdentity(); 15206 try { 15207 Process.setProcessGroup(app.pid, app.curSchedGroup); 15208 } catch (Exception e) { 15209 Slog.w(TAG, "Failed setting process group of " + app.pid 15210 + " to " + app.curSchedGroup); 15211 e.printStackTrace(); 15212 } finally { 15213 Binder.restoreCallingIdentity(oldId); 15214 } 15215 } else { 15216 if (app.thread != null) { 15217 try { 15218 app.thread.setSchedulingGroup(app.curSchedGroup); 15219 } catch (RemoteException e) { 15220 } 15221 } 15222 } 15223 Process.setSwappiness(app.pid, 15224 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15225 } 15226 } 15227 if (app.repProcState != app.curProcState) { 15228 app.repProcState = app.curProcState; 15229 if (!reportingProcessState && app.thread != null) { 15230 try { 15231 if (false) { 15232 //RuntimeException h = new RuntimeException("here"); 15233 Slog.i(TAG, "Sending new process state " + app.repProcState 15234 + " to " + app /*, h*/); 15235 } 15236 app.thread.setProcessState(app.repProcState); 15237 } catch (RemoteException e) { 15238 } 15239 } 15240 } 15241 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15242 app.setProcState)) { 15243 app.lastStateTime = now; 15244 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15245 mSleeping, now); 15246 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15247 + ProcessList.makeProcStateString(app.setProcState) + " to " 15248 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15249 + (app.nextPssTime-now) + ": " + app); 15250 } else { 15251 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15252 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15253 requestPssLocked(app, app.setProcState); 15254 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15255 mSleeping, now); 15256 } else if (false && DEBUG_PSS) { 15257 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15258 } 15259 } 15260 if (app.setProcState != app.curProcState) { 15261 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15262 "Proc state change of " + app.processName 15263 + " to " + app.curProcState); 15264 app.setProcState = app.curProcState; 15265 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15266 app.notCachedSinceIdle = false; 15267 } 15268 if (!doingAll) { 15269 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15270 } else { 15271 app.procStateChanged = true; 15272 } 15273 } 15274 return success; 15275 } 15276 15277 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15278 if (proc.thread != null && proc.baseProcessTracker != null) { 15279 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15280 } 15281 } 15282 15283 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15284 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15285 if (app.thread == null) { 15286 return false; 15287 } 15288 15289 final boolean wasKeeping = app.keeping; 15290 15291 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15292 15293 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15294 reportingProcessState, now); 15295 } 15296 15297 private final ActivityRecord resumedAppLocked() { 15298 return mStackSupervisor.resumedAppLocked(); 15299 } 15300 15301 final boolean updateOomAdjLocked(ProcessRecord app) { 15302 return updateOomAdjLocked(app, false); 15303 } 15304 15305 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15306 final ActivityRecord TOP_ACT = resumedAppLocked(); 15307 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15308 final boolean wasCached = app.cached; 15309 15310 mAdjSeq++; 15311 15312 // This is the desired cached adjusment we want to tell it to use. 15313 // If our app is currently cached, we know it, and that is it. Otherwise, 15314 // we don't know it yet, and it needs to now be cached we will then 15315 // need to do a complete oom adj. 15316 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15317 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15318 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15319 SystemClock.uptimeMillis()); 15320 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15321 // Changed to/from cached state, so apps after it in the LRU 15322 // list may also be changed. 15323 updateOomAdjLocked(); 15324 } 15325 return success; 15326 } 15327 15328 final void updateOomAdjLocked() { 15329 final ActivityRecord TOP_ACT = resumedAppLocked(); 15330 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15331 final long now = SystemClock.uptimeMillis(); 15332 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15333 final int N = mLruProcesses.size(); 15334 15335 if (false) { 15336 RuntimeException e = new RuntimeException(); 15337 e.fillInStackTrace(); 15338 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15339 } 15340 15341 mAdjSeq++; 15342 mNewNumServiceProcs = 0; 15343 mNewNumAServiceProcs = 0; 15344 15345 final int emptyProcessLimit; 15346 final int cachedProcessLimit; 15347 if (mProcessLimit <= 0) { 15348 emptyProcessLimit = cachedProcessLimit = 0; 15349 } else if (mProcessLimit == 1) { 15350 emptyProcessLimit = 1; 15351 cachedProcessLimit = 0; 15352 } else { 15353 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15354 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15355 } 15356 15357 // Let's determine how many processes we have running vs. 15358 // how many slots we have for background processes; we may want 15359 // to put multiple processes in a slot of there are enough of 15360 // them. 15361 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15362 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15363 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15364 if (numEmptyProcs > cachedProcessLimit) { 15365 // If there are more empty processes than our limit on cached 15366 // processes, then use the cached process limit for the factor. 15367 // This ensures that the really old empty processes get pushed 15368 // down to the bottom, so if we are running low on memory we will 15369 // have a better chance at keeping around more cached processes 15370 // instead of a gazillion empty processes. 15371 numEmptyProcs = cachedProcessLimit; 15372 } 15373 int emptyFactor = numEmptyProcs/numSlots; 15374 if (emptyFactor < 1) emptyFactor = 1; 15375 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15376 if (cachedFactor < 1) cachedFactor = 1; 15377 int stepCached = 0; 15378 int stepEmpty = 0; 15379 int numCached = 0; 15380 int numEmpty = 0; 15381 int numTrimming = 0; 15382 15383 mNumNonCachedProcs = 0; 15384 mNumCachedHiddenProcs = 0; 15385 15386 // First update the OOM adjustment for each of the 15387 // application processes based on their current state. 15388 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15389 int nextCachedAdj = curCachedAdj+1; 15390 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15391 int nextEmptyAdj = curEmptyAdj+2; 15392 for (int i=N-1; i>=0; i--) { 15393 ProcessRecord app = mLruProcesses.get(i); 15394 if (!app.killedByAm && app.thread != null) { 15395 app.procStateChanged = false; 15396 final boolean wasKeeping = app.keeping; 15397 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15398 15399 // If we haven't yet assigned the final cached adj 15400 // to the process, do that now. 15401 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15402 switch (app.curProcState) { 15403 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15404 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15405 // This process is a cached process holding activities... 15406 // assign it the next cached value for that type, and then 15407 // step that cached level. 15408 app.curRawAdj = curCachedAdj; 15409 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15410 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15411 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15412 + ")"); 15413 if (curCachedAdj != nextCachedAdj) { 15414 stepCached++; 15415 if (stepCached >= cachedFactor) { 15416 stepCached = 0; 15417 curCachedAdj = nextCachedAdj; 15418 nextCachedAdj += 2; 15419 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15420 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15421 } 15422 } 15423 } 15424 break; 15425 default: 15426 // For everything else, assign next empty cached process 15427 // level and bump that up. Note that this means that 15428 // long-running services that have dropped down to the 15429 // cached level will be treated as empty (since their process 15430 // state is still as a service), which is what we want. 15431 app.curRawAdj = curEmptyAdj; 15432 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15433 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15434 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15435 + ")"); 15436 if (curEmptyAdj != nextEmptyAdj) { 15437 stepEmpty++; 15438 if (stepEmpty >= emptyFactor) { 15439 stepEmpty = 0; 15440 curEmptyAdj = nextEmptyAdj; 15441 nextEmptyAdj += 2; 15442 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15443 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15444 } 15445 } 15446 } 15447 break; 15448 } 15449 } 15450 15451 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15452 15453 // Count the number of process types. 15454 switch (app.curProcState) { 15455 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15456 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15457 mNumCachedHiddenProcs++; 15458 numCached++; 15459 if (numCached > cachedProcessLimit) { 15460 killUnneededProcessLocked(app, "cached #" + numCached); 15461 } 15462 break; 15463 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15464 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15465 && app.lastActivityTime < oldTime) { 15466 killUnneededProcessLocked(app, "empty for " 15467 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15468 / 1000) + "s"); 15469 } else { 15470 numEmpty++; 15471 if (numEmpty > emptyProcessLimit) { 15472 killUnneededProcessLocked(app, "empty #" + numEmpty); 15473 } 15474 } 15475 break; 15476 default: 15477 mNumNonCachedProcs++; 15478 break; 15479 } 15480 15481 if (app.isolated && app.services.size() <= 0) { 15482 // If this is an isolated process, and there are no 15483 // services running in it, then the process is no longer 15484 // needed. We agressively kill these because we can by 15485 // definition not re-use the same process again, and it is 15486 // good to avoid having whatever code was running in them 15487 // left sitting around after no longer needed. 15488 killUnneededProcessLocked(app, "isolated not needed"); 15489 } 15490 15491 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15492 && !app.killedByAm) { 15493 numTrimming++; 15494 } 15495 } 15496 } 15497 15498 mNumServiceProcs = mNewNumServiceProcs; 15499 15500 // Now determine the memory trimming level of background processes. 15501 // Unfortunately we need to start at the back of the list to do this 15502 // properly. We only do this if the number of background apps we 15503 // are managing to keep around is less than half the maximum we desire; 15504 // if we are keeping a good number around, we'll let them use whatever 15505 // memory they want. 15506 final int numCachedAndEmpty = numCached + numEmpty; 15507 int memFactor; 15508 if (numCached <= ProcessList.TRIM_CACHED_APPS 15509 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15510 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15511 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15512 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15513 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15514 } else { 15515 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15516 } 15517 } else { 15518 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15519 } 15520 // We always allow the memory level to go up (better). We only allow it to go 15521 // down if we are in a state where that is allowed, *and* the total number of processes 15522 // has gone down since last time. 15523 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15524 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15525 + " last=" + mLastNumProcesses); 15526 if (memFactor > mLastMemoryLevel) { 15527 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15528 memFactor = mLastMemoryLevel; 15529 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15530 } 15531 } 15532 mLastMemoryLevel = memFactor; 15533 mLastNumProcesses = mLruProcesses.size(); 15534 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15535 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15536 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15537 if (mLowRamStartTime == 0) { 15538 mLowRamStartTime = now; 15539 } 15540 int step = 0; 15541 int fgTrimLevel; 15542 switch (memFactor) { 15543 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15544 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15545 break; 15546 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15547 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15548 break; 15549 default: 15550 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15551 break; 15552 } 15553 int factor = numTrimming/3; 15554 int minFactor = 2; 15555 if (mHomeProcess != null) minFactor++; 15556 if (mPreviousProcess != null) minFactor++; 15557 if (factor < minFactor) factor = minFactor; 15558 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15559 for (int i=N-1; i>=0; i--) { 15560 ProcessRecord app = mLruProcesses.get(i); 15561 if (allChanged || app.procStateChanged) { 15562 setProcessTrackerState(app, trackerMemFactor, now); 15563 app.procStateChanged = false; 15564 } 15565 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15566 && !app.killedByAm) { 15567 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15568 try { 15569 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15570 "Trimming memory of " + app.processName 15571 + " to " + curLevel); 15572 app.thread.scheduleTrimMemory(curLevel); 15573 } catch (RemoteException e) { 15574 } 15575 if (false) { 15576 // For now we won't do this; our memory trimming seems 15577 // to be good enough at this point that destroying 15578 // activities causes more harm than good. 15579 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15580 && app != mHomeProcess && app != mPreviousProcess) { 15581 // Need to do this on its own message because the stack may not 15582 // be in a consistent state at this point. 15583 // For these apps we will also finish their activities 15584 // to help them free memory. 15585 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15586 } 15587 } 15588 } 15589 app.trimMemoryLevel = curLevel; 15590 step++; 15591 if (step >= factor) { 15592 step = 0; 15593 switch (curLevel) { 15594 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15595 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15596 break; 15597 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15598 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15599 break; 15600 } 15601 } 15602 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15603 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15604 && app.thread != null) { 15605 try { 15606 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15607 "Trimming memory of heavy-weight " + app.processName 15608 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15609 app.thread.scheduleTrimMemory( 15610 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15611 } catch (RemoteException e) { 15612 } 15613 } 15614 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15615 } else { 15616 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15617 || app.systemNoUi) && app.pendingUiClean) { 15618 // If this application is now in the background and it 15619 // had done UI, then give it the special trim level to 15620 // have it free UI resources. 15621 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15622 if (app.trimMemoryLevel < level && app.thread != null) { 15623 try { 15624 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15625 "Trimming memory of bg-ui " + app.processName 15626 + " to " + level); 15627 app.thread.scheduleTrimMemory(level); 15628 } catch (RemoteException e) { 15629 } 15630 } 15631 app.pendingUiClean = false; 15632 } 15633 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15634 try { 15635 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15636 "Trimming memory of fg " + app.processName 15637 + " to " + fgTrimLevel); 15638 app.thread.scheduleTrimMemory(fgTrimLevel); 15639 } catch (RemoteException e) { 15640 } 15641 } 15642 app.trimMemoryLevel = fgTrimLevel; 15643 } 15644 } 15645 } else { 15646 if (mLowRamStartTime != 0) { 15647 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15648 mLowRamStartTime = 0; 15649 } 15650 for (int i=N-1; i>=0; i--) { 15651 ProcessRecord app = mLruProcesses.get(i); 15652 if (allChanged || app.procStateChanged) { 15653 setProcessTrackerState(app, trackerMemFactor, now); 15654 app.procStateChanged = false; 15655 } 15656 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15657 || app.systemNoUi) && app.pendingUiClean) { 15658 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15659 && app.thread != null) { 15660 try { 15661 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15662 "Trimming memory of ui hidden " + app.processName 15663 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15664 app.thread.scheduleTrimMemory( 15665 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15666 } catch (RemoteException e) { 15667 } 15668 } 15669 app.pendingUiClean = false; 15670 } 15671 app.trimMemoryLevel = 0; 15672 } 15673 } 15674 15675 if (mAlwaysFinishActivities) { 15676 // Need to do this on its own message because the stack may not 15677 // be in a consistent state at this point. 15678 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15679 } 15680 15681 if (allChanged) { 15682 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15683 } 15684 15685 if (mProcessStats.shouldWriteNowLocked(now)) { 15686 mHandler.post(new Runnable() { 15687 @Override public void run() { 15688 synchronized (ActivityManagerService.this) { 15689 mProcessStats.writeStateAsyncLocked(); 15690 } 15691 } 15692 }); 15693 } 15694 15695 if (DEBUG_OOM_ADJ) { 15696 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15697 } 15698 } 15699 15700 final void trimApplications() { 15701 synchronized (this) { 15702 int i; 15703 15704 // First remove any unused application processes whose package 15705 // has been removed. 15706 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15707 final ProcessRecord app = mRemovedProcesses.get(i); 15708 if (app.activities.size() == 0 15709 && app.curReceiver == null && app.services.size() == 0) { 15710 Slog.i( 15711 TAG, "Exiting empty application process " 15712 + app.processName + " (" 15713 + (app.thread != null ? app.thread.asBinder() : null) 15714 + ")\n"); 15715 if (app.pid > 0 && app.pid != MY_PID) { 15716 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 15717 app.processName, app.setAdj, "empty"); 15718 app.killedByAm = true; 15719 Process.killProcessQuiet(app.pid); 15720 } else { 15721 try { 15722 app.thread.scheduleExit(); 15723 } catch (Exception e) { 15724 // Ignore exceptions. 15725 } 15726 } 15727 cleanUpApplicationRecordLocked(app, false, true, -1); 15728 mRemovedProcesses.remove(i); 15729 15730 if (app.persistent) { 15731 if (app.persistent) { 15732 addAppLocked(app.info, false); 15733 } 15734 } 15735 } 15736 } 15737 15738 // Now update the oom adj for all processes. 15739 updateOomAdjLocked(); 15740 } 15741 } 15742 15743 /** This method sends the specified signal to each of the persistent apps */ 15744 public void signalPersistentProcesses(int sig) throws RemoteException { 15745 if (sig != Process.SIGNAL_USR1) { 15746 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 15747 } 15748 15749 synchronized (this) { 15750 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 15751 != PackageManager.PERMISSION_GRANTED) { 15752 throw new SecurityException("Requires permission " 15753 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 15754 } 15755 15756 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15757 ProcessRecord r = mLruProcesses.get(i); 15758 if (r.thread != null && r.persistent) { 15759 Process.sendSignal(r.pid, sig); 15760 } 15761 } 15762 } 15763 } 15764 15765 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 15766 if (proc == null || proc == mProfileProc) { 15767 proc = mProfileProc; 15768 path = mProfileFile; 15769 profileType = mProfileType; 15770 clearProfilerLocked(); 15771 } 15772 if (proc == null) { 15773 return; 15774 } 15775 try { 15776 proc.thread.profilerControl(false, path, null, profileType); 15777 } catch (RemoteException e) { 15778 throw new IllegalStateException("Process disappeared"); 15779 } 15780 } 15781 15782 private void clearProfilerLocked() { 15783 if (mProfileFd != null) { 15784 try { 15785 mProfileFd.close(); 15786 } catch (IOException e) { 15787 } 15788 } 15789 mProfileApp = null; 15790 mProfileProc = null; 15791 mProfileFile = null; 15792 mProfileType = 0; 15793 mAutoStopProfiler = false; 15794 } 15795 15796 public boolean profileControl(String process, int userId, boolean start, 15797 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 15798 15799 try { 15800 synchronized (this) { 15801 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15802 // its own permission. 15803 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15804 != PackageManager.PERMISSION_GRANTED) { 15805 throw new SecurityException("Requires permission " 15806 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15807 } 15808 15809 if (start && fd == null) { 15810 throw new IllegalArgumentException("null fd"); 15811 } 15812 15813 ProcessRecord proc = null; 15814 if (process != null) { 15815 proc = findProcessLocked(process, userId, "profileControl"); 15816 } 15817 15818 if (start && (proc == null || proc.thread == null)) { 15819 throw new IllegalArgumentException("Unknown process: " + process); 15820 } 15821 15822 if (start) { 15823 stopProfilerLocked(null, null, 0); 15824 setProfileApp(proc.info, proc.processName, path, fd, false); 15825 mProfileProc = proc; 15826 mProfileType = profileType; 15827 try { 15828 fd = fd.dup(); 15829 } catch (IOException e) { 15830 fd = null; 15831 } 15832 proc.thread.profilerControl(start, path, fd, profileType); 15833 fd = null; 15834 mProfileFd = null; 15835 } else { 15836 stopProfilerLocked(proc, path, profileType); 15837 if (fd != null) { 15838 try { 15839 fd.close(); 15840 } catch (IOException e) { 15841 } 15842 } 15843 } 15844 15845 return true; 15846 } 15847 } catch (RemoteException e) { 15848 throw new IllegalStateException("Process disappeared"); 15849 } finally { 15850 if (fd != null) { 15851 try { 15852 fd.close(); 15853 } catch (IOException e) { 15854 } 15855 } 15856 } 15857 } 15858 15859 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 15860 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15861 userId, true, true, callName, null); 15862 ProcessRecord proc = null; 15863 try { 15864 int pid = Integer.parseInt(process); 15865 synchronized (mPidsSelfLocked) { 15866 proc = mPidsSelfLocked.get(pid); 15867 } 15868 } catch (NumberFormatException e) { 15869 } 15870 15871 if (proc == null) { 15872 ArrayMap<String, SparseArray<ProcessRecord>> all 15873 = mProcessNames.getMap(); 15874 SparseArray<ProcessRecord> procs = all.get(process); 15875 if (procs != null && procs.size() > 0) { 15876 proc = procs.valueAt(0); 15877 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 15878 for (int i=1; i<procs.size(); i++) { 15879 ProcessRecord thisProc = procs.valueAt(i); 15880 if (thisProc.userId == userId) { 15881 proc = thisProc; 15882 break; 15883 } 15884 } 15885 } 15886 } 15887 } 15888 15889 return proc; 15890 } 15891 15892 public boolean dumpHeap(String process, int userId, boolean managed, 15893 String path, ParcelFileDescriptor fd) throws RemoteException { 15894 15895 try { 15896 synchronized (this) { 15897 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15898 // its own permission (same as profileControl). 15899 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15900 != PackageManager.PERMISSION_GRANTED) { 15901 throw new SecurityException("Requires permission " 15902 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15903 } 15904 15905 if (fd == null) { 15906 throw new IllegalArgumentException("null fd"); 15907 } 15908 15909 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 15910 if (proc == null || proc.thread == null) { 15911 throw new IllegalArgumentException("Unknown process: " + process); 15912 } 15913 15914 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 15915 if (!isDebuggable) { 15916 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 15917 throw new SecurityException("Process not debuggable: " + proc); 15918 } 15919 } 15920 15921 proc.thread.dumpHeap(managed, path, fd); 15922 fd = null; 15923 return true; 15924 } 15925 } catch (RemoteException e) { 15926 throw new IllegalStateException("Process disappeared"); 15927 } finally { 15928 if (fd != null) { 15929 try { 15930 fd.close(); 15931 } catch (IOException e) { 15932 } 15933 } 15934 } 15935 } 15936 15937 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 15938 public void monitor() { 15939 synchronized (this) { } 15940 } 15941 15942 void onCoreSettingsChange(Bundle settings) { 15943 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 15944 ProcessRecord processRecord = mLruProcesses.get(i); 15945 try { 15946 if (processRecord.thread != null) { 15947 processRecord.thread.setCoreSettings(settings); 15948 } 15949 } catch (RemoteException re) { 15950 /* ignore */ 15951 } 15952 } 15953 } 15954 15955 // Multi-user methods 15956 15957 @Override 15958 public boolean switchUser(final int userId) { 15959 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 15960 != PackageManager.PERMISSION_GRANTED) { 15961 String msg = "Permission Denial: switchUser() from pid=" 15962 + Binder.getCallingPid() 15963 + ", uid=" + Binder.getCallingUid() 15964 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 15965 Slog.w(TAG, msg); 15966 throw new SecurityException(msg); 15967 } 15968 15969 final long ident = Binder.clearCallingIdentity(); 15970 try { 15971 synchronized (this) { 15972 final int oldUserId = mCurrentUserId; 15973 if (oldUserId == userId) { 15974 return true; 15975 } 15976 15977 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 15978 if (userInfo == null) { 15979 Slog.w(TAG, "No user info for user #" + userId); 15980 return false; 15981 } 15982 15983 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 15984 R.anim.screen_user_enter); 15985 15986 boolean needStart = false; 15987 15988 // If the user we are switching to is not currently started, then 15989 // we need to start it now. 15990 if (mStartedUsers.get(userId) == null) { 15991 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 15992 updateStartedUserArrayLocked(); 15993 needStart = true; 15994 } 15995 15996 mCurrentUserId = userId; 15997 final Integer userIdInt = Integer.valueOf(userId); 15998 mUserLru.remove(userIdInt); 15999 mUserLru.add(userIdInt); 16000 16001 mWindowManager.setCurrentUser(userId); 16002 16003 // Once the internal notion of the active user has switched, we lock the device 16004 // with the option to show the user switcher on the keyguard. 16005 mWindowManager.lockNow(null); 16006 16007 final UserStartedState uss = mStartedUsers.get(userId); 16008 16009 // Make sure user is in the started state. If it is currently 16010 // stopping, we need to knock that off. 16011 if (uss.mState == UserStartedState.STATE_STOPPING) { 16012 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16013 // so we can just fairly silently bring the user back from 16014 // the almost-dead. 16015 uss.mState = UserStartedState.STATE_RUNNING; 16016 updateStartedUserArrayLocked(); 16017 needStart = true; 16018 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16019 // This means ACTION_SHUTDOWN has been sent, so we will 16020 // need to treat this as a new boot of the user. 16021 uss.mState = UserStartedState.STATE_BOOTING; 16022 updateStartedUserArrayLocked(); 16023 needStart = true; 16024 } 16025 16026 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16027 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16028 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16029 oldUserId, userId, uss)); 16030 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16031 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16032 if (needStart) { 16033 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16034 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16035 | Intent.FLAG_RECEIVER_FOREGROUND); 16036 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16037 broadcastIntentLocked(null, null, intent, 16038 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16039 false, false, MY_PID, Process.SYSTEM_UID, userId); 16040 } 16041 16042 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16043 if (userId != 0) { 16044 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16045 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16046 broadcastIntentLocked(null, null, intent, null, 16047 new IIntentReceiver.Stub() { 16048 public void performReceive(Intent intent, int resultCode, 16049 String data, Bundle extras, boolean ordered, 16050 boolean sticky, int sendingUser) { 16051 userInitialized(uss, userId); 16052 } 16053 }, 0, null, null, null, AppOpsManager.OP_NONE, 16054 true, false, MY_PID, Process.SYSTEM_UID, 16055 userId); 16056 uss.initializing = true; 16057 } else { 16058 getUserManagerLocked().makeInitialized(userInfo.id); 16059 } 16060 } 16061 16062 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16063 if (homeInFront) { 16064 startHomeActivityLocked(userId); 16065 } else { 16066 mStackSupervisor.resumeTopActivitiesLocked(); 16067 } 16068 16069 EventLogTags.writeAmSwitchUser(userId); 16070 getUserManagerLocked().userForeground(userId); 16071 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16072 if (needStart) { 16073 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16074 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16075 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16076 broadcastIntentLocked(null, null, intent, 16077 null, new IIntentReceiver.Stub() { 16078 @Override 16079 public void performReceive(Intent intent, int resultCode, String data, 16080 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16081 throws RemoteException { 16082 } 16083 }, 0, null, null, 16084 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16085 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16086 } 16087 } 16088 } finally { 16089 Binder.restoreCallingIdentity(ident); 16090 } 16091 16092 return true; 16093 } 16094 16095 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16096 long ident = Binder.clearCallingIdentity(); 16097 try { 16098 Intent intent; 16099 if (oldUserId >= 0) { 16100 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16101 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16102 | Intent.FLAG_RECEIVER_FOREGROUND); 16103 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16104 broadcastIntentLocked(null, null, intent, 16105 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16106 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16107 } 16108 if (newUserId >= 0) { 16109 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16110 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16111 | Intent.FLAG_RECEIVER_FOREGROUND); 16112 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16113 broadcastIntentLocked(null, null, intent, 16114 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16115 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16116 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16117 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16118 | Intent.FLAG_RECEIVER_FOREGROUND); 16119 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16120 broadcastIntentLocked(null, null, intent, 16121 null, null, 0, null, null, 16122 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16123 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16124 } 16125 } finally { 16126 Binder.restoreCallingIdentity(ident); 16127 } 16128 } 16129 16130 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16131 final int newUserId) { 16132 final int N = mUserSwitchObservers.beginBroadcast(); 16133 if (N > 0) { 16134 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16135 int mCount = 0; 16136 @Override 16137 public void sendResult(Bundle data) throws RemoteException { 16138 synchronized (ActivityManagerService.this) { 16139 if (mCurUserSwitchCallback == this) { 16140 mCount++; 16141 if (mCount == N) { 16142 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16143 } 16144 } 16145 } 16146 } 16147 }; 16148 synchronized (this) { 16149 uss.switching = true; 16150 mCurUserSwitchCallback = callback; 16151 } 16152 for (int i=0; i<N; i++) { 16153 try { 16154 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16155 newUserId, callback); 16156 } catch (RemoteException e) { 16157 } 16158 } 16159 } else { 16160 synchronized (this) { 16161 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16162 } 16163 } 16164 mUserSwitchObservers.finishBroadcast(); 16165 } 16166 16167 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16168 synchronized (this) { 16169 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16170 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16171 } 16172 } 16173 16174 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16175 mCurUserSwitchCallback = null; 16176 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16177 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16178 oldUserId, newUserId, uss)); 16179 } 16180 16181 void userInitialized(UserStartedState uss, int newUserId) { 16182 completeSwitchAndInitalize(uss, newUserId, true, false); 16183 } 16184 16185 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16186 completeSwitchAndInitalize(uss, newUserId, false, true); 16187 } 16188 16189 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16190 boolean clearInitializing, boolean clearSwitching) { 16191 boolean unfrozen = false; 16192 synchronized (this) { 16193 if (clearInitializing) { 16194 uss.initializing = false; 16195 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16196 } 16197 if (clearSwitching) { 16198 uss.switching = false; 16199 } 16200 if (!uss.switching && !uss.initializing) { 16201 mWindowManager.stopFreezingScreen(); 16202 unfrozen = true; 16203 } 16204 } 16205 if (unfrozen) { 16206 final int N = mUserSwitchObservers.beginBroadcast(); 16207 for (int i=0; i<N; i++) { 16208 try { 16209 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16210 } catch (RemoteException e) { 16211 } 16212 } 16213 mUserSwitchObservers.finishBroadcast(); 16214 } 16215 } 16216 16217 void finishUserSwitch(UserStartedState uss) { 16218 synchronized (this) { 16219 if (uss.mState == UserStartedState.STATE_BOOTING 16220 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16221 uss.mState = UserStartedState.STATE_RUNNING; 16222 final int userId = uss.mHandle.getIdentifier(); 16223 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16224 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16225 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16226 broadcastIntentLocked(null, null, intent, 16227 null, null, 0, null, null, 16228 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16229 true, false, MY_PID, Process.SYSTEM_UID, userId); 16230 } 16231 int num = mUserLru.size(); 16232 int i = 0; 16233 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16234 Integer oldUserId = mUserLru.get(i); 16235 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16236 if (oldUss == null) { 16237 // Shouldn't happen, but be sane if it does. 16238 mUserLru.remove(i); 16239 num--; 16240 continue; 16241 } 16242 if (oldUss.mState == UserStartedState.STATE_STOPPING 16243 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16244 // This user is already stopping, doesn't count. 16245 num--; 16246 i++; 16247 continue; 16248 } 16249 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16250 // Owner and current can't be stopped, but count as running. 16251 i++; 16252 continue; 16253 } 16254 // This is a user to be stopped. 16255 stopUserLocked(oldUserId, null); 16256 num--; 16257 i++; 16258 } 16259 } 16260 } 16261 16262 @Override 16263 public int stopUser(final int userId, final IStopUserCallback callback) { 16264 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16265 != PackageManager.PERMISSION_GRANTED) { 16266 String msg = "Permission Denial: switchUser() from pid=" 16267 + Binder.getCallingPid() 16268 + ", uid=" + Binder.getCallingUid() 16269 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16270 Slog.w(TAG, msg); 16271 throw new SecurityException(msg); 16272 } 16273 if (userId <= 0) { 16274 throw new IllegalArgumentException("Can't stop primary user " + userId); 16275 } 16276 synchronized (this) { 16277 return stopUserLocked(userId, callback); 16278 } 16279 } 16280 16281 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16282 if (mCurrentUserId == userId) { 16283 return ActivityManager.USER_OP_IS_CURRENT; 16284 } 16285 16286 final UserStartedState uss = mStartedUsers.get(userId); 16287 if (uss == null) { 16288 // User is not started, nothing to do... but we do need to 16289 // callback if requested. 16290 if (callback != null) { 16291 mHandler.post(new Runnable() { 16292 @Override 16293 public void run() { 16294 try { 16295 callback.userStopped(userId); 16296 } catch (RemoteException e) { 16297 } 16298 } 16299 }); 16300 } 16301 return ActivityManager.USER_OP_SUCCESS; 16302 } 16303 16304 if (callback != null) { 16305 uss.mStopCallbacks.add(callback); 16306 } 16307 16308 if (uss.mState != UserStartedState.STATE_STOPPING 16309 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16310 uss.mState = UserStartedState.STATE_STOPPING; 16311 updateStartedUserArrayLocked(); 16312 16313 long ident = Binder.clearCallingIdentity(); 16314 try { 16315 // We are going to broadcast ACTION_USER_STOPPING and then 16316 // once that is done send a final ACTION_SHUTDOWN and then 16317 // stop the user. 16318 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16319 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16320 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16321 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16322 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16323 // This is the result receiver for the final shutdown broadcast. 16324 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16325 @Override 16326 public void performReceive(Intent intent, int resultCode, String data, 16327 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16328 finishUserStop(uss); 16329 } 16330 }; 16331 // This is the result receiver for the initial stopping broadcast. 16332 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16333 @Override 16334 public void performReceive(Intent intent, int resultCode, String data, 16335 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16336 // On to the next. 16337 synchronized (ActivityManagerService.this) { 16338 if (uss.mState != UserStartedState.STATE_STOPPING) { 16339 // Whoops, we are being started back up. Abort, abort! 16340 return; 16341 } 16342 uss.mState = UserStartedState.STATE_SHUTDOWN; 16343 } 16344 broadcastIntentLocked(null, null, shutdownIntent, 16345 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16346 true, false, MY_PID, Process.SYSTEM_UID, userId); 16347 } 16348 }; 16349 // Kick things off. 16350 broadcastIntentLocked(null, null, stoppingIntent, 16351 null, stoppingReceiver, 0, null, null, 16352 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16353 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16354 } finally { 16355 Binder.restoreCallingIdentity(ident); 16356 } 16357 } 16358 16359 return ActivityManager.USER_OP_SUCCESS; 16360 } 16361 16362 void finishUserStop(UserStartedState uss) { 16363 final int userId = uss.mHandle.getIdentifier(); 16364 boolean stopped; 16365 ArrayList<IStopUserCallback> callbacks; 16366 synchronized (this) { 16367 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16368 if (mStartedUsers.get(userId) != uss) { 16369 stopped = false; 16370 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16371 stopped = false; 16372 } else { 16373 stopped = true; 16374 // User can no longer run. 16375 mStartedUsers.remove(userId); 16376 mUserLru.remove(Integer.valueOf(userId)); 16377 updateStartedUserArrayLocked(); 16378 16379 // Clean up all state and processes associated with the user. 16380 // Kill all the processes for the user. 16381 forceStopUserLocked(userId, "finish user"); 16382 } 16383 } 16384 16385 for (int i=0; i<callbacks.size(); i++) { 16386 try { 16387 if (stopped) callbacks.get(i).userStopped(userId); 16388 else callbacks.get(i).userStopAborted(userId); 16389 } catch (RemoteException e) { 16390 } 16391 } 16392 16393 mStackSupervisor.removeUserLocked(userId); 16394 } 16395 16396 @Override 16397 public UserInfo getCurrentUser() { 16398 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16399 != PackageManager.PERMISSION_GRANTED) && ( 16400 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16401 != PackageManager.PERMISSION_GRANTED)) { 16402 String msg = "Permission Denial: getCurrentUser() from pid=" 16403 + Binder.getCallingPid() 16404 + ", uid=" + Binder.getCallingUid() 16405 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16406 Slog.w(TAG, msg); 16407 throw new SecurityException(msg); 16408 } 16409 synchronized (this) { 16410 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16411 } 16412 } 16413 16414 int getCurrentUserIdLocked() { 16415 return mCurrentUserId; 16416 } 16417 16418 @Override 16419 public boolean isUserRunning(int userId, boolean orStopped) { 16420 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16421 != PackageManager.PERMISSION_GRANTED) { 16422 String msg = "Permission Denial: isUserRunning() from pid=" 16423 + Binder.getCallingPid() 16424 + ", uid=" + Binder.getCallingUid() 16425 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16426 Slog.w(TAG, msg); 16427 throw new SecurityException(msg); 16428 } 16429 synchronized (this) { 16430 return isUserRunningLocked(userId, orStopped); 16431 } 16432 } 16433 16434 boolean isUserRunningLocked(int userId, boolean orStopped) { 16435 UserStartedState state = mStartedUsers.get(userId); 16436 if (state == null) { 16437 return false; 16438 } 16439 if (orStopped) { 16440 return true; 16441 } 16442 return state.mState != UserStartedState.STATE_STOPPING 16443 && state.mState != UserStartedState.STATE_SHUTDOWN; 16444 } 16445 16446 @Override 16447 public int[] getRunningUserIds() { 16448 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16449 != PackageManager.PERMISSION_GRANTED) { 16450 String msg = "Permission Denial: isUserRunning() from pid=" 16451 + Binder.getCallingPid() 16452 + ", uid=" + Binder.getCallingUid() 16453 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16454 Slog.w(TAG, msg); 16455 throw new SecurityException(msg); 16456 } 16457 synchronized (this) { 16458 return mStartedUserArray; 16459 } 16460 } 16461 16462 private void updateStartedUserArrayLocked() { 16463 int num = 0; 16464 for (int i=0; i<mStartedUsers.size(); i++) { 16465 UserStartedState uss = mStartedUsers.valueAt(i); 16466 // This list does not include stopping users. 16467 if (uss.mState != UserStartedState.STATE_STOPPING 16468 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16469 num++; 16470 } 16471 } 16472 mStartedUserArray = new int[num]; 16473 num = 0; 16474 for (int i=0; i<mStartedUsers.size(); i++) { 16475 UserStartedState uss = mStartedUsers.valueAt(i); 16476 if (uss.mState != UserStartedState.STATE_STOPPING 16477 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16478 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16479 num++; 16480 } 16481 } 16482 } 16483 16484 @Override 16485 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16486 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16487 != PackageManager.PERMISSION_GRANTED) { 16488 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16489 + Binder.getCallingPid() 16490 + ", uid=" + Binder.getCallingUid() 16491 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16492 Slog.w(TAG, msg); 16493 throw new SecurityException(msg); 16494 } 16495 16496 mUserSwitchObservers.register(observer); 16497 } 16498 16499 @Override 16500 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16501 mUserSwitchObservers.unregister(observer); 16502 } 16503 16504 private boolean userExists(int userId) { 16505 if (userId == 0) { 16506 return true; 16507 } 16508 UserManagerService ums = getUserManagerLocked(); 16509 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16510 } 16511 16512 int[] getUsersLocked() { 16513 UserManagerService ums = getUserManagerLocked(); 16514 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16515 } 16516 16517 UserManagerService getUserManagerLocked() { 16518 if (mUserManager == null) { 16519 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16520 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16521 } 16522 return mUserManager; 16523 } 16524 16525 private int applyUserId(int uid, int userId) { 16526 return UserHandle.getUid(userId, uid); 16527 } 16528 16529 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16530 if (info == null) return null; 16531 ApplicationInfo newInfo = new ApplicationInfo(info); 16532 newInfo.uid = applyUserId(info.uid, userId); 16533 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16534 + info.packageName; 16535 return newInfo; 16536 } 16537 16538 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16539 if (aInfo == null 16540 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16541 return aInfo; 16542 } 16543 16544 ActivityInfo info = new ActivityInfo(aInfo); 16545 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16546 return info; 16547 } 16548} 16549