ActivityManagerService.java revision 41aa48beacc93a1511a290e91293402eeb787165
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; 27import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 28 29import android.app.AppOpsManager; 30import android.app.IActivityContainer; 31import android.app.IActivityContainerCallback; 32import android.appwidget.AppWidgetManager; 33import android.graphics.Rect; 34import android.util.ArrayMap; 35 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.os.Zygote; 46import com.android.internal.util.FastPrintWriter; 47import com.android.internal.util.FastXmlSerializer; 48import com.android.internal.util.MemInfoReader; 49import com.android.internal.util.Preconditions; 50import com.android.server.AppOpsService; 51import com.android.server.AttributeCache; 52import com.android.server.IntentResolver; 53import com.android.server.LocalServices; 54import com.android.server.ServiceThread; 55import com.android.server.SystemService; 56import com.android.server.Watchdog; 57import com.android.server.am.ActivityStack.ActivityState; 58import com.android.server.firewall.IntentFirewall; 59import com.android.server.pm.UserManagerService; 60import com.android.server.wm.AppTransition; 61import com.android.server.wm.WindowManagerService; 62import com.google.android.collect.Lists; 63import com.google.android.collect.Maps; 64 65import libcore.io.IoUtils; 66 67import org.xmlpull.v1.XmlPullParser; 68import org.xmlpull.v1.XmlPullParserException; 69import org.xmlpull.v1.XmlSerializer; 70 71import android.app.Activity; 72import android.app.ActivityManager; 73import android.app.ActivityManager.RunningTaskInfo; 74import android.app.ActivityManager.StackInfo; 75import android.app.ActivityManagerInternal; 76import android.app.ActivityManagerNative; 77import android.app.ActivityOptions; 78import android.app.ActivityThread; 79import android.app.AlertDialog; 80import android.app.AppGlobals; 81import android.app.ApplicationErrorReport; 82import android.app.Dialog; 83import android.app.IActivityController; 84import android.app.IApplicationThread; 85import android.app.IInstrumentationWatcher; 86import android.app.INotificationManager; 87import android.app.IProcessObserver; 88import android.app.IServiceConnection; 89import android.app.IStopUserCallback; 90import android.app.IThumbnailReceiver; 91import android.app.IUiAutomationConnection; 92import android.app.IUserSwitchObserver; 93import android.app.Instrumentation; 94import android.app.Notification; 95import android.app.NotificationManager; 96import android.app.PendingIntent; 97import android.app.backup.IBackupManager; 98import android.content.ActivityNotFoundException; 99import android.content.BroadcastReceiver; 100import android.content.ClipData; 101import android.content.ComponentCallbacks2; 102import android.content.ComponentName; 103import android.content.ContentProvider; 104import android.content.ContentResolver; 105import android.content.Context; 106import android.content.DialogInterface; 107import android.content.IContentProvider; 108import android.content.IIntentReceiver; 109import android.content.IIntentSender; 110import android.content.Intent; 111import android.content.IntentFilter; 112import android.content.IntentSender; 113import android.content.pm.ActivityInfo; 114import android.content.pm.ApplicationInfo; 115import android.content.pm.ConfigurationInfo; 116import android.content.pm.IPackageDataObserver; 117import android.content.pm.IPackageManager; 118import android.content.pm.InstrumentationInfo; 119import android.content.pm.PackageInfo; 120import android.content.pm.PackageManager; 121import android.content.pm.ParceledListSlice; 122import android.content.pm.UserInfo; 123import android.content.pm.PackageManager.NameNotFoundException; 124import android.content.pm.PathPermission; 125import android.content.pm.ProviderInfo; 126import android.content.pm.ResolveInfo; 127import android.content.pm.ServiceInfo; 128import android.content.res.CompatibilityInfo; 129import android.content.res.Configuration; 130import android.graphics.Bitmap; 131import android.net.Proxy; 132import android.net.ProxyProperties; 133import android.net.Uri; 134import android.os.Binder; 135import android.os.Build; 136import android.os.Bundle; 137import android.os.Debug; 138import android.os.DropBoxManager; 139import android.os.Environment; 140import android.os.FactoryTest; 141import android.os.FileObserver; 142import android.os.FileUtils; 143import android.os.Handler; 144import android.os.IBinder; 145import android.os.IPermissionController; 146import android.os.IRemoteCallback; 147import android.os.IUserManager; 148import android.os.Looper; 149import android.os.Message; 150import android.os.Parcel; 151import android.os.ParcelFileDescriptor; 152import android.os.Process; 153import android.os.RemoteCallbackList; 154import android.os.RemoteException; 155import android.os.SELinux; 156import android.os.ServiceManager; 157import android.os.StrictMode; 158import android.os.SystemClock; 159import android.os.SystemProperties; 160import android.os.UpdateLock; 161import android.os.UserHandle; 162import android.provider.Settings; 163import android.text.format.DateUtils; 164import android.text.format.Time; 165import android.util.AtomicFile; 166import android.util.EventLog; 167import android.util.Log; 168import android.util.Pair; 169import android.util.PrintWriterPrinter; 170import android.util.Slog; 171import android.util.SparseArray; 172import android.util.TimeUtils; 173import android.util.Xml; 174import android.view.Gravity; 175import android.view.LayoutInflater; 176import android.view.View; 177import android.view.WindowManager; 178 179import java.io.BufferedInputStream; 180import java.io.BufferedOutputStream; 181import java.io.DataInputStream; 182import java.io.DataOutputStream; 183import java.io.File; 184import java.io.FileDescriptor; 185import java.io.FileInputStream; 186import java.io.FileNotFoundException; 187import java.io.FileOutputStream; 188import java.io.IOException; 189import java.io.InputStreamReader; 190import java.io.PrintWriter; 191import java.io.StringWriter; 192import java.lang.ref.WeakReference; 193import java.util.ArrayList; 194import java.util.Arrays; 195import java.util.Collections; 196import java.util.Comparator; 197import java.util.HashMap; 198import java.util.HashSet; 199import java.util.Iterator; 200import java.util.List; 201import java.util.Locale; 202import java.util.Map; 203import java.util.Set; 204import java.util.concurrent.atomic.AtomicBoolean; 205import java.util.concurrent.atomic.AtomicLong; 206 207public final class ActivityManagerService extends ActivityManagerNative 208 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 209 private static final String USER_DATA_DIR = "/data/user/"; 210 static final String TAG = "ActivityManager"; 211 static final String TAG_MU = "ActivityManagerServiceMU"; 212 static final boolean DEBUG = false; 213 static final boolean localLOGV = DEBUG; 214 static final boolean DEBUG_BACKUP = localLOGV || false; 215 static final boolean DEBUG_BROADCAST = localLOGV || false; 216 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 217 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 218 static final boolean DEBUG_CLEANUP = localLOGV || false; 219 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 220 static final boolean DEBUG_FOCUS = false; 221 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 222 static final boolean DEBUG_MU = localLOGV || false; 223 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 224 static final boolean DEBUG_LRU = localLOGV || false; 225 static final boolean DEBUG_PAUSE = localLOGV || false; 226 static final boolean DEBUG_POWER = localLOGV || false; 227 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 228 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 229 static final boolean DEBUG_PROCESSES = localLOGV || false; 230 static final boolean DEBUG_PROVIDER = localLOGV || false; 231 static final boolean DEBUG_RESULTS = localLOGV || false; 232 static final boolean DEBUG_SERVICE = localLOGV || false; 233 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 234 static final boolean DEBUG_STACK = localLOGV || false; 235 static final boolean DEBUG_SWITCH = localLOGV || false; 236 static final boolean DEBUG_TASKS = localLOGV || false; 237 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 238 static final boolean DEBUG_TRANSITION = localLOGV || false; 239 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 240 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 241 static final boolean DEBUG_VISBILITY = localLOGV || false; 242 static final boolean DEBUG_PSS = localLOGV || false; 243 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 244 static final boolean VALIDATE_TOKENS = false; 245 static final boolean SHOW_ACTIVITY_START_TIME = true; 246 247 // Control over CPU and battery monitoring. 248 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 249 static final boolean MONITOR_CPU_USAGE = true; 250 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 251 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 252 static final boolean MONITOR_THREAD_CPU_USAGE = false; 253 254 // The flags that are set for all calls we make to the package manager. 255 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 256 257 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 258 259 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 260 261 // Maximum number of recent tasks that we can remember. 262 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 263 264 // Amount of time after a call to stopAppSwitches() during which we will 265 // prevent further untrusted switches from happening. 266 static final long APP_SWITCH_DELAY_TIME = 5*1000; 267 268 // How long we wait for a launched process to attach to the activity manager 269 // before we decide it's never going to come up for real. 270 static final int PROC_START_TIMEOUT = 10*1000; 271 272 // How long we wait for a launched process to attach to the activity manager 273 // before we decide it's never going to come up for real, when the process was 274 // started with a wrapper for instrumentation (such as Valgrind) because it 275 // could take much longer than usual. 276 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 277 278 // How long to wait after going idle before forcing apps to GC. 279 static final int GC_TIMEOUT = 5*1000; 280 281 // The minimum amount of time between successive GC requests for a process. 282 static final int GC_MIN_INTERVAL = 60*1000; 283 284 // The minimum amount of time between successive PSS requests for a process. 285 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 286 287 // The minimum amount of time between successive PSS requests for a process 288 // when the request is due to the memory state being lowered. 289 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 290 291 // The rate at which we check for apps using excessive power -- 15 mins. 292 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 293 294 // The minimum sample duration we will allow before deciding we have 295 // enough data on wake locks to start killing things. 296 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 297 298 // The minimum sample duration we will allow before deciding we have 299 // enough data on CPU usage to start killing things. 300 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 301 302 // How long we allow a receiver to run before giving up on it. 303 static final int BROADCAST_FG_TIMEOUT = 10*1000; 304 static final int BROADCAST_BG_TIMEOUT = 60*1000; 305 306 // How long we wait until we timeout on key dispatching. 307 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 308 309 // How long we wait until we timeout on key dispatching during instrumentation. 310 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 311 312 // Amount of time we wait for observers to handle a user switch before 313 // giving up on them and unfreezing the screen. 314 static final int USER_SWITCH_TIMEOUT = 2*1000; 315 316 // Maximum number of users we allow to be running at a time. 317 static final int MAX_RUNNING_USERS = 3; 318 319 // How long to wait in getAssistContextExtras for the activity and foreground services 320 // to respond with the result. 321 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 322 323 // Maximum number of persisted Uri grants a package is allowed 324 static final int MAX_PERSISTED_URI_GRANTS = 128; 325 326 static final int MY_PID = Process.myPid(); 327 328 static final String[] EMPTY_STRING_ARRAY = new String[0]; 329 330 // How many bytes to write into the dropbox log before truncating 331 static final int DROPBOX_MAX_SIZE = 256 * 1024; 332 333 /** Run all ActivityStacks through this */ 334 ActivityStackSupervisor mStackSupervisor; 335 336 public IntentFirewall mIntentFirewall; 337 338 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 339 // default actuion automatically. Important for devices without direct input 340 // devices. 341 private boolean mShowDialogs = true; 342 343 /** 344 * Description of a request to start a new activity, which has been held 345 * due to app switches being disabled. 346 */ 347 static class PendingActivityLaunch { 348 final ActivityRecord r; 349 final ActivityRecord sourceRecord; 350 final int startFlags; 351 final ActivityStack stack; 352 353 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 354 int _startFlags, ActivityStack _stack) { 355 r = _r; 356 sourceRecord = _sourceRecord; 357 startFlags = _startFlags; 358 stack = _stack; 359 } 360 } 361 362 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 363 = new ArrayList<PendingActivityLaunch>(); 364 365 BroadcastQueue mFgBroadcastQueue; 366 BroadcastQueue mBgBroadcastQueue; 367 // Convenient for easy iteration over the queues. Foreground is first 368 // so that dispatch of foreground broadcasts gets precedence. 369 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 370 371 BroadcastQueue broadcastQueueForIntent(Intent intent) { 372 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 373 if (DEBUG_BACKGROUND_BROADCAST) { 374 Slog.i(TAG, "Broadcast intent " + intent + " on " 375 + (isFg ? "foreground" : "background") 376 + " queue"); 377 } 378 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 379 } 380 381 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 382 for (BroadcastQueue queue : mBroadcastQueues) { 383 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 384 if (r != null) { 385 return r; 386 } 387 } 388 return null; 389 } 390 391 /** 392 * Activity we have told the window manager to have key focus. 393 */ 394 ActivityRecord mFocusedActivity = null; 395 396 /** 397 * List of intents that were used to start the most recent tasks. 398 */ 399 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 400 401 public class PendingAssistExtras extends Binder implements Runnable { 402 public final ActivityRecord activity; 403 public boolean haveResult = false; 404 public Bundle result = null; 405 public PendingAssistExtras(ActivityRecord _activity) { 406 activity = _activity; 407 } 408 @Override 409 public void run() { 410 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 411 synchronized (this) { 412 haveResult = true; 413 notifyAll(); 414 } 415 } 416 } 417 418 final ArrayList<PendingAssistExtras> mPendingAssistExtras 419 = new ArrayList<PendingAssistExtras>(); 420 421 /** 422 * Process management. 423 */ 424 final ProcessList mProcessList = new ProcessList(); 425 426 /** 427 * All of the applications we currently have running organized by name. 428 * The keys are strings of the application package name (as 429 * returned by the package manager), and the keys are ApplicationRecord 430 * objects. 431 */ 432 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 433 434 /** 435 * Tracking long-term execution of processes to look for abuse and other 436 * bad app behavior. 437 */ 438 final ProcessStatsService mProcessStats; 439 440 /** 441 * The currently running isolated processes. 442 */ 443 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 444 445 /** 446 * Counter for assigning isolated process uids, to avoid frequently reusing the 447 * same ones. 448 */ 449 int mNextIsolatedProcessUid = 0; 450 451 /** 452 * The currently running heavy-weight process, if any. 453 */ 454 ProcessRecord mHeavyWeightProcess = null; 455 456 /** 457 * The last time that various processes have crashed. 458 */ 459 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 460 461 /** 462 * Information about a process that is currently marked as bad. 463 */ 464 static final class BadProcessInfo { 465 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 466 this.time = time; 467 this.shortMsg = shortMsg; 468 this.longMsg = longMsg; 469 this.stack = stack; 470 } 471 472 final long time; 473 final String shortMsg; 474 final String longMsg; 475 final String stack; 476 } 477 478 /** 479 * Set of applications that we consider to be bad, and will reject 480 * incoming broadcasts from (which the user has no control over). 481 * Processes are added to this set when they have crashed twice within 482 * a minimum amount of time; they are removed from it when they are 483 * later restarted (hopefully due to some user action). The value is the 484 * time it was added to the list. 485 */ 486 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 487 488 /** 489 * All of the processes we currently have running organized by pid. 490 * The keys are the pid running the application. 491 * 492 * <p>NOTE: This object is protected by its own lock, NOT the global 493 * activity manager lock! 494 */ 495 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 496 497 /** 498 * All of the processes that have been forced to be foreground. The key 499 * is the pid of the caller who requested it (we hold a death 500 * link on it). 501 */ 502 abstract class ForegroundToken implements IBinder.DeathRecipient { 503 int pid; 504 IBinder token; 505 } 506 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 507 508 /** 509 * List of records for processes that someone had tried to start before the 510 * system was ready. We don't start them at that point, but ensure they 511 * are started by the time booting is complete. 512 */ 513 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 514 515 /** 516 * List of persistent applications that are in the process 517 * of being started. 518 */ 519 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 520 521 /** 522 * Processes that are being forcibly torn down. 523 */ 524 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 525 526 /** 527 * List of running applications, sorted by recent usage. 528 * The first entry in the list is the least recently used. 529 */ 530 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 531 532 /** 533 * Where in mLruProcesses that the processes hosting activities start. 534 */ 535 int mLruProcessActivityStart = 0; 536 537 /** 538 * Where in mLruProcesses that the processes hosting services start. 539 * This is after (lower index) than mLruProcessesActivityStart. 540 */ 541 int mLruProcessServiceStart = 0; 542 543 /** 544 * List of processes that should gc as soon as things are idle. 545 */ 546 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 547 548 /** 549 * Processes we want to collect PSS data from. 550 */ 551 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 552 553 /** 554 * Last time we requested PSS data of all processes. 555 */ 556 long mLastFullPssTime = SystemClock.uptimeMillis(); 557 558 /** 559 * This is the process holding what we currently consider to be 560 * the "home" activity. 561 */ 562 ProcessRecord mHomeProcess; 563 564 /** 565 * This is the process holding the activity the user last visited that 566 * is in a different process from the one they are currently in. 567 */ 568 ProcessRecord mPreviousProcess; 569 570 /** 571 * The time at which the previous process was last visible. 572 */ 573 long mPreviousProcessVisibleTime; 574 575 /** 576 * Which uses have been started, so are allowed to run code. 577 */ 578 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 579 580 /** 581 * LRU list of history of current users. Most recently current is at the end. 582 */ 583 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 584 585 /** 586 * Constant array of the users that are currently started. 587 */ 588 int[] mStartedUserArray = new int[] { 0 }; 589 590 /** 591 * Registered observers of the user switching mechanics. 592 */ 593 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 594 = new RemoteCallbackList<IUserSwitchObserver>(); 595 596 /** 597 * Currently active user switch. 598 */ 599 Object mCurUserSwitchCallback; 600 601 /** 602 * Packages that the user has asked to have run in screen size 603 * compatibility mode instead of filling the screen. 604 */ 605 final CompatModePackages mCompatModePackages; 606 607 /** 608 * Set of IntentSenderRecord objects that are currently active. 609 */ 610 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 611 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 612 613 /** 614 * Fingerprints (hashCode()) of stack traces that we've 615 * already logged DropBox entries for. Guarded by itself. If 616 * something (rogue user app) forces this over 617 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 618 */ 619 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 620 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 621 622 /** 623 * Strict Mode background batched logging state. 624 * 625 * The string buffer is guarded by itself, and its lock is also 626 * used to determine if another batched write is already 627 * in-flight. 628 */ 629 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 630 631 /** 632 * Keeps track of all IIntentReceivers that have been registered for 633 * broadcasts. Hash keys are the receiver IBinder, hash value is 634 * a ReceiverList. 635 */ 636 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 637 new HashMap<IBinder, ReceiverList>(); 638 639 /** 640 * Resolver for broadcast intents to registered receivers. 641 * Holds BroadcastFilter (subclass of IntentFilter). 642 */ 643 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 644 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 645 @Override 646 protected boolean allowFilterResult( 647 BroadcastFilter filter, List<BroadcastFilter> dest) { 648 IBinder target = filter.receiverList.receiver.asBinder(); 649 for (int i=dest.size()-1; i>=0; i--) { 650 if (dest.get(i).receiverList.receiver.asBinder() == target) { 651 return false; 652 } 653 } 654 return true; 655 } 656 657 @Override 658 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 659 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 660 || userId == filter.owningUserId) { 661 return super.newResult(filter, match, userId); 662 } 663 return null; 664 } 665 666 @Override 667 protected BroadcastFilter[] newArray(int size) { 668 return new BroadcastFilter[size]; 669 } 670 671 @Override 672 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 673 return packageName.equals(filter.packageName); 674 } 675 }; 676 677 /** 678 * State of all active sticky broadcasts per user. Keys are the action of the 679 * sticky Intent, values are an ArrayList of all broadcasted intents with 680 * that action (which should usually be one). The SparseArray is keyed 681 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 682 * for stickies that are sent to all users. 683 */ 684 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 685 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 686 687 final ActiveServices mServices; 688 689 /** 690 * Backup/restore process management 691 */ 692 String mBackupAppName = null; 693 BackupRecord mBackupTarget = null; 694 695 /** 696 * List of PendingThumbnailsRecord objects of clients who are still 697 * waiting to receive all of the thumbnails for a task. 698 */ 699 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 700 new ArrayList<PendingThumbnailsRecord>(); 701 702 final ProviderMap mProviderMap; 703 704 /** 705 * List of content providers who have clients waiting for them. The 706 * application is currently being launched and the provider will be 707 * removed from this list once it is published. 708 */ 709 final ArrayList<ContentProviderRecord> mLaunchingProviders 710 = new ArrayList<ContentProviderRecord>(); 711 712 /** 713 * File storing persisted {@link #mGrantedUriPermissions}. 714 */ 715 private final AtomicFile mGrantFile; 716 717 /** XML constants used in {@link #mGrantFile} */ 718 private static final String TAG_URI_GRANTS = "uri-grants"; 719 private static final String TAG_URI_GRANT = "uri-grant"; 720 private static final String ATTR_USER_HANDLE = "userHandle"; 721 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 722 private static final String ATTR_TARGET_PKG = "targetPkg"; 723 private static final String ATTR_URI = "uri"; 724 private static final String ATTR_MODE_FLAGS = "modeFlags"; 725 private static final String ATTR_CREATED_TIME = "createdTime"; 726 727 /** 728 * Global set of specific {@link Uri} permissions that have been granted. 729 * This optimized lookup structure maps from {@link UriPermission#targetUid} 730 * to {@link UriPermission#uri} to {@link UriPermission}. 731 */ 732 @GuardedBy("this") 733 private final SparseArray<ArrayMap<Uri, UriPermission>> 734 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 735 736 CoreSettingsObserver mCoreSettingsObserver; 737 738 /** 739 * Thread-local storage used to carry caller permissions over through 740 * indirect content-provider access. 741 */ 742 private class Identity { 743 public int pid; 744 public int uid; 745 746 Identity(int _pid, int _uid) { 747 pid = _pid; 748 uid = _uid; 749 } 750 } 751 752 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 753 754 /** 755 * All information we have collected about the runtime performance of 756 * any user id that can impact battery performance. 757 */ 758 final BatteryStatsService mBatteryStatsService; 759 760 /** 761 * Information about component usage 762 */ 763 final UsageStatsService mUsageStatsService; 764 765 /** 766 * Information about and control over application operations 767 */ 768 final AppOpsService mAppOpsService; 769 770 /** 771 * Current configuration information. HistoryRecord objects are given 772 * a reference to this object to indicate which configuration they are 773 * currently running in, so this object must be kept immutable. 774 */ 775 Configuration mConfiguration = new Configuration(); 776 777 /** 778 * Current sequencing integer of the configuration, for skipping old 779 * configurations. 780 */ 781 int mConfigurationSeq = 0; 782 783 /** 784 * Hardware-reported OpenGLES version. 785 */ 786 final int GL_ES_VERSION; 787 788 /** 789 * List of initialization arguments to pass to all processes when binding applications to them. 790 * For example, references to the commonly used services. 791 */ 792 HashMap<String, IBinder> mAppBindArgs; 793 794 /** 795 * Temporary to avoid allocations. Protected by main lock. 796 */ 797 final StringBuilder mStringBuilder = new StringBuilder(256); 798 799 /** 800 * Used to control how we initialize the service. 801 */ 802 ComponentName mTopComponent; 803 String mTopAction = Intent.ACTION_MAIN; 804 String mTopData; 805 boolean mProcessesReady = false; 806 boolean mSystemReady = false; 807 boolean mBooting = false; 808 boolean mWaitingUpdate = false; 809 boolean mDidUpdate = false; 810 boolean mOnBattery = false; 811 boolean mLaunchWarningShown = false; 812 813 Context mContext; 814 815 int mFactoryTest; 816 817 boolean mCheckedForSetup; 818 819 /** 820 * The time at which we will allow normal application switches again, 821 * after a call to {@link #stopAppSwitches()}. 822 */ 823 long mAppSwitchesAllowedTime; 824 825 /** 826 * This is set to true after the first switch after mAppSwitchesAllowedTime 827 * is set; any switches after that will clear the time. 828 */ 829 boolean mDidAppSwitch; 830 831 /** 832 * Last time (in realtime) at which we checked for power usage. 833 */ 834 long mLastPowerCheckRealtime; 835 836 /** 837 * Last time (in uptime) at which we checked for power usage. 838 */ 839 long mLastPowerCheckUptime; 840 841 /** 842 * Set while we are wanting to sleep, to prevent any 843 * activities from being started/resumed. 844 */ 845 boolean mSleeping = false; 846 847 /** 848 * State of external calls telling us if the device is asleep. 849 */ 850 boolean mWentToSleep = false; 851 852 /** 853 * State of external call telling us if the lock screen is shown. 854 */ 855 boolean mLockScreenShown = false; 856 857 /** 858 * Set if we are shutting down the system, similar to sleeping. 859 */ 860 boolean mShuttingDown = false; 861 862 /** 863 * Current sequence id for oom_adj computation traversal. 864 */ 865 int mAdjSeq = 0; 866 867 /** 868 * Current sequence id for process LRU updating. 869 */ 870 int mLruSeq = 0; 871 872 /** 873 * Keep track of the non-cached/empty process we last found, to help 874 * determine how to distribute cached/empty processes next time. 875 */ 876 int mNumNonCachedProcs = 0; 877 878 /** 879 * Keep track of the number of cached hidden procs, to balance oom adj 880 * distribution between those and empty procs. 881 */ 882 int mNumCachedHiddenProcs = 0; 883 884 /** 885 * Keep track of the number of service processes we last found, to 886 * determine on the next iteration which should be B services. 887 */ 888 int mNumServiceProcs = 0; 889 int mNewNumAServiceProcs = 0; 890 int mNewNumServiceProcs = 0; 891 892 /** 893 * Allow the current computed overall memory level of the system to go down? 894 * This is set to false when we are killing processes for reasons other than 895 * memory management, so that the now smaller process list will not be taken as 896 * an indication that memory is tighter. 897 */ 898 boolean mAllowLowerMemLevel = false; 899 900 /** 901 * The last computed memory level, for holding when we are in a state that 902 * processes are going away for other reasons. 903 */ 904 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 905 906 /** 907 * The last total number of process we have, to determine if changes actually look 908 * like a shrinking number of process due to lower RAM. 909 */ 910 int mLastNumProcesses; 911 912 /** 913 * The uptime of the last time we performed idle maintenance. 914 */ 915 long mLastIdleTime = SystemClock.uptimeMillis(); 916 917 /** 918 * Total time spent with RAM that has been added in the past since the last idle time. 919 */ 920 long mLowRamTimeSinceLastIdle = 0; 921 922 /** 923 * If RAM is currently low, when that horrible situatin started. 924 */ 925 long mLowRamStartTime = 0; 926 927 /** 928 * This is set if we had to do a delayed dexopt of an app before launching 929 * it, to increase the ANR timeouts in that case. 930 */ 931 boolean mDidDexOpt; 932 933 /** 934 * Set if the systemServer made a call to enterSafeMode. 935 */ 936 boolean mSafeMode; 937 938 String mDebugApp = null; 939 boolean mWaitForDebugger = false; 940 boolean mDebugTransient = false; 941 String mOrigDebugApp = null; 942 boolean mOrigWaitForDebugger = false; 943 boolean mAlwaysFinishActivities = false; 944 IActivityController mController = null; 945 String mProfileApp = null; 946 ProcessRecord mProfileProc = null; 947 String mProfileFile; 948 ParcelFileDescriptor mProfileFd; 949 int mProfileType = 0; 950 boolean mAutoStopProfiler = false; 951 String mOpenGlTraceApp = null; 952 953 static class ProcessChangeItem { 954 static final int CHANGE_ACTIVITIES = 1<<0; 955 static final int CHANGE_IMPORTANCE= 1<<1; 956 int changes; 957 int uid; 958 int pid; 959 int importance; 960 boolean foregroundActivities; 961 } 962 963 final RemoteCallbackList<IProcessObserver> mProcessObservers 964 = new RemoteCallbackList<IProcessObserver>(); 965 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 966 967 final ArrayList<ProcessChangeItem> mPendingProcessChanges 968 = new ArrayList<ProcessChangeItem>(); 969 final ArrayList<ProcessChangeItem> mAvailProcessChanges 970 = new ArrayList<ProcessChangeItem>(); 971 972 /** 973 * Runtime CPU use collection thread. This object's lock is used to 974 * protect all related state. 975 */ 976 final Thread mProcessCpuThread; 977 978 /** 979 * Used to collect process stats when showing not responding dialog. 980 * Protected by mProcessCpuThread. 981 */ 982 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 983 MONITOR_THREAD_CPU_USAGE); 984 final AtomicLong mLastCpuTime = new AtomicLong(0); 985 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 986 987 long mLastWriteTime = 0; 988 989 /** 990 * Used to retain an update lock when the foreground activity is in 991 * immersive mode. 992 */ 993 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 994 995 /** 996 * Set to true after the system has finished booting. 997 */ 998 boolean mBooted = false; 999 1000 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1001 int mProcessLimitOverride = -1; 1002 1003 WindowManagerService mWindowManager; 1004 1005 final ActivityThread mSystemThread; 1006 1007 int mCurrentUserId = 0; 1008 private UserManagerService mUserManager; 1009 1010 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1011 final ProcessRecord mApp; 1012 final int mPid; 1013 final IApplicationThread mAppThread; 1014 1015 AppDeathRecipient(ProcessRecord app, int pid, 1016 IApplicationThread thread) { 1017 if (localLOGV) Slog.v( 1018 TAG, "New death recipient " + this 1019 + " for thread " + thread.asBinder()); 1020 mApp = app; 1021 mPid = pid; 1022 mAppThread = thread; 1023 } 1024 1025 @Override 1026 public void binderDied() { 1027 if (localLOGV) Slog.v( 1028 TAG, "Death received in " + this 1029 + " for thread " + mAppThread.asBinder()); 1030 synchronized(ActivityManagerService.this) { 1031 appDiedLocked(mApp, mPid, mAppThread); 1032 } 1033 } 1034 } 1035 1036 static final int SHOW_ERROR_MSG = 1; 1037 static final int SHOW_NOT_RESPONDING_MSG = 2; 1038 static final int SHOW_FACTORY_ERROR_MSG = 3; 1039 static final int UPDATE_CONFIGURATION_MSG = 4; 1040 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1041 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1042 static final int SERVICE_TIMEOUT_MSG = 12; 1043 static final int UPDATE_TIME_ZONE = 13; 1044 static final int SHOW_UID_ERROR_MSG = 14; 1045 static final int IM_FEELING_LUCKY_MSG = 15; 1046 static final int PROC_START_TIMEOUT_MSG = 20; 1047 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1048 static final int KILL_APPLICATION_MSG = 22; 1049 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1050 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1051 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1052 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1053 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1054 static final int CLEAR_DNS_CACHE_MSG = 28; 1055 static final int UPDATE_HTTP_PROXY_MSG = 29; 1056 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1057 static final int DISPATCH_PROCESSES_CHANGED = 31; 1058 static final int DISPATCH_PROCESS_DIED = 32; 1059 static final int REPORT_MEM_USAGE_MSG = 33; 1060 static final int REPORT_USER_SWITCH_MSG = 34; 1061 static final int CONTINUE_USER_SWITCH_MSG = 35; 1062 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1063 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1064 static final int PERSIST_URI_GRANTS_MSG = 38; 1065 static final int REQUEST_ALL_PSS_MSG = 39; 1066 static final int UPDATE_TIME = 40; 1067 1068 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1069 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1070 static final int FIRST_COMPAT_MODE_MSG = 300; 1071 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1072 1073 AlertDialog mUidAlert; 1074 CompatModeDialog mCompatModeDialog; 1075 long mLastMemUsageReportTime = 0; 1076 1077 /** 1078 * Flag whether the current user is a "monkey", i.e. whether 1079 * the UI is driven by a UI automation tool. 1080 */ 1081 private boolean mUserIsMonkey; 1082 1083 final ServiceThread mHandlerThread; 1084 final MainHandler mHandler; 1085 1086 final class MainHandler extends Handler { 1087 public MainHandler(Looper looper) { 1088 super(looper, null, true); 1089 } 1090 1091 @Override 1092 public void handleMessage(Message msg) { 1093 switch (msg.what) { 1094 case SHOW_ERROR_MSG: { 1095 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1096 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1097 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1098 synchronized (ActivityManagerService.this) { 1099 ProcessRecord proc = (ProcessRecord)data.get("app"); 1100 AppErrorResult res = (AppErrorResult) data.get("result"); 1101 if (proc != null && proc.crashDialog != null) { 1102 Slog.e(TAG, "App already has crash dialog: " + proc); 1103 if (res != null) { 1104 res.set(0); 1105 } 1106 return; 1107 } 1108 if (!showBackground && UserHandle.getAppId(proc.uid) 1109 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1110 && proc.pid != MY_PID) { 1111 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1112 if (res != null) { 1113 res.set(0); 1114 } 1115 return; 1116 } 1117 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1118 Dialog d = new AppErrorDialog(mContext, 1119 ActivityManagerService.this, res, proc); 1120 d.show(); 1121 proc.crashDialog = d; 1122 } else { 1123 // The device is asleep, so just pretend that the user 1124 // saw a crash dialog and hit "force quit". 1125 if (res != null) { 1126 res.set(0); 1127 } 1128 } 1129 } 1130 1131 ensureBootCompleted(); 1132 } break; 1133 case SHOW_NOT_RESPONDING_MSG: { 1134 synchronized (ActivityManagerService.this) { 1135 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1136 ProcessRecord proc = (ProcessRecord)data.get("app"); 1137 if (proc != null && proc.anrDialog != null) { 1138 Slog.e(TAG, "App already has anr dialog: " + proc); 1139 return; 1140 } 1141 1142 Intent intent = new Intent("android.intent.action.ANR"); 1143 if (!mProcessesReady) { 1144 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1145 | Intent.FLAG_RECEIVER_FOREGROUND); 1146 } 1147 broadcastIntentLocked(null, null, intent, 1148 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1149 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1150 1151 if (mShowDialogs) { 1152 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1153 mContext, proc, (ActivityRecord)data.get("activity"), 1154 msg.arg1 != 0); 1155 d.show(); 1156 proc.anrDialog = d; 1157 } else { 1158 // Just kill the app if there is no dialog to be shown. 1159 killAppAtUsersRequest(proc, null); 1160 } 1161 } 1162 1163 ensureBootCompleted(); 1164 } break; 1165 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1166 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1167 synchronized (ActivityManagerService.this) { 1168 ProcessRecord proc = (ProcessRecord) data.get("app"); 1169 if (proc == null) { 1170 Slog.e(TAG, "App not found when showing strict mode dialog."); 1171 break; 1172 } 1173 if (proc.crashDialog != null) { 1174 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1175 return; 1176 } 1177 AppErrorResult res = (AppErrorResult) data.get("result"); 1178 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1179 Dialog d = new StrictModeViolationDialog(mContext, 1180 ActivityManagerService.this, res, proc); 1181 d.show(); 1182 proc.crashDialog = d; 1183 } else { 1184 // The device is asleep, so just pretend that the user 1185 // saw a crash dialog and hit "force quit". 1186 res.set(0); 1187 } 1188 } 1189 ensureBootCompleted(); 1190 } break; 1191 case SHOW_FACTORY_ERROR_MSG: { 1192 Dialog d = new FactoryErrorDialog( 1193 mContext, msg.getData().getCharSequence("msg")); 1194 d.show(); 1195 ensureBootCompleted(); 1196 } break; 1197 case UPDATE_CONFIGURATION_MSG: { 1198 final ContentResolver resolver = mContext.getContentResolver(); 1199 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1200 } break; 1201 case GC_BACKGROUND_PROCESSES_MSG: { 1202 synchronized (ActivityManagerService.this) { 1203 performAppGcsIfAppropriateLocked(); 1204 } 1205 } break; 1206 case WAIT_FOR_DEBUGGER_MSG: { 1207 synchronized (ActivityManagerService.this) { 1208 ProcessRecord app = (ProcessRecord)msg.obj; 1209 if (msg.arg1 != 0) { 1210 if (!app.waitedForDebugger) { 1211 Dialog d = new AppWaitingForDebuggerDialog( 1212 ActivityManagerService.this, 1213 mContext, app); 1214 app.waitDialog = d; 1215 app.waitedForDebugger = true; 1216 d.show(); 1217 } 1218 } else { 1219 if (app.waitDialog != null) { 1220 app.waitDialog.dismiss(); 1221 app.waitDialog = null; 1222 } 1223 } 1224 } 1225 } break; 1226 case SERVICE_TIMEOUT_MSG: { 1227 if (mDidDexOpt) { 1228 mDidDexOpt = false; 1229 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1230 nmsg.obj = msg.obj; 1231 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1232 return; 1233 } 1234 mServices.serviceTimeout((ProcessRecord)msg.obj); 1235 } break; 1236 case UPDATE_TIME_ZONE: { 1237 synchronized (ActivityManagerService.this) { 1238 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1239 ProcessRecord r = mLruProcesses.get(i); 1240 if (r.thread != null) { 1241 try { 1242 r.thread.updateTimeZone(); 1243 } catch (RemoteException ex) { 1244 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1245 } 1246 } 1247 } 1248 } 1249 } break; 1250 case CLEAR_DNS_CACHE_MSG: { 1251 synchronized (ActivityManagerService.this) { 1252 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1253 ProcessRecord r = mLruProcesses.get(i); 1254 if (r.thread != null) { 1255 try { 1256 r.thread.clearDnsCache(); 1257 } catch (RemoteException ex) { 1258 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1259 } 1260 } 1261 } 1262 } 1263 } break; 1264 case UPDATE_HTTP_PROXY_MSG: { 1265 ProxyProperties proxy = (ProxyProperties)msg.obj; 1266 String host = ""; 1267 String port = ""; 1268 String exclList = ""; 1269 String pacFileUrl = null; 1270 if (proxy != null) { 1271 host = proxy.getHost(); 1272 port = Integer.toString(proxy.getPort()); 1273 exclList = proxy.getExclusionList(); 1274 pacFileUrl = proxy.getPacFileUrl(); 1275 } 1276 synchronized (ActivityManagerService.this) { 1277 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1278 ProcessRecord r = mLruProcesses.get(i); 1279 if (r.thread != null) { 1280 try { 1281 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1282 } catch (RemoteException ex) { 1283 Slog.w(TAG, "Failed to update http proxy for: " + 1284 r.info.processName); 1285 } 1286 } 1287 } 1288 } 1289 } break; 1290 case SHOW_UID_ERROR_MSG: { 1291 String title = "System UIDs Inconsistent"; 1292 String text = "UIDs on the system are inconsistent, you need to wipe your" 1293 + " data partition or your device will be unstable."; 1294 Log.e(TAG, title + ": " + text); 1295 if (mShowDialogs) { 1296 // XXX This is a temporary dialog, no need to localize. 1297 AlertDialog d = new BaseErrorDialog(mContext); 1298 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1299 d.setCancelable(false); 1300 d.setTitle(title); 1301 d.setMessage(text); 1302 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1303 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1304 mUidAlert = d; 1305 d.show(); 1306 } 1307 } break; 1308 case IM_FEELING_LUCKY_MSG: { 1309 if (mUidAlert != null) { 1310 mUidAlert.dismiss(); 1311 mUidAlert = null; 1312 } 1313 } break; 1314 case PROC_START_TIMEOUT_MSG: { 1315 if (mDidDexOpt) { 1316 mDidDexOpt = false; 1317 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1318 nmsg.obj = msg.obj; 1319 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1320 return; 1321 } 1322 ProcessRecord app = (ProcessRecord)msg.obj; 1323 synchronized (ActivityManagerService.this) { 1324 processStartTimedOutLocked(app); 1325 } 1326 } break; 1327 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1328 synchronized (ActivityManagerService.this) { 1329 doPendingActivityLaunchesLocked(true); 1330 } 1331 } break; 1332 case KILL_APPLICATION_MSG: { 1333 synchronized (ActivityManagerService.this) { 1334 int appid = msg.arg1; 1335 boolean restart = (msg.arg2 == 1); 1336 Bundle bundle = (Bundle)msg.obj; 1337 String pkg = bundle.getString("pkg"); 1338 String reason = bundle.getString("reason"); 1339 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1340 UserHandle.USER_ALL, reason); 1341 } 1342 } break; 1343 case FINALIZE_PENDING_INTENT_MSG: { 1344 ((PendingIntentRecord)msg.obj).completeFinalize(); 1345 } break; 1346 case POST_HEAVY_NOTIFICATION_MSG: { 1347 INotificationManager inm = NotificationManager.getService(); 1348 if (inm == null) { 1349 return; 1350 } 1351 1352 ActivityRecord root = (ActivityRecord)msg.obj; 1353 ProcessRecord process = root.app; 1354 if (process == null) { 1355 return; 1356 } 1357 1358 try { 1359 Context context = mContext.createPackageContext(process.info.packageName, 0); 1360 String text = mContext.getString(R.string.heavy_weight_notification, 1361 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1362 Notification notification = new Notification(); 1363 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1364 notification.when = 0; 1365 notification.flags = Notification.FLAG_ONGOING_EVENT; 1366 notification.tickerText = text; 1367 notification.defaults = 0; // please be quiet 1368 notification.sound = null; 1369 notification.vibrate = null; 1370 notification.setLatestEventInfo(context, text, 1371 mContext.getText(R.string.heavy_weight_notification_detail), 1372 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1373 PendingIntent.FLAG_CANCEL_CURRENT, null, 1374 new UserHandle(root.userId))); 1375 1376 try { 1377 int[] outId = new int[1]; 1378 inm.enqueueNotificationWithTag("android", "android", null, 1379 R.string.heavy_weight_notification, 1380 notification, outId, root.userId); 1381 } catch (RuntimeException e) { 1382 Slog.w(ActivityManagerService.TAG, 1383 "Error showing notification for heavy-weight app", e); 1384 } catch (RemoteException e) { 1385 } 1386 } catch (NameNotFoundException e) { 1387 Slog.w(TAG, "Unable to create context for heavy notification", e); 1388 } 1389 } break; 1390 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1391 INotificationManager inm = NotificationManager.getService(); 1392 if (inm == null) { 1393 return; 1394 } 1395 try { 1396 inm.cancelNotificationWithTag("android", null, 1397 R.string.heavy_weight_notification, msg.arg1); 1398 } catch (RuntimeException e) { 1399 Slog.w(ActivityManagerService.TAG, 1400 "Error canceling notification for service", e); 1401 } catch (RemoteException e) { 1402 } 1403 } break; 1404 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1405 synchronized (ActivityManagerService.this) { 1406 checkExcessivePowerUsageLocked(true); 1407 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1408 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1409 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1410 } 1411 } break; 1412 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1413 synchronized (ActivityManagerService.this) { 1414 ActivityRecord ar = (ActivityRecord)msg.obj; 1415 if (mCompatModeDialog != null) { 1416 if (mCompatModeDialog.mAppInfo.packageName.equals( 1417 ar.info.applicationInfo.packageName)) { 1418 return; 1419 } 1420 mCompatModeDialog.dismiss(); 1421 mCompatModeDialog = null; 1422 } 1423 if (ar != null && false) { 1424 if (mCompatModePackages.getPackageAskCompatModeLocked( 1425 ar.packageName)) { 1426 int mode = mCompatModePackages.computeCompatModeLocked( 1427 ar.info.applicationInfo); 1428 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1429 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1430 mCompatModeDialog = new CompatModeDialog( 1431 ActivityManagerService.this, mContext, 1432 ar.info.applicationInfo); 1433 mCompatModeDialog.show(); 1434 } 1435 } 1436 } 1437 } 1438 break; 1439 } 1440 case DISPATCH_PROCESSES_CHANGED: { 1441 dispatchProcessesChanged(); 1442 break; 1443 } 1444 case DISPATCH_PROCESS_DIED: { 1445 final int pid = msg.arg1; 1446 final int uid = msg.arg2; 1447 dispatchProcessDied(pid, uid); 1448 break; 1449 } 1450 case REPORT_MEM_USAGE_MSG: { 1451 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1452 Thread thread = new Thread() { 1453 @Override public void run() { 1454 final SparseArray<ProcessMemInfo> infoMap 1455 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1456 for (int i=0, N=memInfos.size(); i<N; i++) { 1457 ProcessMemInfo mi = memInfos.get(i); 1458 infoMap.put(mi.pid, mi); 1459 } 1460 updateCpuStatsNow(); 1461 synchronized (mProcessCpuThread) { 1462 final int N = mProcessCpuTracker.countStats(); 1463 for (int i=0; i<N; i++) { 1464 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1465 if (st.vsize > 0) { 1466 long pss = Debug.getPss(st.pid, null); 1467 if (pss > 0) { 1468 if (infoMap.indexOfKey(st.pid) < 0) { 1469 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1470 ProcessList.NATIVE_ADJ, -1, "native", null); 1471 mi.pss = pss; 1472 memInfos.add(mi); 1473 } 1474 } 1475 } 1476 } 1477 } 1478 1479 long totalPss = 0; 1480 for (int i=0, N=memInfos.size(); i<N; i++) { 1481 ProcessMemInfo mi = memInfos.get(i); 1482 if (mi.pss == 0) { 1483 mi.pss = Debug.getPss(mi.pid, null); 1484 } 1485 totalPss += mi.pss; 1486 } 1487 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1488 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1489 if (lhs.oomAdj != rhs.oomAdj) { 1490 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1491 } 1492 if (lhs.pss != rhs.pss) { 1493 return lhs.pss < rhs.pss ? 1 : -1; 1494 } 1495 return 0; 1496 } 1497 }); 1498 1499 StringBuilder tag = new StringBuilder(128); 1500 StringBuilder stack = new StringBuilder(128); 1501 tag.append("Low on memory -- "); 1502 appendMemBucket(tag, totalPss, "total", false); 1503 appendMemBucket(stack, totalPss, "total", true); 1504 1505 StringBuilder logBuilder = new StringBuilder(1024); 1506 logBuilder.append("Low on memory:\n"); 1507 1508 boolean firstLine = true; 1509 int lastOomAdj = Integer.MIN_VALUE; 1510 for (int i=0, N=memInfos.size(); i<N; i++) { 1511 ProcessMemInfo mi = memInfos.get(i); 1512 1513 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1514 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1515 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1516 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1517 if (lastOomAdj != mi.oomAdj) { 1518 lastOomAdj = mi.oomAdj; 1519 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1520 tag.append(" / "); 1521 } 1522 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1523 if (firstLine) { 1524 stack.append(":"); 1525 firstLine = false; 1526 } 1527 stack.append("\n\t at "); 1528 } else { 1529 stack.append("$"); 1530 } 1531 } else { 1532 tag.append(" "); 1533 stack.append("$"); 1534 } 1535 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1536 appendMemBucket(tag, mi.pss, mi.name, false); 1537 } 1538 appendMemBucket(stack, mi.pss, mi.name, true); 1539 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1540 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1541 stack.append("("); 1542 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1543 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1544 stack.append(DUMP_MEM_OOM_LABEL[k]); 1545 stack.append(":"); 1546 stack.append(DUMP_MEM_OOM_ADJ[k]); 1547 } 1548 } 1549 stack.append(")"); 1550 } 1551 } 1552 1553 logBuilder.append(" "); 1554 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1555 logBuilder.append(' '); 1556 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1557 logBuilder.append(' '); 1558 ProcessList.appendRamKb(logBuilder, mi.pss); 1559 logBuilder.append(" kB: "); 1560 logBuilder.append(mi.name); 1561 logBuilder.append(" ("); 1562 logBuilder.append(mi.pid); 1563 logBuilder.append(") "); 1564 logBuilder.append(mi.adjType); 1565 logBuilder.append('\n'); 1566 if (mi.adjReason != null) { 1567 logBuilder.append(" "); 1568 logBuilder.append(mi.adjReason); 1569 logBuilder.append('\n'); 1570 } 1571 } 1572 1573 logBuilder.append(" "); 1574 ProcessList.appendRamKb(logBuilder, totalPss); 1575 logBuilder.append(" kB: TOTAL\n"); 1576 1577 long[] infos = new long[Debug.MEMINFO_COUNT]; 1578 Debug.getMemInfo(infos); 1579 logBuilder.append(" MemInfo: "); 1580 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1581 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1582 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1583 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1584 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1585 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1586 logBuilder.append(" ZRAM: "); 1587 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1588 logBuilder.append(" kB RAM, "); 1589 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1590 logBuilder.append(" kB swap total, "); 1591 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1592 logBuilder.append(" kB swap free\n"); 1593 } 1594 Slog.i(TAG, logBuilder.toString()); 1595 1596 StringBuilder dropBuilder = new StringBuilder(1024); 1597 /* 1598 StringWriter oomSw = new StringWriter(); 1599 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1600 StringWriter catSw = new StringWriter(); 1601 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1602 String[] emptyArgs = new String[] { }; 1603 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1604 oomPw.flush(); 1605 String oomString = oomSw.toString(); 1606 */ 1607 dropBuilder.append(stack); 1608 dropBuilder.append('\n'); 1609 dropBuilder.append('\n'); 1610 dropBuilder.append(logBuilder); 1611 dropBuilder.append('\n'); 1612 /* 1613 dropBuilder.append(oomString); 1614 dropBuilder.append('\n'); 1615 */ 1616 StringWriter catSw = new StringWriter(); 1617 synchronized (ActivityManagerService.this) { 1618 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1619 String[] emptyArgs = new String[] { }; 1620 catPw.println(); 1621 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1622 catPw.println(); 1623 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1624 false, false, null); 1625 catPw.println(); 1626 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1627 catPw.flush(); 1628 } 1629 dropBuilder.append(catSw.toString()); 1630 addErrorToDropBox("lowmem", null, "system_server", null, 1631 null, tag.toString(), dropBuilder.toString(), null, null); 1632 //Slog.i(TAG, "Sent to dropbox:"); 1633 //Slog.i(TAG, dropBuilder.toString()); 1634 synchronized (ActivityManagerService.this) { 1635 long now = SystemClock.uptimeMillis(); 1636 if (mLastMemUsageReportTime < now) { 1637 mLastMemUsageReportTime = now; 1638 } 1639 } 1640 } 1641 }; 1642 thread.start(); 1643 break; 1644 } 1645 case REPORT_USER_SWITCH_MSG: { 1646 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1647 break; 1648 } 1649 case CONTINUE_USER_SWITCH_MSG: { 1650 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1651 break; 1652 } 1653 case USER_SWITCH_TIMEOUT_MSG: { 1654 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1655 break; 1656 } 1657 case IMMERSIVE_MODE_LOCK_MSG: { 1658 final boolean nextState = (msg.arg1 != 0); 1659 if (mUpdateLock.isHeld() != nextState) { 1660 if (DEBUG_IMMERSIVE) { 1661 final ActivityRecord r = (ActivityRecord) msg.obj; 1662 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1663 } 1664 if (nextState) { 1665 mUpdateLock.acquire(); 1666 } else { 1667 mUpdateLock.release(); 1668 } 1669 } 1670 break; 1671 } 1672 case PERSIST_URI_GRANTS_MSG: { 1673 writeGrantedUriPermissions(); 1674 break; 1675 } 1676 case REQUEST_ALL_PSS_MSG: { 1677 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1678 break; 1679 } 1680 case UPDATE_TIME: { 1681 synchronized (ActivityManagerService.this) { 1682 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1683 ProcessRecord r = mLruProcesses.get(i); 1684 if (r.thread != null) { 1685 try { 1686 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1687 } catch (RemoteException ex) { 1688 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1689 } 1690 } 1691 } 1692 } 1693 1694 break; 1695 } 1696 } 1697 } 1698 }; 1699 1700 static final int COLLECT_PSS_BG_MSG = 1; 1701 1702 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1703 @Override 1704 public void handleMessage(Message msg) { 1705 switch (msg.what) { 1706 case COLLECT_PSS_BG_MSG: { 1707 int i=0, num=0; 1708 long start = SystemClock.uptimeMillis(); 1709 long[] tmp = new long[1]; 1710 do { 1711 ProcessRecord proc; 1712 int procState; 1713 int pid; 1714 synchronized (ActivityManagerService.this) { 1715 if (i >= mPendingPssProcesses.size()) { 1716 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1717 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1718 mPendingPssProcesses.clear(); 1719 return; 1720 } 1721 proc = mPendingPssProcesses.get(i); 1722 procState = proc.pssProcState; 1723 if (proc.thread != null && procState == proc.setProcState) { 1724 pid = proc.pid; 1725 } else { 1726 proc = null; 1727 pid = 0; 1728 } 1729 i++; 1730 } 1731 if (proc != null) { 1732 long pss = Debug.getPss(pid, tmp); 1733 synchronized (ActivityManagerService.this) { 1734 if (proc.thread != null && proc.setProcState == procState 1735 && proc.pid == pid) { 1736 num++; 1737 proc.lastPssTime = SystemClock.uptimeMillis(); 1738 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1739 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1740 + ": " + pss + " lastPss=" + proc.lastPss 1741 + " state=" + ProcessList.makeProcStateString(procState)); 1742 if (proc.initialIdlePss == 0) { 1743 proc.initialIdlePss = pss; 1744 } 1745 proc.lastPss = pss; 1746 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1747 proc.lastCachedPss = pss; 1748 } 1749 } 1750 } 1751 } 1752 } while (true); 1753 } 1754 } 1755 } 1756 }; 1757 1758 public void setSystemProcess() { 1759 try { 1760 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1761 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1762 ServiceManager.addService("meminfo", new MemBinder(this)); 1763 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1764 ServiceManager.addService("dbinfo", new DbBinder(this)); 1765 if (MONITOR_CPU_USAGE) { 1766 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1767 } 1768 ServiceManager.addService("permission", new PermissionController(this)); 1769 1770 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1771 "android", STOCK_PM_FLAGS); 1772 mSystemThread.installSystemApplicationInfo(info); 1773 1774 synchronized (this) { 1775 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1776 app.persistent = true; 1777 app.pid = MY_PID; 1778 app.maxAdj = ProcessList.SYSTEM_ADJ; 1779 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1780 mProcessNames.put(app.processName, app.uid, app); 1781 synchronized (mPidsSelfLocked) { 1782 mPidsSelfLocked.put(app.pid, app); 1783 } 1784 updateLruProcessLocked(app, false, null); 1785 updateOomAdjLocked(); 1786 } 1787 } catch (PackageManager.NameNotFoundException e) { 1788 throw new RuntimeException( 1789 "Unable to find android system package", e); 1790 } 1791 } 1792 1793 public void setWindowManager(WindowManagerService wm) { 1794 mWindowManager = wm; 1795 mStackSupervisor.setWindowManager(wm); 1796 } 1797 1798 public void startObservingNativeCrashes() { 1799 final NativeCrashListener ncl = new NativeCrashListener(this); 1800 ncl.start(); 1801 } 1802 1803 public IAppOpsService getAppOpsService() { 1804 return mAppOpsService; 1805 } 1806 1807 static class MemBinder extends Binder { 1808 ActivityManagerService mActivityManagerService; 1809 MemBinder(ActivityManagerService activityManagerService) { 1810 mActivityManagerService = activityManagerService; 1811 } 1812 1813 @Override 1814 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1815 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1816 != PackageManager.PERMISSION_GRANTED) { 1817 pw.println("Permission Denial: can't dump meminfo from from pid=" 1818 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1819 + " without permission " + android.Manifest.permission.DUMP); 1820 return; 1821 } 1822 1823 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1824 } 1825 } 1826 1827 static class GraphicsBinder extends Binder { 1828 ActivityManagerService mActivityManagerService; 1829 GraphicsBinder(ActivityManagerService activityManagerService) { 1830 mActivityManagerService = activityManagerService; 1831 } 1832 1833 @Override 1834 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1835 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1836 != PackageManager.PERMISSION_GRANTED) { 1837 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1838 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1839 + " without permission " + android.Manifest.permission.DUMP); 1840 return; 1841 } 1842 1843 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1844 } 1845 } 1846 1847 static class DbBinder extends Binder { 1848 ActivityManagerService mActivityManagerService; 1849 DbBinder(ActivityManagerService activityManagerService) { 1850 mActivityManagerService = activityManagerService; 1851 } 1852 1853 @Override 1854 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1855 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1856 != PackageManager.PERMISSION_GRANTED) { 1857 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1858 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1859 + " without permission " + android.Manifest.permission.DUMP); 1860 return; 1861 } 1862 1863 mActivityManagerService.dumpDbInfo(fd, pw, args); 1864 } 1865 } 1866 1867 static class CpuBinder extends Binder { 1868 ActivityManagerService mActivityManagerService; 1869 CpuBinder(ActivityManagerService activityManagerService) { 1870 mActivityManagerService = activityManagerService; 1871 } 1872 1873 @Override 1874 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1875 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1876 != PackageManager.PERMISSION_GRANTED) { 1877 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1878 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1879 + " without permission " + android.Manifest.permission.DUMP); 1880 return; 1881 } 1882 1883 synchronized (mActivityManagerService.mProcessCpuThread) { 1884 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1885 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1886 SystemClock.uptimeMillis())); 1887 } 1888 } 1889 } 1890 1891 public static final class Lifecycle extends SystemService { 1892 private final ActivityManagerService mService; 1893 1894 public Lifecycle(Context context) { 1895 super(context); 1896 mService = new ActivityManagerService(context); 1897 } 1898 1899 @Override 1900 public void onStart() { 1901 mService.start(); 1902 } 1903 1904 public ActivityManagerService getService() { 1905 return mService; 1906 } 1907 } 1908 1909 // Note: This method is invoked on the main thread but may need to attach various 1910 // handlers to other threads. So take care to be explicit about the looper. 1911 public ActivityManagerService(Context systemContext) { 1912 mContext = systemContext; 1913 mFactoryTest = FactoryTest.getMode(); 1914 mSystemThread = ActivityThread.currentActivityThread(); 1915 1916 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1917 1918 mHandlerThread = new ServiceThread(TAG, 1919 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1920 mHandlerThread.start(); 1921 mHandler = new MainHandler(mHandlerThread.getLooper()); 1922 1923 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1924 "foreground", BROADCAST_FG_TIMEOUT, false); 1925 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1926 "background", BROADCAST_BG_TIMEOUT, true); 1927 mBroadcastQueues[0] = mFgBroadcastQueue; 1928 mBroadcastQueues[1] = mBgBroadcastQueue; 1929 1930 mServices = new ActiveServices(this); 1931 mProviderMap = new ProviderMap(this); 1932 1933 // TODO: Move creation of battery stats service outside of activity manager service. 1934 File dataDir = Environment.getDataDirectory(); 1935 File systemDir = new File(dataDir, "system"); 1936 systemDir.mkdirs(); 1937 mBatteryStatsService = new BatteryStatsService(new File( 1938 systemDir, "batterystats.bin").toString(), mHandler); 1939 mBatteryStatsService.getActiveStatistics().readLocked(); 1940 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1941 mOnBattery = DEBUG_POWER ? true 1942 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1943 mBatteryStatsService.getActiveStatistics().setCallback(this); 1944 1945 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1946 1947 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1948 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1949 1950 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1951 1952 // User 0 is the first and only user that runs at boot. 1953 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1954 mUserLru.add(Integer.valueOf(0)); 1955 updateStartedUserArrayLocked(); 1956 1957 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1958 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1959 1960 mConfiguration.setToDefaults(); 1961 mConfiguration.setLocale(Locale.getDefault()); 1962 1963 mConfigurationSeq = mConfiguration.seq = 1; 1964 mProcessCpuTracker.init(); 1965 1966 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1967 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1968 mStackSupervisor = new ActivityStackSupervisor(this); 1969 1970 mProcessCpuThread = new Thread("CpuTracker") { 1971 @Override 1972 public void run() { 1973 while (true) { 1974 try { 1975 try { 1976 synchronized(this) { 1977 final long now = SystemClock.uptimeMillis(); 1978 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1979 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1980 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1981 // + ", write delay=" + nextWriteDelay); 1982 if (nextWriteDelay < nextCpuDelay) { 1983 nextCpuDelay = nextWriteDelay; 1984 } 1985 if (nextCpuDelay > 0) { 1986 mProcessCpuMutexFree.set(true); 1987 this.wait(nextCpuDelay); 1988 } 1989 } 1990 } catch (InterruptedException e) { 1991 } 1992 updateCpuStatsNow(); 1993 } catch (Exception e) { 1994 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1995 } 1996 } 1997 } 1998 }; 1999 2000 Watchdog.getInstance().addMonitor(this); 2001 Watchdog.getInstance().addThread(mHandler); 2002 } 2003 2004 private void start() { 2005 mProcessCpuThread.start(); 2006 2007 mBatteryStatsService.publish(mContext); 2008 mUsageStatsService.publish(mContext); 2009 mAppOpsService.publish(mContext); 2010 2011 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2012 } 2013 2014 @Override 2015 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2016 throws RemoteException { 2017 if (code == SYSPROPS_TRANSACTION) { 2018 // We need to tell all apps about the system property change. 2019 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2020 synchronized(this) { 2021 final int NP = mProcessNames.getMap().size(); 2022 for (int ip=0; ip<NP; ip++) { 2023 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2024 final int NA = apps.size(); 2025 for (int ia=0; ia<NA; ia++) { 2026 ProcessRecord app = apps.valueAt(ia); 2027 if (app.thread != null) { 2028 procs.add(app.thread.asBinder()); 2029 } 2030 } 2031 } 2032 } 2033 2034 int N = procs.size(); 2035 for (int i=0; i<N; i++) { 2036 Parcel data2 = Parcel.obtain(); 2037 try { 2038 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2039 } catch (RemoteException e) { 2040 } 2041 data2.recycle(); 2042 } 2043 } 2044 try { 2045 return super.onTransact(code, data, reply, flags); 2046 } catch (RuntimeException e) { 2047 // The activity manager only throws security exceptions, so let's 2048 // log all others. 2049 if (!(e instanceof SecurityException)) { 2050 Slog.wtf(TAG, "Activity Manager Crash", e); 2051 } 2052 throw e; 2053 } 2054 } 2055 2056 void updateCpuStats() { 2057 final long now = SystemClock.uptimeMillis(); 2058 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2059 return; 2060 } 2061 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2062 synchronized (mProcessCpuThread) { 2063 mProcessCpuThread.notify(); 2064 } 2065 } 2066 } 2067 2068 void updateCpuStatsNow() { 2069 synchronized (mProcessCpuThread) { 2070 mProcessCpuMutexFree.set(false); 2071 final long now = SystemClock.uptimeMillis(); 2072 boolean haveNewCpuStats = false; 2073 2074 if (MONITOR_CPU_USAGE && 2075 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2076 mLastCpuTime.set(now); 2077 haveNewCpuStats = true; 2078 mProcessCpuTracker.update(); 2079 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2080 //Slog.i(TAG, "Total CPU usage: " 2081 // + mProcessCpu.getTotalCpuPercent() + "%"); 2082 2083 // Slog the cpu usage if the property is set. 2084 if ("true".equals(SystemProperties.get("events.cpu"))) { 2085 int user = mProcessCpuTracker.getLastUserTime(); 2086 int system = mProcessCpuTracker.getLastSystemTime(); 2087 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2088 int irq = mProcessCpuTracker.getLastIrqTime(); 2089 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2090 int idle = mProcessCpuTracker.getLastIdleTime(); 2091 2092 int total = user + system + iowait + irq + softIrq + idle; 2093 if (total == 0) total = 1; 2094 2095 EventLog.writeEvent(EventLogTags.CPU, 2096 ((user+system+iowait+irq+softIrq) * 100) / total, 2097 (user * 100) / total, 2098 (system * 100) / total, 2099 (iowait * 100) / total, 2100 (irq * 100) / total, 2101 (softIrq * 100) / total); 2102 } 2103 } 2104 2105 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2106 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2107 synchronized(bstats) { 2108 synchronized(mPidsSelfLocked) { 2109 if (haveNewCpuStats) { 2110 if (mOnBattery) { 2111 int perc = bstats.startAddingCpuLocked(); 2112 int totalUTime = 0; 2113 int totalSTime = 0; 2114 final int N = mProcessCpuTracker.countStats(); 2115 for (int i=0; i<N; i++) { 2116 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2117 if (!st.working) { 2118 continue; 2119 } 2120 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2121 int otherUTime = (st.rel_utime*perc)/100; 2122 int otherSTime = (st.rel_stime*perc)/100; 2123 totalUTime += otherUTime; 2124 totalSTime += otherSTime; 2125 if (pr != null) { 2126 BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked( 2127 st.name, st.pid); 2128 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2129 st.rel_stime-otherSTime); 2130 ps.addSpeedStepTimes(cpuSpeedTimes); 2131 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2132 } else if (st.uid >= Process.FIRST_APPLICATION_UID) { 2133 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2134 if (ps == null) { 2135 st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid, 2136 "(Unknown)"); 2137 } 2138 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2139 st.rel_stime-otherSTime); 2140 ps.addSpeedStepTimes(cpuSpeedTimes); 2141 } else { 2142 BatteryStatsImpl.Uid.Proc ps = 2143 bstats.getProcessStatsLocked(st.name, st.pid); 2144 if (ps != null) { 2145 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2146 st.rel_stime-otherSTime); 2147 ps.addSpeedStepTimes(cpuSpeedTimes); 2148 } 2149 } 2150 } 2151 bstats.finishAddingCpuLocked(perc, totalUTime, 2152 totalSTime, cpuSpeedTimes); 2153 } 2154 } 2155 } 2156 2157 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2158 mLastWriteTime = now; 2159 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2160 } 2161 } 2162 } 2163 } 2164 2165 @Override 2166 public void batteryNeedsCpuUpdate() { 2167 updateCpuStatsNow(); 2168 } 2169 2170 @Override 2171 public void batteryPowerChanged(boolean onBattery) { 2172 // When plugging in, update the CPU stats first before changing 2173 // the plug state. 2174 updateCpuStatsNow(); 2175 synchronized (this) { 2176 synchronized(mPidsSelfLocked) { 2177 mOnBattery = DEBUG_POWER ? true : onBattery; 2178 } 2179 } 2180 } 2181 2182 /** 2183 * Initialize the application bind args. These are passed to each 2184 * process when the bindApplication() IPC is sent to the process. They're 2185 * lazily setup to make sure the services are running when they're asked for. 2186 */ 2187 private HashMap<String, IBinder> getCommonServicesLocked() { 2188 if (mAppBindArgs == null) { 2189 mAppBindArgs = new HashMap<String, IBinder>(); 2190 2191 // Setup the application init args 2192 mAppBindArgs.put("package", ServiceManager.getService("package")); 2193 mAppBindArgs.put("window", ServiceManager.getService("window")); 2194 mAppBindArgs.put(Context.ALARM_SERVICE, 2195 ServiceManager.getService(Context.ALARM_SERVICE)); 2196 } 2197 return mAppBindArgs; 2198 } 2199 2200 final void setFocusedActivityLocked(ActivityRecord r) { 2201 if (mFocusedActivity != r) { 2202 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2203 mFocusedActivity = r; 2204 mStackSupervisor.setFocusedStack(r); 2205 if (r != null) { 2206 mWindowManager.setFocusedApp(r.appToken, true); 2207 } 2208 applyUpdateLockStateLocked(r); 2209 } 2210 } 2211 2212 @Override 2213 public void setFocusedStack(int stackId) { 2214 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2215 synchronized (ActivityManagerService.this) { 2216 ActivityStack stack = mStackSupervisor.getStack(stackId); 2217 if (stack != null) { 2218 ActivityRecord r = stack.topRunningActivityLocked(null); 2219 if (r != null) { 2220 setFocusedActivityLocked(r); 2221 } 2222 } 2223 } 2224 } 2225 2226 @Override 2227 public void notifyActivityDrawn(IBinder token) { 2228 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2229 synchronized (this) { 2230 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2231 if (r != null) { 2232 r.task.stack.notifyActivityDrawnLocked(r); 2233 } 2234 } 2235 } 2236 2237 final void applyUpdateLockStateLocked(ActivityRecord r) { 2238 // Modifications to the UpdateLock state are done on our handler, outside 2239 // the activity manager's locks. The new state is determined based on the 2240 // state *now* of the relevant activity record. The object is passed to 2241 // the handler solely for logging detail, not to be consulted/modified. 2242 final boolean nextState = r != null && r.immersive; 2243 mHandler.sendMessage( 2244 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2245 } 2246 2247 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2248 Message msg = Message.obtain(); 2249 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2250 msg.obj = r.task.askedCompatMode ? null : r; 2251 mHandler.sendMessage(msg); 2252 } 2253 2254 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2255 String what, Object obj, ProcessRecord srcApp) { 2256 app.lastActivityTime = now; 2257 2258 if (app.activities.size() > 0) { 2259 // Don't want to touch dependent processes that are hosting activities. 2260 return index; 2261 } 2262 2263 int lrui = mLruProcesses.lastIndexOf(app); 2264 if (lrui < 0) { 2265 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2266 + what + " " + obj + " from " + srcApp); 2267 return index; 2268 } 2269 2270 if (lrui >= index) { 2271 // Don't want to cause this to move dependent processes *back* in the 2272 // list as if they were less frequently used. 2273 return index; 2274 } 2275 2276 if (lrui >= mLruProcessActivityStart) { 2277 // Don't want to touch dependent processes that are hosting activities. 2278 return index; 2279 } 2280 2281 mLruProcesses.remove(lrui); 2282 if (index > 0) { 2283 index--; 2284 } 2285 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2286 + " in LRU list: " + app); 2287 mLruProcesses.add(index, app); 2288 return index; 2289 } 2290 2291 final void removeLruProcessLocked(ProcessRecord app) { 2292 int lrui = mLruProcesses.lastIndexOf(app); 2293 if (lrui >= 0) { 2294 if (lrui <= mLruProcessActivityStart) { 2295 mLruProcessActivityStart--; 2296 } 2297 if (lrui <= mLruProcessServiceStart) { 2298 mLruProcessServiceStart--; 2299 } 2300 mLruProcesses.remove(lrui); 2301 } 2302 } 2303 2304 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2305 ProcessRecord client) { 2306 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities; 2307 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2308 if (!activityChange && hasActivity) { 2309 // The process has activties, so we are only going to allow activity-based 2310 // adjustments move it. It should be kept in the front of the list with other 2311 // processes that have activities, and we don't want those to change their 2312 // order except due to activity operations. 2313 return; 2314 } 2315 2316 mLruSeq++; 2317 final long now = SystemClock.uptimeMillis(); 2318 app.lastActivityTime = now; 2319 2320 // First a quick reject: if the app is already at the position we will 2321 // put it, then there is nothing to do. 2322 if (hasActivity) { 2323 final int N = mLruProcesses.size(); 2324 if (N > 0 && mLruProcesses.get(N-1) == app) { 2325 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2326 return; 2327 } 2328 } else { 2329 if (mLruProcessServiceStart > 0 2330 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2331 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2332 return; 2333 } 2334 } 2335 2336 int lrui = mLruProcesses.lastIndexOf(app); 2337 2338 if (app.persistent && lrui >= 0) { 2339 // We don't care about the position of persistent processes, as long as 2340 // they are in the list. 2341 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2342 return; 2343 } 2344 2345 /* In progress: compute new position first, so we can avoid doing work 2346 if the process is not actually going to move. Not yet working. 2347 int addIndex; 2348 int nextIndex; 2349 boolean inActivity = false, inService = false; 2350 if (hasActivity) { 2351 // Process has activities, put it at the very tipsy-top. 2352 addIndex = mLruProcesses.size(); 2353 nextIndex = mLruProcessServiceStart; 2354 inActivity = true; 2355 } else if (hasService) { 2356 // Process has services, put it at the top of the service list. 2357 addIndex = mLruProcessActivityStart; 2358 nextIndex = mLruProcessServiceStart; 2359 inActivity = true; 2360 inService = true; 2361 } else { 2362 // Process not otherwise of interest, it goes to the top of the non-service area. 2363 addIndex = mLruProcessServiceStart; 2364 if (client != null) { 2365 int clientIndex = mLruProcesses.lastIndexOf(client); 2366 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2367 + app); 2368 if (clientIndex >= 0 && addIndex > clientIndex) { 2369 addIndex = clientIndex; 2370 } 2371 } 2372 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2373 } 2374 2375 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2376 + mLruProcessActivityStart + "): " + app); 2377 */ 2378 2379 if (lrui >= 0) { 2380 if (lrui < mLruProcessActivityStart) { 2381 mLruProcessActivityStart--; 2382 } 2383 if (lrui < mLruProcessServiceStart) { 2384 mLruProcessServiceStart--; 2385 } 2386 /* 2387 if (addIndex > lrui) { 2388 addIndex--; 2389 } 2390 if (nextIndex > lrui) { 2391 nextIndex--; 2392 } 2393 */ 2394 mLruProcesses.remove(lrui); 2395 } 2396 2397 /* 2398 mLruProcesses.add(addIndex, app); 2399 if (inActivity) { 2400 mLruProcessActivityStart++; 2401 } 2402 if (inService) { 2403 mLruProcessActivityStart++; 2404 } 2405 */ 2406 2407 int nextIndex; 2408 if (hasActivity) { 2409 final int N = mLruProcesses.size(); 2410 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2411 // Process doesn't have activities, but has clients with 2412 // activities... move it up, but one below the top (the top 2413 // should always have a real activity). 2414 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2415 mLruProcesses.add(N-1, app); 2416 // To keep it from spamming the LRU list (by making a bunch of clients), 2417 // we will push down any other entries owned by the app. 2418 final int uid = app.info.uid; 2419 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2420 ProcessRecord subProc = mLruProcesses.get(i); 2421 if (subProc.info.uid == uid) { 2422 // We want to push this one down the list. If the process after 2423 // it is for the same uid, however, don't do so, because we don't 2424 // want them internally to be re-ordered. 2425 if (mLruProcesses.get(i-1).info.uid != uid) { 2426 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2427 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2428 ProcessRecord tmp = mLruProcesses.get(i); 2429 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2430 mLruProcesses.set(i-1, tmp); 2431 i--; 2432 } 2433 } else { 2434 // A gap, we can stop here. 2435 break; 2436 } 2437 } 2438 } else { 2439 // Process has activities, put it at the very tipsy-top. 2440 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2441 mLruProcesses.add(app); 2442 } 2443 nextIndex = mLruProcessServiceStart; 2444 } else if (hasService) { 2445 // Process has services, put it at the top of the service list. 2446 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2447 mLruProcesses.add(mLruProcessActivityStart, app); 2448 nextIndex = mLruProcessServiceStart; 2449 mLruProcessActivityStart++; 2450 } else { 2451 // Process not otherwise of interest, it goes to the top of the non-service area. 2452 int index = mLruProcessServiceStart; 2453 if (client != null) { 2454 // If there is a client, don't allow the process to be moved up higher 2455 // in the list than that client. 2456 int clientIndex = mLruProcesses.lastIndexOf(client); 2457 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2458 + " when updating " + app); 2459 if (clientIndex <= lrui) { 2460 // Don't allow the client index restriction to push it down farther in the 2461 // list than it already is. 2462 clientIndex = lrui; 2463 } 2464 if (clientIndex >= 0 && index > clientIndex) { 2465 index = clientIndex; 2466 } 2467 } 2468 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2469 mLruProcesses.add(index, app); 2470 nextIndex = index-1; 2471 mLruProcessActivityStart++; 2472 mLruProcessServiceStart++; 2473 } 2474 2475 // If the app is currently using a content provider or service, 2476 // bump those processes as well. 2477 for (int j=app.connections.size()-1; j>=0; j--) { 2478 ConnectionRecord cr = app.connections.valueAt(j); 2479 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2480 && cr.binding.service.app != null 2481 && cr.binding.service.app.lruSeq != mLruSeq 2482 && !cr.binding.service.app.persistent) { 2483 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2484 "service connection", cr, app); 2485 } 2486 } 2487 for (int j=app.conProviders.size()-1; j>=0; j--) { 2488 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2489 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2490 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2491 "provider reference", cpr, app); 2492 } 2493 } 2494 } 2495 2496 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2497 if (uid == Process.SYSTEM_UID) { 2498 // The system gets to run in any process. If there are multiple 2499 // processes with the same uid, just pick the first (this 2500 // should never happen). 2501 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2502 if (procs == null) return null; 2503 final int N = procs.size(); 2504 for (int i = 0; i < N; i++) { 2505 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2506 } 2507 } 2508 ProcessRecord proc = mProcessNames.get(processName, uid); 2509 if (false && proc != null && !keepIfLarge 2510 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2511 && proc.lastCachedPss >= 4000) { 2512 // Turn this condition on to cause killing to happen regularly, for testing. 2513 if (proc.baseProcessTracker != null) { 2514 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2515 } 2516 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2517 + "k from cached"); 2518 } else if (proc != null && !keepIfLarge 2519 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2520 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2521 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2522 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2523 if (proc.baseProcessTracker != null) { 2524 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2525 } 2526 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2527 + "k from cached"); 2528 } 2529 } 2530 return proc; 2531 } 2532 2533 void ensurePackageDexOpt(String packageName) { 2534 IPackageManager pm = AppGlobals.getPackageManager(); 2535 try { 2536 if (pm.performDexOpt(packageName)) { 2537 mDidDexOpt = true; 2538 } 2539 } catch (RemoteException e) { 2540 } 2541 } 2542 2543 boolean isNextTransitionForward() { 2544 int transit = mWindowManager.getPendingAppTransition(); 2545 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2546 || transit == AppTransition.TRANSIT_TASK_OPEN 2547 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2548 } 2549 2550 final ProcessRecord startProcessLocked(String processName, 2551 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2552 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2553 boolean isolated, boolean keepIfLarge) { 2554 ProcessRecord app; 2555 if (!isolated) { 2556 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2557 } else { 2558 // If this is an isolated process, it can't re-use an existing process. 2559 app = null; 2560 } 2561 // We don't have to do anything more if: 2562 // (1) There is an existing application record; and 2563 // (2) The caller doesn't think it is dead, OR there is no thread 2564 // object attached to it so we know it couldn't have crashed; and 2565 // (3) There is a pid assigned to it, so it is either starting or 2566 // already running. 2567 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2568 + " app=" + app + " knownToBeDead=" + knownToBeDead 2569 + " thread=" + (app != null ? app.thread : null) 2570 + " pid=" + (app != null ? app.pid : -1)); 2571 if (app != null && app.pid > 0) { 2572 if (!knownToBeDead || app.thread == null) { 2573 // We already have the app running, or are waiting for it to 2574 // come up (we have a pid but not yet its thread), so keep it. 2575 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2576 // If this is a new package in the process, add the package to the list 2577 app.addPackage(info.packageName, mProcessStats); 2578 return app; 2579 } 2580 2581 // An application record is attached to a previous process, 2582 // clean it up now. 2583 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2584 handleAppDiedLocked(app, true, true); 2585 } 2586 2587 String hostingNameStr = hostingName != null 2588 ? hostingName.flattenToShortString() : null; 2589 2590 if (!isolated) { 2591 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2592 // If we are in the background, then check to see if this process 2593 // is bad. If so, we will just silently fail. 2594 if (mBadProcesses.get(info.processName, info.uid) != null) { 2595 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2596 + "/" + info.processName); 2597 return null; 2598 } 2599 } else { 2600 // When the user is explicitly starting a process, then clear its 2601 // crash count so that we won't make it bad until they see at 2602 // least one crash dialog again, and make the process good again 2603 // if it had been bad. 2604 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2605 + "/" + info.processName); 2606 mProcessCrashTimes.remove(info.processName, info.uid); 2607 if (mBadProcesses.get(info.processName, info.uid) != null) { 2608 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2609 UserHandle.getUserId(info.uid), info.uid, 2610 info.processName); 2611 mBadProcesses.remove(info.processName, info.uid); 2612 if (app != null) { 2613 app.bad = false; 2614 } 2615 } 2616 } 2617 } 2618 2619 if (app == null) { 2620 app = newProcessRecordLocked(info, processName, isolated); 2621 if (app == null) { 2622 Slog.w(TAG, "Failed making new process record for " 2623 + processName + "/" + info.uid + " isolated=" + isolated); 2624 return null; 2625 } 2626 mProcessNames.put(processName, app.uid, app); 2627 if (isolated) { 2628 mIsolatedProcesses.put(app.uid, app); 2629 } 2630 } else { 2631 // If this is a new package in the process, add the package to the list 2632 app.addPackage(info.packageName, mProcessStats); 2633 } 2634 2635 // If the system is not ready yet, then hold off on starting this 2636 // process until it is. 2637 if (!mProcessesReady 2638 && !isAllowedWhileBooting(info) 2639 && !allowWhileBooting) { 2640 if (!mProcessesOnHold.contains(app)) { 2641 mProcessesOnHold.add(app); 2642 } 2643 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2644 return app; 2645 } 2646 2647 startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */); 2648 return (app.pid != 0) ? app : null; 2649 } 2650 2651 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2652 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2653 } 2654 2655 private final void startProcessLocked(ProcessRecord app, 2656 String hostingType, String hostingNameStr, String abiOverride) { 2657 if (app.pid > 0 && app.pid != MY_PID) { 2658 synchronized (mPidsSelfLocked) { 2659 mPidsSelfLocked.remove(app.pid); 2660 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2661 } 2662 app.setPid(0); 2663 } 2664 2665 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2666 "startProcessLocked removing on hold: " + app); 2667 mProcessesOnHold.remove(app); 2668 2669 updateCpuStats(); 2670 2671 try { 2672 int uid = app.uid; 2673 2674 int[] gids = null; 2675 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2676 if (!app.isolated) { 2677 int[] permGids = null; 2678 try { 2679 final PackageManager pm = mContext.getPackageManager(); 2680 permGids = pm.getPackageGids(app.info.packageName); 2681 2682 if (Environment.isExternalStorageEmulated()) { 2683 if (pm.checkPermission( 2684 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2685 app.info.packageName) == PERMISSION_GRANTED) { 2686 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2687 } else { 2688 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2689 } 2690 } 2691 } catch (PackageManager.NameNotFoundException e) { 2692 Slog.w(TAG, "Unable to retrieve gids", e); 2693 } 2694 2695 /* 2696 * Add shared application GID so applications can share some 2697 * resources like shared libraries 2698 */ 2699 if (permGids == null) { 2700 gids = new int[1]; 2701 } else { 2702 gids = new int[permGids.length + 1]; 2703 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2704 } 2705 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2706 } 2707 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2708 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2709 && mTopComponent != null 2710 && app.processName.equals(mTopComponent.getPackageName())) { 2711 uid = 0; 2712 } 2713 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2714 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2715 uid = 0; 2716 } 2717 } 2718 int debugFlags = 0; 2719 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2720 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2721 // Also turn on CheckJNI for debuggable apps. It's quite 2722 // awkward to turn on otherwise. 2723 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2724 } 2725 // Run the app in safe mode if its manifest requests so or the 2726 // system is booted in safe mode. 2727 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2728 mSafeMode == true) { 2729 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2730 } 2731 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2732 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2733 } 2734 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2735 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2736 } 2737 if ("1".equals(SystemProperties.get("debug.assert"))) { 2738 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2739 } 2740 2741 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi; 2742 if (requiredAbi == null) { 2743 requiredAbi = Build.SUPPORTED_ABIS[0]; 2744 } 2745 2746 // Start the process. It will either succeed and return a result containing 2747 // the PID of the new process, or else throw a RuntimeException. 2748 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2749 app.processName, uid, uid, gids, debugFlags, mountExternal, 2750 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2751 2752 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2753 synchronized (bs) { 2754 if (bs.isOnBattery()) { 2755 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2756 } 2757 } 2758 2759 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2760 UserHandle.getUserId(uid), startResult.pid, uid, 2761 app.processName, hostingType, 2762 hostingNameStr != null ? hostingNameStr : ""); 2763 2764 if (app.persistent) { 2765 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2766 } 2767 2768 StringBuilder buf = mStringBuilder; 2769 buf.setLength(0); 2770 buf.append("Start proc "); 2771 buf.append(app.processName); 2772 buf.append(" for "); 2773 buf.append(hostingType); 2774 if (hostingNameStr != null) { 2775 buf.append(" "); 2776 buf.append(hostingNameStr); 2777 } 2778 buf.append(": pid="); 2779 buf.append(startResult.pid); 2780 buf.append(" uid="); 2781 buf.append(uid); 2782 buf.append(" gids={"); 2783 if (gids != null) { 2784 for (int gi=0; gi<gids.length; gi++) { 2785 if (gi != 0) buf.append(", "); 2786 buf.append(gids[gi]); 2787 2788 } 2789 } 2790 buf.append("}"); 2791 if (requiredAbi != null) { 2792 buf.append(" abi="); 2793 buf.append(requiredAbi); 2794 } 2795 Slog.i(TAG, buf.toString()); 2796 app.setPid(startResult.pid); 2797 app.usingWrapper = startResult.usingWrapper; 2798 app.removed = false; 2799 synchronized (mPidsSelfLocked) { 2800 this.mPidsSelfLocked.put(startResult.pid, app); 2801 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2802 msg.obj = app; 2803 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2804 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2805 } 2806 } catch (RuntimeException e) { 2807 // XXX do better error recovery. 2808 app.setPid(0); 2809 Slog.e(TAG, "Failure starting process " + app.processName, e); 2810 } 2811 } 2812 2813 void updateUsageStats(ActivityRecord component, boolean resumed) { 2814 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2815 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2816 if (resumed) { 2817 mUsageStatsService.noteResumeComponent(component.realActivity); 2818 synchronized (stats) { 2819 stats.noteActivityResumedLocked(component.app.uid); 2820 } 2821 } else { 2822 mUsageStatsService.notePauseComponent(component.realActivity); 2823 synchronized (stats) { 2824 stats.noteActivityPausedLocked(component.app.uid); 2825 } 2826 } 2827 } 2828 2829 Intent getHomeIntent() { 2830 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2831 intent.setComponent(mTopComponent); 2832 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2833 intent.addCategory(Intent.CATEGORY_HOME); 2834 } 2835 return intent; 2836 } 2837 2838 boolean startHomeActivityLocked(int userId) { 2839 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2840 && mTopAction == null) { 2841 // We are running in factory test mode, but unable to find 2842 // the factory test app, so just sit around displaying the 2843 // error message and don't try to start anything. 2844 return false; 2845 } 2846 Intent intent = getHomeIntent(); 2847 ActivityInfo aInfo = 2848 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2849 if (aInfo != null) { 2850 intent.setComponent(new ComponentName( 2851 aInfo.applicationInfo.packageName, aInfo.name)); 2852 // Don't do this if the home app is currently being 2853 // instrumented. 2854 aInfo = new ActivityInfo(aInfo); 2855 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2856 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2857 aInfo.applicationInfo.uid, true); 2858 if (app == null || app.instrumentationClass == null) { 2859 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2860 mStackSupervisor.startHomeActivity(intent, aInfo); 2861 } 2862 } 2863 2864 return true; 2865 } 2866 2867 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2868 ActivityInfo ai = null; 2869 ComponentName comp = intent.getComponent(); 2870 try { 2871 if (comp != null) { 2872 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2873 } else { 2874 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2875 intent, 2876 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2877 flags, userId); 2878 2879 if (info != null) { 2880 ai = info.activityInfo; 2881 } 2882 } 2883 } catch (RemoteException e) { 2884 // ignore 2885 } 2886 2887 return ai; 2888 } 2889 2890 /** 2891 * Starts the "new version setup screen" if appropriate. 2892 */ 2893 void startSetupActivityLocked() { 2894 // Only do this once per boot. 2895 if (mCheckedForSetup) { 2896 return; 2897 } 2898 2899 // We will show this screen if the current one is a different 2900 // version than the last one shown, and we are not running in 2901 // low-level factory test mode. 2902 final ContentResolver resolver = mContext.getContentResolver(); 2903 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2904 Settings.Global.getInt(resolver, 2905 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2906 mCheckedForSetup = true; 2907 2908 // See if we should be showing the platform update setup UI. 2909 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2910 List<ResolveInfo> ris = mContext.getPackageManager() 2911 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2912 2913 // We don't allow third party apps to replace this. 2914 ResolveInfo ri = null; 2915 for (int i=0; ris != null && i<ris.size(); i++) { 2916 if ((ris.get(i).activityInfo.applicationInfo.flags 2917 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2918 ri = ris.get(i); 2919 break; 2920 } 2921 } 2922 2923 if (ri != null) { 2924 String vers = ri.activityInfo.metaData != null 2925 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2926 : null; 2927 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2928 vers = ri.activityInfo.applicationInfo.metaData.getString( 2929 Intent.METADATA_SETUP_VERSION); 2930 } 2931 String lastVers = Settings.Secure.getString( 2932 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2933 if (vers != null && !vers.equals(lastVers)) { 2934 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2935 intent.setComponent(new ComponentName( 2936 ri.activityInfo.packageName, ri.activityInfo.name)); 2937 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2938 null, null, 0, 0, 0, null, 0, null, false, null, null); 2939 } 2940 } 2941 } 2942 } 2943 2944 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2945 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2946 } 2947 2948 void enforceNotIsolatedCaller(String caller) { 2949 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2950 throw new SecurityException("Isolated process not allowed to call " + caller); 2951 } 2952 } 2953 2954 @Override 2955 public int getFrontActivityScreenCompatMode() { 2956 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2957 synchronized (this) { 2958 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2959 } 2960 } 2961 2962 @Override 2963 public void setFrontActivityScreenCompatMode(int mode) { 2964 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2965 "setFrontActivityScreenCompatMode"); 2966 synchronized (this) { 2967 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2968 } 2969 } 2970 2971 @Override 2972 public int getPackageScreenCompatMode(String packageName) { 2973 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2974 synchronized (this) { 2975 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2976 } 2977 } 2978 2979 @Override 2980 public void setPackageScreenCompatMode(String packageName, int mode) { 2981 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2982 "setPackageScreenCompatMode"); 2983 synchronized (this) { 2984 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2985 } 2986 } 2987 2988 @Override 2989 public boolean getPackageAskScreenCompat(String packageName) { 2990 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2991 synchronized (this) { 2992 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2993 } 2994 } 2995 2996 @Override 2997 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2998 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2999 "setPackageAskScreenCompat"); 3000 synchronized (this) { 3001 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3002 } 3003 } 3004 3005 private void dispatchProcessesChanged() { 3006 int N; 3007 synchronized (this) { 3008 N = mPendingProcessChanges.size(); 3009 if (mActiveProcessChanges.length < N) { 3010 mActiveProcessChanges = new ProcessChangeItem[N]; 3011 } 3012 mPendingProcessChanges.toArray(mActiveProcessChanges); 3013 mAvailProcessChanges.addAll(mPendingProcessChanges); 3014 mPendingProcessChanges.clear(); 3015 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3016 } 3017 3018 int i = mProcessObservers.beginBroadcast(); 3019 while (i > 0) { 3020 i--; 3021 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3022 if (observer != null) { 3023 try { 3024 for (int j=0; j<N; j++) { 3025 ProcessChangeItem item = mActiveProcessChanges[j]; 3026 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3027 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3028 + item.pid + " uid=" + item.uid + ": " 3029 + item.foregroundActivities); 3030 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3031 item.foregroundActivities); 3032 } 3033 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3034 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3035 + item.pid + " uid=" + item.uid + ": " + item.importance); 3036 observer.onImportanceChanged(item.pid, item.uid, 3037 item.importance); 3038 } 3039 } 3040 } catch (RemoteException e) { 3041 } 3042 } 3043 } 3044 mProcessObservers.finishBroadcast(); 3045 } 3046 3047 private void dispatchProcessDied(int pid, int uid) { 3048 int i = mProcessObservers.beginBroadcast(); 3049 while (i > 0) { 3050 i--; 3051 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3052 if (observer != null) { 3053 try { 3054 observer.onProcessDied(pid, uid); 3055 } catch (RemoteException e) { 3056 } 3057 } 3058 } 3059 mProcessObservers.finishBroadcast(); 3060 } 3061 3062 final void doPendingActivityLaunchesLocked(boolean doResume) { 3063 final int N = mPendingActivityLaunches.size(); 3064 if (N <= 0) { 3065 return; 3066 } 3067 for (int i=0; i<N; i++) { 3068 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3069 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3070 doResume && i == (N-1), null); 3071 } 3072 mPendingActivityLaunches.clear(); 3073 } 3074 3075 @Override 3076 public final int startActivity(IApplicationThread caller, String callingPackage, 3077 Intent intent, String resolvedType, IBinder resultTo, 3078 String resultWho, int requestCode, int startFlags, 3079 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3080 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3081 resultWho, requestCode, 3082 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3083 } 3084 3085 @Override 3086 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3087 Intent intent, String resolvedType, IBinder resultTo, 3088 String resultWho, int requestCode, int startFlags, 3089 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3090 enforceNotIsolatedCaller("startActivity"); 3091 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3092 false, true, "startActivity", null); 3093 // TODO: Switch to user app stacks here. 3094 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3095 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3096 null, null, options, userId, null); 3097 } 3098 3099 @Override 3100 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3101 Intent intent, String resolvedType, IBinder resultTo, 3102 String resultWho, int requestCode, int startFlags, String profileFile, 3103 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3104 enforceNotIsolatedCaller("startActivityAndWait"); 3105 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3106 false, true, "startActivityAndWait", null); 3107 WaitResult res = new WaitResult(); 3108 // TODO: Switch to user app stacks here. 3109 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3110 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3111 res, null, options, UserHandle.getCallingUserId(), null); 3112 return res; 3113 } 3114 3115 @Override 3116 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3117 Intent intent, String resolvedType, IBinder resultTo, 3118 String resultWho, int requestCode, int startFlags, Configuration config, 3119 Bundle options, int userId) { 3120 enforceNotIsolatedCaller("startActivityWithConfig"); 3121 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3122 false, true, "startActivityWithConfig", null); 3123 // TODO: Switch to user app stacks here. 3124 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3125 resolvedType, resultTo, resultWho, requestCode, startFlags, 3126 null, null, null, config, options, userId, null); 3127 return ret; 3128 } 3129 3130 @Override 3131 public int startActivityIntentSender(IApplicationThread caller, 3132 IntentSender intent, Intent fillInIntent, String resolvedType, 3133 IBinder resultTo, String resultWho, int requestCode, 3134 int flagsMask, int flagsValues, Bundle options) { 3135 enforceNotIsolatedCaller("startActivityIntentSender"); 3136 // Refuse possible leaked file descriptors 3137 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3138 throw new IllegalArgumentException("File descriptors passed in Intent"); 3139 } 3140 3141 IIntentSender sender = intent.getTarget(); 3142 if (!(sender instanceof PendingIntentRecord)) { 3143 throw new IllegalArgumentException("Bad PendingIntent object"); 3144 } 3145 3146 PendingIntentRecord pir = (PendingIntentRecord)sender; 3147 3148 synchronized (this) { 3149 // If this is coming from the currently resumed activity, it is 3150 // effectively saying that app switches are allowed at this point. 3151 final ActivityStack stack = getFocusedStack(); 3152 if (stack.mResumedActivity != null && 3153 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3154 mAppSwitchesAllowedTime = 0; 3155 } 3156 } 3157 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3158 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3159 return ret; 3160 } 3161 3162 @Override 3163 public boolean startNextMatchingActivity(IBinder callingActivity, 3164 Intent intent, Bundle options) { 3165 // Refuse possible leaked file descriptors 3166 if (intent != null && intent.hasFileDescriptors() == true) { 3167 throw new IllegalArgumentException("File descriptors passed in Intent"); 3168 } 3169 3170 synchronized (this) { 3171 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3172 if (r == null) { 3173 ActivityOptions.abort(options); 3174 return false; 3175 } 3176 if (r.app == null || r.app.thread == null) { 3177 // The caller is not running... d'oh! 3178 ActivityOptions.abort(options); 3179 return false; 3180 } 3181 intent = new Intent(intent); 3182 // The caller is not allowed to change the data. 3183 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3184 // And we are resetting to find the next component... 3185 intent.setComponent(null); 3186 3187 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3188 3189 ActivityInfo aInfo = null; 3190 try { 3191 List<ResolveInfo> resolves = 3192 AppGlobals.getPackageManager().queryIntentActivities( 3193 intent, r.resolvedType, 3194 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3195 UserHandle.getCallingUserId()); 3196 3197 // Look for the original activity in the list... 3198 final int N = resolves != null ? resolves.size() : 0; 3199 for (int i=0; i<N; i++) { 3200 ResolveInfo rInfo = resolves.get(i); 3201 if (rInfo.activityInfo.packageName.equals(r.packageName) 3202 && rInfo.activityInfo.name.equals(r.info.name)) { 3203 // We found the current one... the next matching is 3204 // after it. 3205 i++; 3206 if (i<N) { 3207 aInfo = resolves.get(i).activityInfo; 3208 } 3209 if (debug) { 3210 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3211 + "/" + r.info.name); 3212 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3213 + "/" + aInfo.name); 3214 } 3215 break; 3216 } 3217 } 3218 } catch (RemoteException e) { 3219 } 3220 3221 if (aInfo == null) { 3222 // Nobody who is next! 3223 ActivityOptions.abort(options); 3224 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3225 return false; 3226 } 3227 3228 intent.setComponent(new ComponentName( 3229 aInfo.applicationInfo.packageName, aInfo.name)); 3230 intent.setFlags(intent.getFlags()&~( 3231 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3232 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3233 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3234 Intent.FLAG_ACTIVITY_NEW_TASK)); 3235 3236 // Okay now we need to start the new activity, replacing the 3237 // currently running activity. This is a little tricky because 3238 // we want to start the new one as if the current one is finished, 3239 // but not finish the current one first so that there is no flicker. 3240 // And thus... 3241 final boolean wasFinishing = r.finishing; 3242 r.finishing = true; 3243 3244 // Propagate reply information over to the new activity. 3245 final ActivityRecord resultTo = r.resultTo; 3246 final String resultWho = r.resultWho; 3247 final int requestCode = r.requestCode; 3248 r.resultTo = null; 3249 if (resultTo != null) { 3250 resultTo.removeResultsLocked(r, resultWho, requestCode); 3251 } 3252 3253 final long origId = Binder.clearCallingIdentity(); 3254 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3255 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3256 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3257 options, false, null, null); 3258 Binder.restoreCallingIdentity(origId); 3259 3260 r.finishing = wasFinishing; 3261 if (res != ActivityManager.START_SUCCESS) { 3262 return false; 3263 } 3264 return true; 3265 } 3266 } 3267 3268 final int startActivityInPackage(int uid, String callingPackage, 3269 Intent intent, String resolvedType, IBinder resultTo, 3270 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3271 IActivityContainer container) { 3272 3273 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3274 false, true, "startActivityInPackage", null); 3275 3276 // TODO: Switch to user app stacks here. 3277 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3278 resultTo, resultWho, requestCode, startFlags, 3279 null, null, null, null, options, userId, container); 3280 return ret; 3281 } 3282 3283 @Override 3284 public final int startActivities(IApplicationThread caller, String callingPackage, 3285 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3286 int userId) { 3287 enforceNotIsolatedCaller("startActivities"); 3288 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3289 false, true, "startActivity", null); 3290 // TODO: Switch to user app stacks here. 3291 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3292 resolvedTypes, resultTo, options, userId); 3293 return ret; 3294 } 3295 3296 final int startActivitiesInPackage(int uid, String callingPackage, 3297 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3298 Bundle options, int userId) { 3299 3300 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3301 false, true, "startActivityInPackage", null); 3302 // TODO: Switch to user app stacks here. 3303 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3304 resultTo, options, userId); 3305 return ret; 3306 } 3307 3308 final void addRecentTaskLocked(TaskRecord task) { 3309 int N = mRecentTasks.size(); 3310 // Quick case: check if the top-most recent task is the same. 3311 if (N > 0 && mRecentTasks.get(0) == task) { 3312 return; 3313 } 3314 // Remove any existing entries that are the same kind of task. 3315 for (int i=0; i<N; i++) { 3316 TaskRecord tr = mRecentTasks.get(i); 3317 if (task.userId == tr.userId 3318 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 3319 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 3320 tr.disposeThumbnail(); 3321 mRecentTasks.remove(i); 3322 i--; 3323 N--; 3324 if (task.intent == null) { 3325 // If the new recent task we are adding is not fully 3326 // specified, then replace it with the existing recent task. 3327 task = tr; 3328 } 3329 } 3330 } 3331 if (N >= MAX_RECENT_TASKS) { 3332 mRecentTasks.remove(N-1).disposeThumbnail(); 3333 } 3334 mRecentTasks.add(0, task); 3335 } 3336 3337 @Override 3338 public void reportActivityFullyDrawn(IBinder token) { 3339 synchronized (this) { 3340 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3341 if (r == null) { 3342 return; 3343 } 3344 r.reportFullyDrawnLocked(); 3345 } 3346 } 3347 3348 @Override 3349 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3350 synchronized (this) { 3351 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3352 if (r == null) { 3353 return; 3354 } 3355 final long origId = Binder.clearCallingIdentity(); 3356 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3357 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3358 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3359 if (config != null) { 3360 r.frozenBeforeDestroy = true; 3361 if (!updateConfigurationLocked(config, r, false, false)) { 3362 mStackSupervisor.resumeTopActivitiesLocked(); 3363 } 3364 } 3365 Binder.restoreCallingIdentity(origId); 3366 } 3367 } 3368 3369 @Override 3370 public int getRequestedOrientation(IBinder token) { 3371 synchronized (this) { 3372 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3373 if (r == null) { 3374 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3375 } 3376 return mWindowManager.getAppOrientation(r.appToken); 3377 } 3378 } 3379 3380 /** 3381 * This is the internal entry point for handling Activity.finish(). 3382 * 3383 * @param token The Binder token referencing the Activity we want to finish. 3384 * @param resultCode Result code, if any, from this Activity. 3385 * @param resultData Result data (Intent), if any, from this Activity. 3386 * 3387 * @return Returns true if the activity successfully finished, or false if it is still running. 3388 */ 3389 @Override 3390 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3391 // Refuse possible leaked file descriptors 3392 if (resultData != null && resultData.hasFileDescriptors() == true) { 3393 throw new IllegalArgumentException("File descriptors passed in Intent"); 3394 } 3395 3396 synchronized(this) { 3397 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3398 if (r == null) { 3399 return true; 3400 } 3401 if (mController != null) { 3402 // Find the first activity that is not finishing. 3403 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3404 if (next != null) { 3405 // ask watcher if this is allowed 3406 boolean resumeOK = true; 3407 try { 3408 resumeOK = mController.activityResuming(next.packageName); 3409 } catch (RemoteException e) { 3410 mController = null; 3411 Watchdog.getInstance().setActivityController(null); 3412 } 3413 3414 if (!resumeOK) { 3415 return false; 3416 } 3417 } 3418 } 3419 final long origId = Binder.clearCallingIdentity(); 3420 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3421 resultData, "app-request", true); 3422 Binder.restoreCallingIdentity(origId); 3423 return res; 3424 } 3425 } 3426 3427 @Override 3428 public final void finishHeavyWeightApp() { 3429 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3430 != PackageManager.PERMISSION_GRANTED) { 3431 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3432 + Binder.getCallingPid() 3433 + ", uid=" + Binder.getCallingUid() 3434 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3435 Slog.w(TAG, msg); 3436 throw new SecurityException(msg); 3437 } 3438 3439 synchronized(this) { 3440 if (mHeavyWeightProcess == null) { 3441 return; 3442 } 3443 3444 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3445 mHeavyWeightProcess.activities); 3446 for (int i=0; i<activities.size(); i++) { 3447 ActivityRecord r = activities.get(i); 3448 if (!r.finishing) { 3449 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3450 null, "finish-heavy", true); 3451 } 3452 } 3453 3454 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3455 mHeavyWeightProcess.userId, 0)); 3456 mHeavyWeightProcess = null; 3457 } 3458 } 3459 3460 @Override 3461 public void crashApplication(int uid, int initialPid, String packageName, 3462 String message) { 3463 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3464 != PackageManager.PERMISSION_GRANTED) { 3465 String msg = "Permission Denial: crashApplication() from pid=" 3466 + Binder.getCallingPid() 3467 + ", uid=" + Binder.getCallingUid() 3468 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3469 Slog.w(TAG, msg); 3470 throw new SecurityException(msg); 3471 } 3472 3473 synchronized(this) { 3474 ProcessRecord proc = null; 3475 3476 // Figure out which process to kill. We don't trust that initialPid 3477 // still has any relation to current pids, so must scan through the 3478 // list. 3479 synchronized (mPidsSelfLocked) { 3480 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3481 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3482 if (p.uid != uid) { 3483 continue; 3484 } 3485 if (p.pid == initialPid) { 3486 proc = p; 3487 break; 3488 } 3489 if (p.pkgList.containsKey(packageName)) { 3490 proc = p; 3491 } 3492 } 3493 } 3494 3495 if (proc == null) { 3496 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3497 + " initialPid=" + initialPid 3498 + " packageName=" + packageName); 3499 return; 3500 } 3501 3502 if (proc.thread != null) { 3503 if (proc.pid == Process.myPid()) { 3504 Log.w(TAG, "crashApplication: trying to crash self!"); 3505 return; 3506 } 3507 long ident = Binder.clearCallingIdentity(); 3508 try { 3509 proc.thread.scheduleCrash(message); 3510 } catch (RemoteException e) { 3511 } 3512 Binder.restoreCallingIdentity(ident); 3513 } 3514 } 3515 } 3516 3517 @Override 3518 public final void finishSubActivity(IBinder token, String resultWho, 3519 int requestCode) { 3520 synchronized(this) { 3521 final long origId = Binder.clearCallingIdentity(); 3522 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3523 if (r != null) { 3524 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3525 } 3526 Binder.restoreCallingIdentity(origId); 3527 } 3528 } 3529 3530 @Override 3531 public boolean finishActivityAffinity(IBinder token) { 3532 synchronized(this) { 3533 final long origId = Binder.clearCallingIdentity(); 3534 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3535 boolean res = false; 3536 if (r != null) { 3537 res = r.task.stack.finishActivityAffinityLocked(r); 3538 } 3539 Binder.restoreCallingIdentity(origId); 3540 return res; 3541 } 3542 } 3543 3544 @Override 3545 public boolean willActivityBeVisible(IBinder token) { 3546 synchronized(this) { 3547 ActivityStack stack = ActivityRecord.getStackLocked(token); 3548 if (stack != null) { 3549 return stack.willActivityBeVisibleLocked(token); 3550 } 3551 return false; 3552 } 3553 } 3554 3555 @Override 3556 public void overridePendingTransition(IBinder token, String packageName, 3557 int enterAnim, int exitAnim) { 3558 synchronized(this) { 3559 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3560 if (self == null) { 3561 return; 3562 } 3563 3564 final long origId = Binder.clearCallingIdentity(); 3565 3566 if (self.state == ActivityState.RESUMED 3567 || self.state == ActivityState.PAUSING) { 3568 mWindowManager.overridePendingAppTransition(packageName, 3569 enterAnim, exitAnim, null); 3570 } 3571 3572 Binder.restoreCallingIdentity(origId); 3573 } 3574 } 3575 3576 /** 3577 * Main function for removing an existing process from the activity manager 3578 * as a result of that process going away. Clears out all connections 3579 * to the process. 3580 */ 3581 private final void handleAppDiedLocked(ProcessRecord app, 3582 boolean restarting, boolean allowRestart) { 3583 int pid = app.pid; 3584 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3585 if (!restarting) { 3586 removeLruProcessLocked(app); 3587 if (pid > 0) { 3588 ProcessList.remove(pid); 3589 } 3590 } 3591 3592 if (mProfileProc == app) { 3593 clearProfilerLocked(); 3594 } 3595 3596 // Remove this application's activities from active lists. 3597 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3598 3599 app.activities.clear(); 3600 3601 if (app.instrumentationClass != null) { 3602 Slog.w(TAG, "Crash of app " + app.processName 3603 + " running instrumentation " + app.instrumentationClass); 3604 Bundle info = new Bundle(); 3605 info.putString("shortMsg", "Process crashed."); 3606 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3607 } 3608 3609 if (!restarting) { 3610 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3611 // If there was nothing to resume, and we are not already 3612 // restarting this process, but there is a visible activity that 3613 // is hosted by the process... then make sure all visible 3614 // activities are running, taking care of restarting this 3615 // process. 3616 if (hasVisibleActivities) { 3617 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3618 } 3619 } 3620 } 3621 } 3622 3623 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3624 IBinder threadBinder = thread.asBinder(); 3625 // Find the application record. 3626 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3627 ProcessRecord rec = mLruProcesses.get(i); 3628 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3629 return i; 3630 } 3631 } 3632 return -1; 3633 } 3634 3635 final ProcessRecord getRecordForAppLocked( 3636 IApplicationThread thread) { 3637 if (thread == null) { 3638 return null; 3639 } 3640 3641 int appIndex = getLRURecordIndexForAppLocked(thread); 3642 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3643 } 3644 3645 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3646 // If there are no longer any background processes running, 3647 // and the app that died was not running instrumentation, 3648 // then tell everyone we are now low on memory. 3649 boolean haveBg = false; 3650 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3651 ProcessRecord rec = mLruProcesses.get(i); 3652 if (rec.thread != null 3653 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3654 haveBg = true; 3655 break; 3656 } 3657 } 3658 3659 if (!haveBg) { 3660 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3661 if (doReport) { 3662 long now = SystemClock.uptimeMillis(); 3663 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3664 doReport = false; 3665 } else { 3666 mLastMemUsageReportTime = now; 3667 } 3668 } 3669 final ArrayList<ProcessMemInfo> memInfos 3670 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3671 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3672 long now = SystemClock.uptimeMillis(); 3673 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3674 ProcessRecord rec = mLruProcesses.get(i); 3675 if (rec == dyingProc || rec.thread == null) { 3676 continue; 3677 } 3678 if (doReport) { 3679 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3680 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3681 } 3682 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3683 // The low memory report is overriding any current 3684 // state for a GC request. Make sure to do 3685 // heavy/important/visible/foreground processes first. 3686 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3687 rec.lastRequestedGc = 0; 3688 } else { 3689 rec.lastRequestedGc = rec.lastLowMemory; 3690 } 3691 rec.reportLowMemory = true; 3692 rec.lastLowMemory = now; 3693 mProcessesToGc.remove(rec); 3694 addProcessToGcListLocked(rec); 3695 } 3696 } 3697 if (doReport) { 3698 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3699 mHandler.sendMessage(msg); 3700 } 3701 scheduleAppGcsLocked(); 3702 } 3703 } 3704 3705 final void appDiedLocked(ProcessRecord app, int pid, 3706 IApplicationThread thread) { 3707 3708 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3709 synchronized (stats) { 3710 stats.noteProcessDiedLocked(app.info.uid, pid); 3711 } 3712 3713 // Clean up already done if the process has been re-started. 3714 if (app.pid == pid && app.thread != null && 3715 app.thread.asBinder() == thread.asBinder()) { 3716 boolean doLowMem = app.instrumentationClass == null; 3717 boolean doOomAdj = doLowMem; 3718 if (!app.killedByAm) { 3719 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3720 + ") has died."); 3721 mAllowLowerMemLevel = true; 3722 } else { 3723 // Note that we always want to do oom adj to update our state with the 3724 // new number of procs. 3725 mAllowLowerMemLevel = false; 3726 doLowMem = false; 3727 } 3728 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3729 if (DEBUG_CLEANUP) Slog.v( 3730 TAG, "Dying app: " + app + ", pid: " + pid 3731 + ", thread: " + thread.asBinder()); 3732 handleAppDiedLocked(app, false, true); 3733 3734 if (doOomAdj) { 3735 updateOomAdjLocked(); 3736 } 3737 if (doLowMem) { 3738 doLowMemReportIfNeededLocked(app); 3739 } 3740 } else if (app.pid != pid) { 3741 // A new process has already been started. 3742 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3743 + ") has died and restarted (pid " + app.pid + ")."); 3744 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3745 } else if (DEBUG_PROCESSES) { 3746 Slog.d(TAG, "Received spurious death notification for thread " 3747 + thread.asBinder()); 3748 } 3749 } 3750 3751 /** 3752 * If a stack trace dump file is configured, dump process stack traces. 3753 * @param clearTraces causes the dump file to be erased prior to the new 3754 * traces being written, if true; when false, the new traces will be 3755 * appended to any existing file content. 3756 * @param firstPids of dalvik VM processes to dump stack traces for first 3757 * @param lastPids of dalvik VM processes to dump stack traces for last 3758 * @param nativeProcs optional list of native process names to dump stack crawls 3759 * @return file containing stack traces, or null if no dump file is configured 3760 */ 3761 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3762 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3763 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3764 if (tracesPath == null || tracesPath.length() == 0) { 3765 return null; 3766 } 3767 3768 File tracesFile = new File(tracesPath); 3769 try { 3770 File tracesDir = tracesFile.getParentFile(); 3771 if (!tracesDir.exists()) { 3772 tracesFile.mkdirs(); 3773 if (!SELinux.restorecon(tracesDir)) { 3774 return null; 3775 } 3776 } 3777 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3778 3779 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3780 tracesFile.createNewFile(); 3781 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3782 } catch (IOException e) { 3783 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3784 return null; 3785 } 3786 3787 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3788 return tracesFile; 3789 } 3790 3791 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3792 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3793 // Use a FileObserver to detect when traces finish writing. 3794 // The order of traces is considered important to maintain for legibility. 3795 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3796 @Override 3797 public synchronized void onEvent(int event, String path) { notify(); } 3798 }; 3799 3800 try { 3801 observer.startWatching(); 3802 3803 // First collect all of the stacks of the most important pids. 3804 if (firstPids != null) { 3805 try { 3806 int num = firstPids.size(); 3807 for (int i = 0; i < num; i++) { 3808 synchronized (observer) { 3809 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3810 observer.wait(200); // Wait for write-close, give up after 200msec 3811 } 3812 } 3813 } catch (InterruptedException e) { 3814 Log.wtf(TAG, e); 3815 } 3816 } 3817 3818 // Next collect the stacks of the native pids 3819 if (nativeProcs != null) { 3820 int[] pids = Process.getPidsForCommands(nativeProcs); 3821 if (pids != null) { 3822 for (int pid : pids) { 3823 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3824 } 3825 } 3826 } 3827 3828 // Lastly, measure CPU usage. 3829 if (processCpuTracker != null) { 3830 processCpuTracker.init(); 3831 System.gc(); 3832 processCpuTracker.update(); 3833 try { 3834 synchronized (processCpuTracker) { 3835 processCpuTracker.wait(500); // measure over 1/2 second. 3836 } 3837 } catch (InterruptedException e) { 3838 } 3839 processCpuTracker.update(); 3840 3841 // We'll take the stack crawls of just the top apps using CPU. 3842 final int N = processCpuTracker.countWorkingStats(); 3843 int numProcs = 0; 3844 for (int i=0; i<N && numProcs<5; i++) { 3845 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3846 if (lastPids.indexOfKey(stats.pid) >= 0) { 3847 numProcs++; 3848 try { 3849 synchronized (observer) { 3850 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3851 observer.wait(200); // Wait for write-close, give up after 200msec 3852 } 3853 } catch (InterruptedException e) { 3854 Log.wtf(TAG, e); 3855 } 3856 3857 } 3858 } 3859 } 3860 } finally { 3861 observer.stopWatching(); 3862 } 3863 } 3864 3865 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3866 if (true || IS_USER_BUILD) { 3867 return; 3868 } 3869 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3870 if (tracesPath == null || tracesPath.length() == 0) { 3871 return; 3872 } 3873 3874 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3875 StrictMode.allowThreadDiskWrites(); 3876 try { 3877 final File tracesFile = new File(tracesPath); 3878 final File tracesDir = tracesFile.getParentFile(); 3879 final File tracesTmp = new File(tracesDir, "__tmp__"); 3880 try { 3881 if (!tracesDir.exists()) { 3882 tracesFile.mkdirs(); 3883 if (!SELinux.restorecon(tracesDir.getPath())) { 3884 return; 3885 } 3886 } 3887 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3888 3889 if (tracesFile.exists()) { 3890 tracesTmp.delete(); 3891 tracesFile.renameTo(tracesTmp); 3892 } 3893 StringBuilder sb = new StringBuilder(); 3894 Time tobj = new Time(); 3895 tobj.set(System.currentTimeMillis()); 3896 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3897 sb.append(": "); 3898 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3899 sb.append(" since "); 3900 sb.append(msg); 3901 FileOutputStream fos = new FileOutputStream(tracesFile); 3902 fos.write(sb.toString().getBytes()); 3903 if (app == null) { 3904 fos.write("\n*** No application process!".getBytes()); 3905 } 3906 fos.close(); 3907 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3908 } catch (IOException e) { 3909 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3910 return; 3911 } 3912 3913 if (app != null) { 3914 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3915 firstPids.add(app.pid); 3916 dumpStackTraces(tracesPath, firstPids, null, null, null); 3917 } 3918 3919 File lastTracesFile = null; 3920 File curTracesFile = null; 3921 for (int i=9; i>=0; i--) { 3922 String name = String.format(Locale.US, "slow%02d.txt", i); 3923 curTracesFile = new File(tracesDir, name); 3924 if (curTracesFile.exists()) { 3925 if (lastTracesFile != null) { 3926 curTracesFile.renameTo(lastTracesFile); 3927 } else { 3928 curTracesFile.delete(); 3929 } 3930 } 3931 lastTracesFile = curTracesFile; 3932 } 3933 tracesFile.renameTo(curTracesFile); 3934 if (tracesTmp.exists()) { 3935 tracesTmp.renameTo(tracesFile); 3936 } 3937 } finally { 3938 StrictMode.setThreadPolicy(oldPolicy); 3939 } 3940 } 3941 3942 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3943 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3944 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3945 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3946 3947 if (mController != null) { 3948 try { 3949 // 0 == continue, -1 = kill process immediately 3950 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3951 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3952 } catch (RemoteException e) { 3953 mController = null; 3954 Watchdog.getInstance().setActivityController(null); 3955 } 3956 } 3957 3958 long anrTime = SystemClock.uptimeMillis(); 3959 if (MONITOR_CPU_USAGE) { 3960 updateCpuStatsNow(); 3961 } 3962 3963 synchronized (this) { 3964 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3965 if (mShuttingDown) { 3966 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3967 return; 3968 } else if (app.notResponding) { 3969 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3970 return; 3971 } else if (app.crashing) { 3972 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3973 return; 3974 } 3975 3976 // In case we come through here for the same app before completing 3977 // this one, mark as anring now so we will bail out. 3978 app.notResponding = true; 3979 3980 // Log the ANR to the event log. 3981 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3982 app.processName, app.info.flags, annotation); 3983 3984 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3985 firstPids.add(app.pid); 3986 3987 int parentPid = app.pid; 3988 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3989 if (parentPid != app.pid) firstPids.add(parentPid); 3990 3991 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3992 3993 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3994 ProcessRecord r = mLruProcesses.get(i); 3995 if (r != null && r.thread != null) { 3996 int pid = r.pid; 3997 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3998 if (r.persistent) { 3999 firstPids.add(pid); 4000 } else { 4001 lastPids.put(pid, Boolean.TRUE); 4002 } 4003 } 4004 } 4005 } 4006 } 4007 4008 // Log the ANR to the main log. 4009 StringBuilder info = new StringBuilder(); 4010 info.setLength(0); 4011 info.append("ANR in ").append(app.processName); 4012 if (activity != null && activity.shortComponentName != null) { 4013 info.append(" (").append(activity.shortComponentName).append(")"); 4014 } 4015 info.append("\n"); 4016 info.append("PID: ").append(app.pid).append("\n"); 4017 if (annotation != null) { 4018 info.append("Reason: ").append(annotation).append("\n"); 4019 } 4020 if (parent != null && parent != activity) { 4021 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4022 } 4023 4024 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4025 4026 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4027 NATIVE_STACKS_OF_INTEREST); 4028 4029 String cpuInfo = null; 4030 if (MONITOR_CPU_USAGE) { 4031 updateCpuStatsNow(); 4032 synchronized (mProcessCpuThread) { 4033 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4034 } 4035 info.append(processCpuTracker.printCurrentLoad()); 4036 info.append(cpuInfo); 4037 } 4038 4039 info.append(processCpuTracker.printCurrentState(anrTime)); 4040 4041 Slog.e(TAG, info.toString()); 4042 if (tracesFile == null) { 4043 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4044 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4045 } 4046 4047 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4048 cpuInfo, tracesFile, null); 4049 4050 if (mController != null) { 4051 try { 4052 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4053 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4054 if (res != 0) { 4055 if (res < 0 && app.pid != MY_PID) { 4056 Process.killProcess(app.pid); 4057 } else { 4058 synchronized (this) { 4059 mServices.scheduleServiceTimeoutLocked(app); 4060 } 4061 } 4062 return; 4063 } 4064 } catch (RemoteException e) { 4065 mController = null; 4066 Watchdog.getInstance().setActivityController(null); 4067 } 4068 } 4069 4070 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4071 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4072 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4073 4074 synchronized (this) { 4075 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4076 killUnneededProcessLocked(app, "background ANR"); 4077 return; 4078 } 4079 4080 // Set the app's notResponding state, and look up the errorReportReceiver 4081 makeAppNotRespondingLocked(app, 4082 activity != null ? activity.shortComponentName : null, 4083 annotation != null ? "ANR " + annotation : "ANR", 4084 info.toString()); 4085 4086 // Bring up the infamous App Not Responding dialog 4087 Message msg = Message.obtain(); 4088 HashMap<String, Object> map = new HashMap<String, Object>(); 4089 msg.what = SHOW_NOT_RESPONDING_MSG; 4090 msg.obj = map; 4091 msg.arg1 = aboveSystem ? 1 : 0; 4092 map.put("app", app); 4093 if (activity != null) { 4094 map.put("activity", activity); 4095 } 4096 4097 mHandler.sendMessage(msg); 4098 } 4099 } 4100 4101 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4102 if (!mLaunchWarningShown) { 4103 mLaunchWarningShown = true; 4104 mHandler.post(new Runnable() { 4105 @Override 4106 public void run() { 4107 synchronized (ActivityManagerService.this) { 4108 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4109 d.show(); 4110 mHandler.postDelayed(new Runnable() { 4111 @Override 4112 public void run() { 4113 synchronized (ActivityManagerService.this) { 4114 d.dismiss(); 4115 mLaunchWarningShown = false; 4116 } 4117 } 4118 }, 4000); 4119 } 4120 } 4121 }); 4122 } 4123 } 4124 4125 @Override 4126 public boolean clearApplicationUserData(final String packageName, 4127 final IPackageDataObserver observer, int userId) { 4128 enforceNotIsolatedCaller("clearApplicationUserData"); 4129 int uid = Binder.getCallingUid(); 4130 int pid = Binder.getCallingPid(); 4131 userId = handleIncomingUser(pid, uid, 4132 userId, false, true, "clearApplicationUserData", null); 4133 long callingId = Binder.clearCallingIdentity(); 4134 try { 4135 IPackageManager pm = AppGlobals.getPackageManager(); 4136 int pkgUid = -1; 4137 synchronized(this) { 4138 try { 4139 pkgUid = pm.getPackageUid(packageName, userId); 4140 } catch (RemoteException e) { 4141 } 4142 if (pkgUid == -1) { 4143 Slog.w(TAG, "Invalid packageName: " + packageName); 4144 if (observer != null) { 4145 try { 4146 observer.onRemoveCompleted(packageName, false); 4147 } catch (RemoteException e) { 4148 Slog.i(TAG, "Observer no longer exists."); 4149 } 4150 } 4151 return false; 4152 } 4153 if (uid == pkgUid || checkComponentPermission( 4154 android.Manifest.permission.CLEAR_APP_USER_DATA, 4155 pid, uid, -1, true) 4156 == PackageManager.PERMISSION_GRANTED) { 4157 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4158 } else { 4159 throw new SecurityException("PID " + pid + " does not have permission " 4160 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4161 + " of package " + packageName); 4162 } 4163 } 4164 4165 try { 4166 // Clear application user data 4167 pm.clearApplicationUserData(packageName, observer, userId); 4168 4169 // Remove all permissions granted from/to this package 4170 removeUriPermissionsForPackageLocked(packageName, userId, true); 4171 4172 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4173 Uri.fromParts("package", packageName, null)); 4174 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4175 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4176 null, null, 0, null, null, null, false, false, userId); 4177 } catch (RemoteException e) { 4178 } 4179 } finally { 4180 Binder.restoreCallingIdentity(callingId); 4181 } 4182 return true; 4183 } 4184 4185 @Override 4186 public void killBackgroundProcesses(final String packageName, int userId) { 4187 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4188 != PackageManager.PERMISSION_GRANTED && 4189 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4190 != PackageManager.PERMISSION_GRANTED) { 4191 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4192 + Binder.getCallingPid() 4193 + ", uid=" + Binder.getCallingUid() 4194 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4195 Slog.w(TAG, msg); 4196 throw new SecurityException(msg); 4197 } 4198 4199 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4200 userId, true, true, "killBackgroundProcesses", null); 4201 long callingId = Binder.clearCallingIdentity(); 4202 try { 4203 IPackageManager pm = AppGlobals.getPackageManager(); 4204 synchronized(this) { 4205 int appId = -1; 4206 try { 4207 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4208 } catch (RemoteException e) { 4209 } 4210 if (appId == -1) { 4211 Slog.w(TAG, "Invalid packageName: " + packageName); 4212 return; 4213 } 4214 killPackageProcessesLocked(packageName, appId, userId, 4215 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4216 } 4217 } finally { 4218 Binder.restoreCallingIdentity(callingId); 4219 } 4220 } 4221 4222 @Override 4223 public void killAllBackgroundProcesses() { 4224 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4225 != PackageManager.PERMISSION_GRANTED) { 4226 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4227 + Binder.getCallingPid() 4228 + ", uid=" + Binder.getCallingUid() 4229 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4230 Slog.w(TAG, msg); 4231 throw new SecurityException(msg); 4232 } 4233 4234 long callingId = Binder.clearCallingIdentity(); 4235 try { 4236 synchronized(this) { 4237 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4238 final int NP = mProcessNames.getMap().size(); 4239 for (int ip=0; ip<NP; ip++) { 4240 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4241 final int NA = apps.size(); 4242 for (int ia=0; ia<NA; ia++) { 4243 ProcessRecord app = apps.valueAt(ia); 4244 if (app.persistent) { 4245 // we don't kill persistent processes 4246 continue; 4247 } 4248 if (app.removed) { 4249 procs.add(app); 4250 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4251 app.removed = true; 4252 procs.add(app); 4253 } 4254 } 4255 } 4256 4257 int N = procs.size(); 4258 for (int i=0; i<N; i++) { 4259 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4260 } 4261 mAllowLowerMemLevel = true; 4262 updateOomAdjLocked(); 4263 doLowMemReportIfNeededLocked(null); 4264 } 4265 } finally { 4266 Binder.restoreCallingIdentity(callingId); 4267 } 4268 } 4269 4270 @Override 4271 public void forceStopPackage(final String packageName, int userId) { 4272 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4273 != PackageManager.PERMISSION_GRANTED) { 4274 String msg = "Permission Denial: forceStopPackage() from pid=" 4275 + Binder.getCallingPid() 4276 + ", uid=" + Binder.getCallingUid() 4277 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4278 Slog.w(TAG, msg); 4279 throw new SecurityException(msg); 4280 } 4281 final int callingPid = Binder.getCallingPid(); 4282 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4283 userId, true, true, "forceStopPackage", null); 4284 long callingId = Binder.clearCallingIdentity(); 4285 try { 4286 IPackageManager pm = AppGlobals.getPackageManager(); 4287 synchronized(this) { 4288 int[] users = userId == UserHandle.USER_ALL 4289 ? getUsersLocked() : new int[] { userId }; 4290 for (int user : users) { 4291 int pkgUid = -1; 4292 try { 4293 pkgUid = pm.getPackageUid(packageName, user); 4294 } catch (RemoteException e) { 4295 } 4296 if (pkgUid == -1) { 4297 Slog.w(TAG, "Invalid packageName: " + packageName); 4298 continue; 4299 } 4300 try { 4301 pm.setPackageStoppedState(packageName, true, user); 4302 } catch (RemoteException e) { 4303 } catch (IllegalArgumentException e) { 4304 Slog.w(TAG, "Failed trying to unstop package " 4305 + packageName + ": " + e); 4306 } 4307 if (isUserRunningLocked(user, false)) { 4308 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4309 } 4310 } 4311 } 4312 } finally { 4313 Binder.restoreCallingIdentity(callingId); 4314 } 4315 } 4316 4317 /* 4318 * The pkg name and app id have to be specified. 4319 */ 4320 @Override 4321 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4322 if (pkg == null) { 4323 return; 4324 } 4325 // Make sure the uid is valid. 4326 if (appid < 0) { 4327 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4328 return; 4329 } 4330 int callerUid = Binder.getCallingUid(); 4331 // Only the system server can kill an application 4332 if (callerUid == Process.SYSTEM_UID) { 4333 // Post an aysnc message to kill the application 4334 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4335 msg.arg1 = appid; 4336 msg.arg2 = 0; 4337 Bundle bundle = new Bundle(); 4338 bundle.putString("pkg", pkg); 4339 bundle.putString("reason", reason); 4340 msg.obj = bundle; 4341 mHandler.sendMessage(msg); 4342 } else { 4343 throw new SecurityException(callerUid + " cannot kill pkg: " + 4344 pkg); 4345 } 4346 } 4347 4348 @Override 4349 public void closeSystemDialogs(String reason) { 4350 enforceNotIsolatedCaller("closeSystemDialogs"); 4351 4352 final int pid = Binder.getCallingPid(); 4353 final int uid = Binder.getCallingUid(); 4354 final long origId = Binder.clearCallingIdentity(); 4355 try { 4356 synchronized (this) { 4357 // Only allow this from foreground processes, so that background 4358 // applications can't abuse it to prevent system UI from being shown. 4359 if (uid >= Process.FIRST_APPLICATION_UID) { 4360 ProcessRecord proc; 4361 synchronized (mPidsSelfLocked) { 4362 proc = mPidsSelfLocked.get(pid); 4363 } 4364 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4365 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4366 + " from background process " + proc); 4367 return; 4368 } 4369 } 4370 closeSystemDialogsLocked(reason); 4371 } 4372 } finally { 4373 Binder.restoreCallingIdentity(origId); 4374 } 4375 } 4376 4377 void closeSystemDialogsLocked(String reason) { 4378 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4379 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4380 | Intent.FLAG_RECEIVER_FOREGROUND); 4381 if (reason != null) { 4382 intent.putExtra("reason", reason); 4383 } 4384 mWindowManager.closeSystemDialogs(reason); 4385 4386 mStackSupervisor.closeSystemDialogsLocked(); 4387 4388 broadcastIntentLocked(null, null, intent, null, 4389 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4390 Process.SYSTEM_UID, UserHandle.USER_ALL); 4391 } 4392 4393 @Override 4394 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4395 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4396 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4397 for (int i=pids.length-1; i>=0; i--) { 4398 ProcessRecord proc; 4399 int oomAdj; 4400 synchronized (this) { 4401 synchronized (mPidsSelfLocked) { 4402 proc = mPidsSelfLocked.get(pids[i]); 4403 oomAdj = proc != null ? proc.setAdj : 0; 4404 } 4405 } 4406 infos[i] = new Debug.MemoryInfo(); 4407 Debug.getMemoryInfo(pids[i], infos[i]); 4408 if (proc != null) { 4409 synchronized (this) { 4410 if (proc.thread != null && proc.setAdj == oomAdj) { 4411 // Record this for posterity if the process has been stable. 4412 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4413 infos[i].getTotalUss(), false, proc.pkgList); 4414 } 4415 } 4416 } 4417 } 4418 return infos; 4419 } 4420 4421 @Override 4422 public long[] getProcessPss(int[] pids) { 4423 enforceNotIsolatedCaller("getProcessPss"); 4424 long[] pss = new long[pids.length]; 4425 for (int i=pids.length-1; i>=0; i--) { 4426 ProcessRecord proc; 4427 int oomAdj; 4428 synchronized (this) { 4429 synchronized (mPidsSelfLocked) { 4430 proc = mPidsSelfLocked.get(pids[i]); 4431 oomAdj = proc != null ? proc.setAdj : 0; 4432 } 4433 } 4434 long[] tmpUss = new long[1]; 4435 pss[i] = Debug.getPss(pids[i], tmpUss); 4436 if (proc != null) { 4437 synchronized (this) { 4438 if (proc.thread != null && proc.setAdj == oomAdj) { 4439 // Record this for posterity if the process has been stable. 4440 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4441 } 4442 } 4443 } 4444 } 4445 return pss; 4446 } 4447 4448 @Override 4449 public void killApplicationProcess(String processName, int uid) { 4450 if (processName == null) { 4451 return; 4452 } 4453 4454 int callerUid = Binder.getCallingUid(); 4455 // Only the system server can kill an application 4456 if (callerUid == Process.SYSTEM_UID) { 4457 synchronized (this) { 4458 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4459 if (app != null && app.thread != null) { 4460 try { 4461 app.thread.scheduleSuicide(); 4462 } catch (RemoteException e) { 4463 // If the other end already died, then our work here is done. 4464 } 4465 } else { 4466 Slog.w(TAG, "Process/uid not found attempting kill of " 4467 + processName + " / " + uid); 4468 } 4469 } 4470 } else { 4471 throw new SecurityException(callerUid + " cannot kill app process: " + 4472 processName); 4473 } 4474 } 4475 4476 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4477 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4478 false, true, false, UserHandle.getUserId(uid), reason); 4479 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4480 Uri.fromParts("package", packageName, null)); 4481 if (!mProcessesReady) { 4482 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4483 | Intent.FLAG_RECEIVER_FOREGROUND); 4484 } 4485 intent.putExtra(Intent.EXTRA_UID, uid); 4486 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4487 broadcastIntentLocked(null, null, intent, 4488 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4489 false, false, 4490 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4491 } 4492 4493 private void forceStopUserLocked(int userId, String reason) { 4494 forceStopPackageLocked(null, -1, false, false, true, false, userId, reason); 4495 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4496 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4497 | Intent.FLAG_RECEIVER_FOREGROUND); 4498 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4499 broadcastIntentLocked(null, null, intent, 4500 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4501 false, false, 4502 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4503 } 4504 4505 private final boolean killPackageProcessesLocked(String packageName, int appId, 4506 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4507 boolean doit, boolean evenPersistent, String reason) { 4508 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4509 4510 // Remove all processes this package may have touched: all with the 4511 // same UID (except for the system or root user), and all whose name 4512 // matches the package name. 4513 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4514 final int NP = mProcessNames.getMap().size(); 4515 for (int ip=0; ip<NP; ip++) { 4516 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4517 final int NA = apps.size(); 4518 for (int ia=0; ia<NA; ia++) { 4519 ProcessRecord app = apps.valueAt(ia); 4520 if (app.persistent && !evenPersistent) { 4521 // we don't kill persistent processes 4522 continue; 4523 } 4524 if (app.removed) { 4525 if (doit) { 4526 procs.add(app); 4527 } 4528 continue; 4529 } 4530 4531 // Skip process if it doesn't meet our oom adj requirement. 4532 if (app.setAdj < minOomAdj) { 4533 continue; 4534 } 4535 4536 // If no package is specified, we call all processes under the 4537 // give user id. 4538 if (packageName == null) { 4539 if (app.userId != userId) { 4540 continue; 4541 } 4542 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4543 continue; 4544 } 4545 // Package has been specified, we want to hit all processes 4546 // that match it. We need to qualify this by the processes 4547 // that are running under the specified app and user ID. 4548 } else { 4549 if (UserHandle.getAppId(app.uid) != appId) { 4550 continue; 4551 } 4552 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4553 continue; 4554 } 4555 if (!app.pkgList.containsKey(packageName)) { 4556 continue; 4557 } 4558 } 4559 4560 // Process has passed all conditions, kill it! 4561 if (!doit) { 4562 return true; 4563 } 4564 app.removed = true; 4565 procs.add(app); 4566 } 4567 } 4568 4569 int N = procs.size(); 4570 for (int i=0; i<N; i++) { 4571 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4572 } 4573 updateOomAdjLocked(); 4574 return N > 0; 4575 } 4576 4577 private final boolean forceStopPackageLocked(String name, int appId, 4578 boolean callerWillRestart, boolean purgeCache, boolean doit, 4579 boolean evenPersistent, int userId, String reason) { 4580 int i; 4581 int N; 4582 4583 if (userId == UserHandle.USER_ALL && name == null) { 4584 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4585 } 4586 4587 if (appId < 0 && name != null) { 4588 try { 4589 appId = UserHandle.getAppId( 4590 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4591 } catch (RemoteException e) { 4592 } 4593 } 4594 4595 if (doit) { 4596 if (name != null) { 4597 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4598 + " user=" + userId + ": " + reason); 4599 } else { 4600 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4601 } 4602 4603 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4604 for (int ip=pmap.size()-1; ip>=0; ip--) { 4605 SparseArray<Long> ba = pmap.valueAt(ip); 4606 for (i=ba.size()-1; i>=0; i--) { 4607 boolean remove = false; 4608 final int entUid = ba.keyAt(i); 4609 if (name != null) { 4610 if (userId == UserHandle.USER_ALL) { 4611 if (UserHandle.getAppId(entUid) == appId) { 4612 remove = true; 4613 } 4614 } else { 4615 if (entUid == UserHandle.getUid(userId, appId)) { 4616 remove = true; 4617 } 4618 } 4619 } else if (UserHandle.getUserId(entUid) == userId) { 4620 remove = true; 4621 } 4622 if (remove) { 4623 ba.removeAt(i); 4624 } 4625 } 4626 if (ba.size() == 0) { 4627 pmap.removeAt(ip); 4628 } 4629 } 4630 } 4631 4632 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4633 -100, callerWillRestart, true, doit, evenPersistent, 4634 name == null ? ("stop user " + userId) : ("stop " + name)); 4635 4636 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4637 if (!doit) { 4638 return true; 4639 } 4640 didSomething = true; 4641 } 4642 4643 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4644 if (!doit) { 4645 return true; 4646 } 4647 didSomething = true; 4648 } 4649 4650 if (name == null) { 4651 // Remove all sticky broadcasts from this user. 4652 mStickyBroadcasts.remove(userId); 4653 } 4654 4655 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4656 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4657 userId, providers)) { 4658 if (!doit) { 4659 return true; 4660 } 4661 didSomething = true; 4662 } 4663 N = providers.size(); 4664 for (i=0; i<N; i++) { 4665 removeDyingProviderLocked(null, providers.get(i), true); 4666 } 4667 4668 // Remove transient permissions granted from/to this package/user 4669 removeUriPermissionsForPackageLocked(name, userId, false); 4670 4671 if (name == null) { 4672 // Remove pending intents. For now we only do this when force 4673 // stopping users, because we have some problems when doing this 4674 // for packages -- app widgets are not currently cleaned up for 4675 // such packages, so they can be left with bad pending intents. 4676 if (mIntentSenderRecords.size() > 0) { 4677 Iterator<WeakReference<PendingIntentRecord>> it 4678 = mIntentSenderRecords.values().iterator(); 4679 while (it.hasNext()) { 4680 WeakReference<PendingIntentRecord> wpir = it.next(); 4681 if (wpir == null) { 4682 it.remove(); 4683 continue; 4684 } 4685 PendingIntentRecord pir = wpir.get(); 4686 if (pir == null) { 4687 it.remove(); 4688 continue; 4689 } 4690 if (name == null) { 4691 // Stopping user, remove all objects for the user. 4692 if (pir.key.userId != userId) { 4693 // Not the same user, skip it. 4694 continue; 4695 } 4696 } else { 4697 if (UserHandle.getAppId(pir.uid) != appId) { 4698 // Different app id, skip it. 4699 continue; 4700 } 4701 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4702 // Different user, skip it. 4703 continue; 4704 } 4705 if (!pir.key.packageName.equals(name)) { 4706 // Different package, skip it. 4707 continue; 4708 } 4709 } 4710 if (!doit) { 4711 return true; 4712 } 4713 didSomething = true; 4714 it.remove(); 4715 pir.canceled = true; 4716 if (pir.key.activity != null) { 4717 pir.key.activity.pendingResults.remove(pir.ref); 4718 } 4719 } 4720 } 4721 } 4722 4723 if (doit) { 4724 if (purgeCache && name != null) { 4725 AttributeCache ac = AttributeCache.instance(); 4726 if (ac != null) { 4727 ac.removePackage(name); 4728 } 4729 } 4730 if (mBooted) { 4731 mStackSupervisor.resumeTopActivitiesLocked(); 4732 mStackSupervisor.scheduleIdleLocked(); 4733 } 4734 } 4735 4736 return didSomething; 4737 } 4738 4739 private final boolean removeProcessLocked(ProcessRecord app, 4740 boolean callerWillRestart, boolean allowRestart, String reason) { 4741 final String name = app.processName; 4742 final int uid = app.uid; 4743 if (DEBUG_PROCESSES) Slog.d( 4744 TAG, "Force removing proc " + app.toShortString() + " (" + name 4745 + "/" + uid + ")"); 4746 4747 mProcessNames.remove(name, uid); 4748 mIsolatedProcesses.remove(app.uid); 4749 if (mHeavyWeightProcess == app) { 4750 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4751 mHeavyWeightProcess.userId, 0)); 4752 mHeavyWeightProcess = null; 4753 } 4754 boolean needRestart = false; 4755 if (app.pid > 0 && app.pid != MY_PID) { 4756 int pid = app.pid; 4757 synchronized (mPidsSelfLocked) { 4758 mPidsSelfLocked.remove(pid); 4759 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4760 } 4761 killUnneededProcessLocked(app, reason); 4762 handleAppDiedLocked(app, true, allowRestart); 4763 removeLruProcessLocked(app); 4764 4765 if (app.persistent && !app.isolated) { 4766 if (!callerWillRestart) { 4767 addAppLocked(app.info, false, null /* ABI override */); 4768 } else { 4769 needRestart = true; 4770 } 4771 } 4772 } else { 4773 mRemovedProcesses.add(app); 4774 } 4775 4776 return needRestart; 4777 } 4778 4779 private final void processStartTimedOutLocked(ProcessRecord app) { 4780 final int pid = app.pid; 4781 boolean gone = false; 4782 synchronized (mPidsSelfLocked) { 4783 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4784 if (knownApp != null && knownApp.thread == null) { 4785 mPidsSelfLocked.remove(pid); 4786 gone = true; 4787 } 4788 } 4789 4790 if (gone) { 4791 Slog.w(TAG, "Process " + app + " failed to attach"); 4792 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4793 pid, app.uid, app.processName); 4794 mProcessNames.remove(app.processName, app.uid); 4795 mIsolatedProcesses.remove(app.uid); 4796 if (mHeavyWeightProcess == app) { 4797 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4798 mHeavyWeightProcess.userId, 0)); 4799 mHeavyWeightProcess = null; 4800 } 4801 // Take care of any launching providers waiting for this process. 4802 checkAppInLaunchingProvidersLocked(app, true); 4803 // Take care of any services that are waiting for the process. 4804 mServices.processStartTimedOutLocked(app); 4805 killUnneededProcessLocked(app, "start timeout"); 4806 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4807 Slog.w(TAG, "Unattached app died before backup, skipping"); 4808 try { 4809 IBackupManager bm = IBackupManager.Stub.asInterface( 4810 ServiceManager.getService(Context.BACKUP_SERVICE)); 4811 bm.agentDisconnected(app.info.packageName); 4812 } catch (RemoteException e) { 4813 // Can't happen; the backup manager is local 4814 } 4815 } 4816 if (isPendingBroadcastProcessLocked(pid)) { 4817 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4818 skipPendingBroadcastLocked(pid); 4819 } 4820 } else { 4821 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4822 } 4823 } 4824 4825 private final boolean attachApplicationLocked(IApplicationThread thread, 4826 int pid) { 4827 4828 // Find the application record that is being attached... either via 4829 // the pid if we are running in multiple processes, or just pull the 4830 // next app record if we are emulating process with anonymous threads. 4831 ProcessRecord app; 4832 if (pid != MY_PID && pid >= 0) { 4833 synchronized (mPidsSelfLocked) { 4834 app = mPidsSelfLocked.get(pid); 4835 } 4836 } else { 4837 app = null; 4838 } 4839 4840 if (app == null) { 4841 Slog.w(TAG, "No pending application record for pid " + pid 4842 + " (IApplicationThread " + thread + "); dropping process"); 4843 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4844 if (pid > 0 && pid != MY_PID) { 4845 Process.killProcessQuiet(pid); 4846 } else { 4847 try { 4848 thread.scheduleExit(); 4849 } catch (Exception e) { 4850 // Ignore exceptions. 4851 } 4852 } 4853 return false; 4854 } 4855 4856 // If this application record is still attached to a previous 4857 // process, clean it up now. 4858 if (app.thread != null) { 4859 handleAppDiedLocked(app, true, true); 4860 } 4861 4862 // Tell the process all about itself. 4863 4864 if (localLOGV) Slog.v( 4865 TAG, "Binding process pid " + pid + " to record " + app); 4866 4867 final String processName = app.processName; 4868 try { 4869 AppDeathRecipient adr = new AppDeathRecipient( 4870 app, pid, thread); 4871 thread.asBinder().linkToDeath(adr, 0); 4872 app.deathRecipient = adr; 4873 } catch (RemoteException e) { 4874 app.resetPackageList(mProcessStats); 4875 startProcessLocked(app, "link fail", processName, null /* ABI override */); 4876 return false; 4877 } 4878 4879 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4880 4881 app.makeActive(thread, mProcessStats); 4882 app.curAdj = app.setAdj = -100; 4883 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4884 app.forcingToForeground = null; 4885 app.foregroundServices = false; 4886 app.hasShownUi = false; 4887 app.debugging = false; 4888 app.cached = false; 4889 4890 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4891 4892 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4893 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4894 4895 if (!normalMode) { 4896 Slog.i(TAG, "Launching preboot mode app: " + app); 4897 } 4898 4899 if (localLOGV) Slog.v( 4900 TAG, "New app record " + app 4901 + " thread=" + thread.asBinder() + " pid=" + pid); 4902 try { 4903 int testMode = IApplicationThread.DEBUG_OFF; 4904 if (mDebugApp != null && mDebugApp.equals(processName)) { 4905 testMode = mWaitForDebugger 4906 ? IApplicationThread.DEBUG_WAIT 4907 : IApplicationThread.DEBUG_ON; 4908 app.debugging = true; 4909 if (mDebugTransient) { 4910 mDebugApp = mOrigDebugApp; 4911 mWaitForDebugger = mOrigWaitForDebugger; 4912 } 4913 } 4914 String profileFile = app.instrumentationProfileFile; 4915 ParcelFileDescriptor profileFd = null; 4916 boolean profileAutoStop = false; 4917 if (mProfileApp != null && mProfileApp.equals(processName)) { 4918 mProfileProc = app; 4919 profileFile = mProfileFile; 4920 profileFd = mProfileFd; 4921 profileAutoStop = mAutoStopProfiler; 4922 } 4923 boolean enableOpenGlTrace = false; 4924 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4925 enableOpenGlTrace = true; 4926 mOpenGlTraceApp = null; 4927 } 4928 4929 // If the app is being launched for restore or full backup, set it up specially 4930 boolean isRestrictedBackupMode = false; 4931 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4932 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4933 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4934 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4935 } 4936 4937 ensurePackageDexOpt(app.instrumentationInfo != null 4938 ? app.instrumentationInfo.packageName 4939 : app.info.packageName); 4940 if (app.instrumentationClass != null) { 4941 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4942 } 4943 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4944 + processName + " with config " + mConfiguration); 4945 ApplicationInfo appInfo = app.instrumentationInfo != null 4946 ? app.instrumentationInfo : app.info; 4947 app.compat = compatibilityInfoForPackageLocked(appInfo); 4948 if (profileFd != null) { 4949 profileFd = profileFd.dup(); 4950 } 4951 thread.bindApplication(processName, appInfo, providers, 4952 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4953 app.instrumentationArguments, app.instrumentationWatcher, 4954 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4955 isRestrictedBackupMode || !normalMode, app.persistent, 4956 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4957 mCoreSettingsObserver.getCoreSettingsLocked()); 4958 updateLruProcessLocked(app, false, null); 4959 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4960 } catch (Exception e) { 4961 // todo: Yikes! What should we do? For now we will try to 4962 // start another process, but that could easily get us in 4963 // an infinite loop of restarting processes... 4964 Slog.w(TAG, "Exception thrown during bind!", e); 4965 4966 app.resetPackageList(mProcessStats); 4967 app.unlinkDeathRecipient(); 4968 startProcessLocked(app, "bind fail", processName, null /* ABI override */); 4969 return false; 4970 } 4971 4972 // Remove this record from the list of starting applications. 4973 mPersistentStartingProcesses.remove(app); 4974 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4975 "Attach application locked removing on hold: " + app); 4976 mProcessesOnHold.remove(app); 4977 4978 boolean badApp = false; 4979 boolean didSomething = false; 4980 4981 // See if the top visible activity is waiting to run in this process... 4982 if (normalMode) { 4983 try { 4984 if (mStackSupervisor.attachApplicationLocked(app)) { 4985 didSomething = true; 4986 } 4987 } catch (Exception e) { 4988 badApp = true; 4989 } 4990 } 4991 4992 // Find any services that should be running in this process... 4993 if (!badApp) { 4994 try { 4995 didSomething |= mServices.attachApplicationLocked(app, processName); 4996 } catch (Exception e) { 4997 badApp = true; 4998 } 4999 } 5000 5001 // Check if a next-broadcast receiver is in this process... 5002 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5003 try { 5004 didSomething |= sendPendingBroadcastsLocked(app); 5005 } catch (Exception e) { 5006 // If the app died trying to launch the receiver we declare it 'bad' 5007 badApp = true; 5008 } 5009 } 5010 5011 // Check whether the next backup agent is in this process... 5012 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5013 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5014 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5015 try { 5016 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5017 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5018 mBackupTarget.backupMode); 5019 } catch (Exception e) { 5020 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5021 e.printStackTrace(); 5022 } 5023 } 5024 5025 if (badApp) { 5026 // todo: Also need to kill application to deal with all 5027 // kinds of exceptions. 5028 handleAppDiedLocked(app, false, true); 5029 return false; 5030 } 5031 5032 if (!didSomething) { 5033 updateOomAdjLocked(); 5034 } 5035 5036 return true; 5037 } 5038 5039 @Override 5040 public final void attachApplication(IApplicationThread thread) { 5041 synchronized (this) { 5042 int callingPid = Binder.getCallingPid(); 5043 final long origId = Binder.clearCallingIdentity(); 5044 attachApplicationLocked(thread, callingPid); 5045 Binder.restoreCallingIdentity(origId); 5046 } 5047 } 5048 5049 @Override 5050 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5051 final long origId = Binder.clearCallingIdentity(); 5052 synchronized (this) { 5053 ActivityStack stack = ActivityRecord.getStackLocked(token); 5054 if (stack != null) { 5055 ActivityRecord r = 5056 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5057 if (stopProfiling) { 5058 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5059 try { 5060 mProfileFd.close(); 5061 } catch (IOException e) { 5062 } 5063 clearProfilerLocked(); 5064 } 5065 } 5066 } 5067 } 5068 Binder.restoreCallingIdentity(origId); 5069 } 5070 5071 void enableScreenAfterBoot() { 5072 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5073 SystemClock.uptimeMillis()); 5074 mWindowManager.enableScreenAfterBoot(); 5075 5076 synchronized (this) { 5077 updateEventDispatchingLocked(); 5078 } 5079 } 5080 5081 @Override 5082 public void showBootMessage(final CharSequence msg, final boolean always) { 5083 enforceNotIsolatedCaller("showBootMessage"); 5084 mWindowManager.showBootMessage(msg, always); 5085 } 5086 5087 @Override 5088 public void dismissKeyguardOnNextActivity() { 5089 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5090 final long token = Binder.clearCallingIdentity(); 5091 try { 5092 synchronized (this) { 5093 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5094 if (mLockScreenShown) { 5095 mLockScreenShown = false; 5096 comeOutOfSleepIfNeededLocked(); 5097 } 5098 mStackSupervisor.setDismissKeyguard(true); 5099 } 5100 } finally { 5101 Binder.restoreCallingIdentity(token); 5102 } 5103 } 5104 5105 final void finishBooting() { 5106 IntentFilter pkgFilter = new IntentFilter(); 5107 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5108 pkgFilter.addDataScheme("package"); 5109 mContext.registerReceiver(new BroadcastReceiver() { 5110 @Override 5111 public void onReceive(Context context, Intent intent) { 5112 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5113 if (pkgs != null) { 5114 for (String pkg : pkgs) { 5115 synchronized (ActivityManagerService.this) { 5116 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0, 5117 "finished booting")) { 5118 setResultCode(Activity.RESULT_OK); 5119 return; 5120 } 5121 } 5122 } 5123 } 5124 } 5125 }, pkgFilter); 5126 5127 synchronized (this) { 5128 // Ensure that any processes we had put on hold are now started 5129 // up. 5130 final int NP = mProcessesOnHold.size(); 5131 if (NP > 0) { 5132 ArrayList<ProcessRecord> procs = 5133 new ArrayList<ProcessRecord>(mProcessesOnHold); 5134 for (int ip=0; ip<NP; ip++) { 5135 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5136 + procs.get(ip)); 5137 startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */); 5138 } 5139 } 5140 5141 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5142 // Start looking for apps that are abusing wake locks. 5143 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5144 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5145 // Tell anyone interested that we are done booting! 5146 SystemProperties.set("sys.boot_completed", "1"); 5147 SystemProperties.set("dev.bootcomplete", "1"); 5148 for (int i=0; i<mStartedUsers.size(); i++) { 5149 UserStartedState uss = mStartedUsers.valueAt(i); 5150 if (uss.mState == UserStartedState.STATE_BOOTING) { 5151 uss.mState = UserStartedState.STATE_RUNNING; 5152 final int userId = mStartedUsers.keyAt(i); 5153 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5154 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5155 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5156 broadcastIntentLocked(null, null, intent, null, 5157 new IIntentReceiver.Stub() { 5158 @Override 5159 public void performReceive(Intent intent, int resultCode, 5160 String data, Bundle extras, boolean ordered, 5161 boolean sticky, int sendingUser) { 5162 synchronized (ActivityManagerService.this) { 5163 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5164 true, false); 5165 } 5166 } 5167 }, 5168 0, null, null, 5169 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5170 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5171 userId); 5172 } 5173 } 5174 } 5175 } 5176 } 5177 5178 final void ensureBootCompleted() { 5179 boolean booting; 5180 boolean enableScreen; 5181 synchronized (this) { 5182 booting = mBooting; 5183 mBooting = false; 5184 enableScreen = !mBooted; 5185 mBooted = true; 5186 } 5187 5188 if (booting) { 5189 finishBooting(); 5190 } 5191 5192 if (enableScreen) { 5193 enableScreenAfterBoot(); 5194 } 5195 } 5196 5197 @Override 5198 public final void activityResumed(IBinder token) { 5199 final long origId = Binder.clearCallingIdentity(); 5200 synchronized(this) { 5201 ActivityStack stack = ActivityRecord.getStackLocked(token); 5202 if (stack != null) { 5203 ActivityRecord.activityResumedLocked(token); 5204 } 5205 } 5206 Binder.restoreCallingIdentity(origId); 5207 } 5208 5209 @Override 5210 public final void activityPaused(IBinder token) { 5211 final long origId = Binder.clearCallingIdentity(); 5212 synchronized(this) { 5213 ActivityStack stack = ActivityRecord.getStackLocked(token); 5214 if (stack != null) { 5215 stack.activityPausedLocked(token, false); 5216 } 5217 } 5218 Binder.restoreCallingIdentity(origId); 5219 } 5220 5221 @Override 5222 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5223 CharSequence description) { 5224 if (localLOGV) Slog.v( 5225 TAG, "Activity stopped: token=" + token); 5226 5227 // Refuse possible leaked file descriptors 5228 if (icicle != null && icicle.hasFileDescriptors()) { 5229 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5230 } 5231 5232 ActivityRecord r = null; 5233 5234 final long origId = Binder.clearCallingIdentity(); 5235 5236 synchronized (this) { 5237 r = ActivityRecord.isInStackLocked(token); 5238 if (r != null) { 5239 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5240 } 5241 } 5242 5243 if (r != null) { 5244 sendPendingThumbnail(r, null, null, null, false); 5245 } 5246 5247 trimApplications(); 5248 5249 Binder.restoreCallingIdentity(origId); 5250 } 5251 5252 @Override 5253 public final void activityDestroyed(IBinder token) { 5254 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5255 synchronized (this) { 5256 ActivityStack stack = ActivityRecord.getStackLocked(token); 5257 if (stack != null) { 5258 stack.activityDestroyedLocked(token); 5259 } 5260 } 5261 } 5262 5263 @Override 5264 public String getCallingPackage(IBinder token) { 5265 synchronized (this) { 5266 ActivityRecord r = getCallingRecordLocked(token); 5267 return r != null ? r.info.packageName : null; 5268 } 5269 } 5270 5271 @Override 5272 public ComponentName getCallingActivity(IBinder token) { 5273 synchronized (this) { 5274 ActivityRecord r = getCallingRecordLocked(token); 5275 return r != null ? r.intent.getComponent() : null; 5276 } 5277 } 5278 5279 private ActivityRecord getCallingRecordLocked(IBinder token) { 5280 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5281 if (r == null) { 5282 return null; 5283 } 5284 return r.resultTo; 5285 } 5286 5287 @Override 5288 public ComponentName getActivityClassForToken(IBinder token) { 5289 synchronized(this) { 5290 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5291 if (r == null) { 5292 return null; 5293 } 5294 return r.intent.getComponent(); 5295 } 5296 } 5297 5298 @Override 5299 public String getPackageForToken(IBinder token) { 5300 synchronized(this) { 5301 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5302 if (r == null) { 5303 return null; 5304 } 5305 return r.packageName; 5306 } 5307 } 5308 5309 @Override 5310 public IIntentSender getIntentSender(int type, 5311 String packageName, IBinder token, String resultWho, 5312 int requestCode, Intent[] intents, String[] resolvedTypes, 5313 int flags, Bundle options, int userId) { 5314 enforceNotIsolatedCaller("getIntentSender"); 5315 // Refuse possible leaked file descriptors 5316 if (intents != null) { 5317 if (intents.length < 1) { 5318 throw new IllegalArgumentException("Intents array length must be >= 1"); 5319 } 5320 for (int i=0; i<intents.length; i++) { 5321 Intent intent = intents[i]; 5322 if (intent != null) { 5323 if (intent.hasFileDescriptors()) { 5324 throw new IllegalArgumentException("File descriptors passed in Intent"); 5325 } 5326 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5327 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5328 throw new IllegalArgumentException( 5329 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5330 } 5331 intents[i] = new Intent(intent); 5332 } 5333 } 5334 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5335 throw new IllegalArgumentException( 5336 "Intent array length does not match resolvedTypes length"); 5337 } 5338 } 5339 if (options != null) { 5340 if (options.hasFileDescriptors()) { 5341 throw new IllegalArgumentException("File descriptors passed in options"); 5342 } 5343 } 5344 5345 synchronized(this) { 5346 int callingUid = Binder.getCallingUid(); 5347 int origUserId = userId; 5348 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5349 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5350 "getIntentSender", null); 5351 if (origUserId == UserHandle.USER_CURRENT) { 5352 // We don't want to evaluate this until the pending intent is 5353 // actually executed. However, we do want to always do the 5354 // security checking for it above. 5355 userId = UserHandle.USER_CURRENT; 5356 } 5357 try { 5358 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5359 int uid = AppGlobals.getPackageManager() 5360 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5361 if (!UserHandle.isSameApp(callingUid, uid)) { 5362 String msg = "Permission Denial: getIntentSender() from pid=" 5363 + Binder.getCallingPid() 5364 + ", uid=" + Binder.getCallingUid() 5365 + ", (need uid=" + uid + ")" 5366 + " is not allowed to send as package " + packageName; 5367 Slog.w(TAG, msg); 5368 throw new SecurityException(msg); 5369 } 5370 } 5371 5372 return getIntentSenderLocked(type, packageName, callingUid, userId, 5373 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5374 5375 } catch (RemoteException e) { 5376 throw new SecurityException(e); 5377 } 5378 } 5379 } 5380 5381 IIntentSender getIntentSenderLocked(int type, String packageName, 5382 int callingUid, int userId, IBinder token, String resultWho, 5383 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5384 Bundle options) { 5385 if (DEBUG_MU) 5386 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5387 ActivityRecord activity = null; 5388 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5389 activity = ActivityRecord.isInStackLocked(token); 5390 if (activity == null) { 5391 return null; 5392 } 5393 if (activity.finishing) { 5394 return null; 5395 } 5396 } 5397 5398 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5399 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5400 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5401 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5402 |PendingIntent.FLAG_UPDATE_CURRENT); 5403 5404 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5405 type, packageName, activity, resultWho, 5406 requestCode, intents, resolvedTypes, flags, options, userId); 5407 WeakReference<PendingIntentRecord> ref; 5408 ref = mIntentSenderRecords.get(key); 5409 PendingIntentRecord rec = ref != null ? ref.get() : null; 5410 if (rec != null) { 5411 if (!cancelCurrent) { 5412 if (updateCurrent) { 5413 if (rec.key.requestIntent != null) { 5414 rec.key.requestIntent.replaceExtras(intents != null ? 5415 intents[intents.length - 1] : null); 5416 } 5417 if (intents != null) { 5418 intents[intents.length-1] = rec.key.requestIntent; 5419 rec.key.allIntents = intents; 5420 rec.key.allResolvedTypes = resolvedTypes; 5421 } else { 5422 rec.key.allIntents = null; 5423 rec.key.allResolvedTypes = null; 5424 } 5425 } 5426 return rec; 5427 } 5428 rec.canceled = true; 5429 mIntentSenderRecords.remove(key); 5430 } 5431 if (noCreate) { 5432 return rec; 5433 } 5434 rec = new PendingIntentRecord(this, key, callingUid); 5435 mIntentSenderRecords.put(key, rec.ref); 5436 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5437 if (activity.pendingResults == null) { 5438 activity.pendingResults 5439 = new HashSet<WeakReference<PendingIntentRecord>>(); 5440 } 5441 activity.pendingResults.add(rec.ref); 5442 } 5443 return rec; 5444 } 5445 5446 @Override 5447 public void cancelIntentSender(IIntentSender sender) { 5448 if (!(sender instanceof PendingIntentRecord)) { 5449 return; 5450 } 5451 synchronized(this) { 5452 PendingIntentRecord rec = (PendingIntentRecord)sender; 5453 try { 5454 int uid = AppGlobals.getPackageManager() 5455 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5456 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5457 String msg = "Permission Denial: cancelIntentSender() from pid=" 5458 + Binder.getCallingPid() 5459 + ", uid=" + Binder.getCallingUid() 5460 + " is not allowed to cancel packges " 5461 + rec.key.packageName; 5462 Slog.w(TAG, msg); 5463 throw new SecurityException(msg); 5464 } 5465 } catch (RemoteException e) { 5466 throw new SecurityException(e); 5467 } 5468 cancelIntentSenderLocked(rec, true); 5469 } 5470 } 5471 5472 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5473 rec.canceled = true; 5474 mIntentSenderRecords.remove(rec.key); 5475 if (cleanActivity && rec.key.activity != null) { 5476 rec.key.activity.pendingResults.remove(rec.ref); 5477 } 5478 } 5479 5480 @Override 5481 public String getPackageForIntentSender(IIntentSender pendingResult) { 5482 if (!(pendingResult instanceof PendingIntentRecord)) { 5483 return null; 5484 } 5485 try { 5486 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5487 return res.key.packageName; 5488 } catch (ClassCastException e) { 5489 } 5490 return null; 5491 } 5492 5493 @Override 5494 public int getUidForIntentSender(IIntentSender sender) { 5495 if (sender instanceof PendingIntentRecord) { 5496 try { 5497 PendingIntentRecord res = (PendingIntentRecord)sender; 5498 return res.uid; 5499 } catch (ClassCastException e) { 5500 } 5501 } 5502 return -1; 5503 } 5504 5505 @Override 5506 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5507 if (!(pendingResult instanceof PendingIntentRecord)) { 5508 return false; 5509 } 5510 try { 5511 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5512 if (res.key.allIntents == null) { 5513 return false; 5514 } 5515 for (int i=0; i<res.key.allIntents.length; i++) { 5516 Intent intent = res.key.allIntents[i]; 5517 if (intent.getPackage() != null && intent.getComponent() != null) { 5518 return false; 5519 } 5520 } 5521 return true; 5522 } catch (ClassCastException e) { 5523 } 5524 return false; 5525 } 5526 5527 @Override 5528 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5529 if (!(pendingResult instanceof PendingIntentRecord)) { 5530 return false; 5531 } 5532 try { 5533 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5534 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5535 return true; 5536 } 5537 return false; 5538 } catch (ClassCastException e) { 5539 } 5540 return false; 5541 } 5542 5543 @Override 5544 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5545 if (!(pendingResult instanceof PendingIntentRecord)) { 5546 return null; 5547 } 5548 try { 5549 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5550 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5551 } catch (ClassCastException e) { 5552 } 5553 return null; 5554 } 5555 5556 @Override 5557 public void setProcessLimit(int max) { 5558 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5559 "setProcessLimit()"); 5560 synchronized (this) { 5561 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5562 mProcessLimitOverride = max; 5563 } 5564 trimApplications(); 5565 } 5566 5567 @Override 5568 public int getProcessLimit() { 5569 synchronized (this) { 5570 return mProcessLimitOverride; 5571 } 5572 } 5573 5574 void foregroundTokenDied(ForegroundToken token) { 5575 synchronized (ActivityManagerService.this) { 5576 synchronized (mPidsSelfLocked) { 5577 ForegroundToken cur 5578 = mForegroundProcesses.get(token.pid); 5579 if (cur != token) { 5580 return; 5581 } 5582 mForegroundProcesses.remove(token.pid); 5583 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5584 if (pr == null) { 5585 return; 5586 } 5587 pr.forcingToForeground = null; 5588 pr.foregroundServices = false; 5589 } 5590 updateOomAdjLocked(); 5591 } 5592 } 5593 5594 @Override 5595 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5596 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5597 "setProcessForeground()"); 5598 synchronized(this) { 5599 boolean changed = false; 5600 5601 synchronized (mPidsSelfLocked) { 5602 ProcessRecord pr = mPidsSelfLocked.get(pid); 5603 if (pr == null && isForeground) { 5604 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5605 return; 5606 } 5607 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5608 if (oldToken != null) { 5609 oldToken.token.unlinkToDeath(oldToken, 0); 5610 mForegroundProcesses.remove(pid); 5611 if (pr != null) { 5612 pr.forcingToForeground = null; 5613 } 5614 changed = true; 5615 } 5616 if (isForeground && token != null) { 5617 ForegroundToken newToken = new ForegroundToken() { 5618 @Override 5619 public void binderDied() { 5620 foregroundTokenDied(this); 5621 } 5622 }; 5623 newToken.pid = pid; 5624 newToken.token = token; 5625 try { 5626 token.linkToDeath(newToken, 0); 5627 mForegroundProcesses.put(pid, newToken); 5628 pr.forcingToForeground = token; 5629 changed = true; 5630 } catch (RemoteException e) { 5631 // If the process died while doing this, we will later 5632 // do the cleanup with the process death link. 5633 } 5634 } 5635 } 5636 5637 if (changed) { 5638 updateOomAdjLocked(); 5639 } 5640 } 5641 } 5642 5643 // ========================================================= 5644 // PERMISSIONS 5645 // ========================================================= 5646 5647 static class PermissionController extends IPermissionController.Stub { 5648 ActivityManagerService mActivityManagerService; 5649 PermissionController(ActivityManagerService activityManagerService) { 5650 mActivityManagerService = activityManagerService; 5651 } 5652 5653 @Override 5654 public boolean checkPermission(String permission, int pid, int uid) { 5655 return mActivityManagerService.checkPermission(permission, pid, 5656 uid) == PackageManager.PERMISSION_GRANTED; 5657 } 5658 } 5659 5660 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5661 @Override 5662 public int checkComponentPermission(String permission, int pid, int uid, 5663 int owningUid, boolean exported) { 5664 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5665 owningUid, exported); 5666 } 5667 5668 @Override 5669 public Object getAMSLock() { 5670 return ActivityManagerService.this; 5671 } 5672 } 5673 5674 /** 5675 * This can be called with or without the global lock held. 5676 */ 5677 int checkComponentPermission(String permission, int pid, int uid, 5678 int owningUid, boolean exported) { 5679 // We might be performing an operation on behalf of an indirect binder 5680 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5681 // client identity accordingly before proceeding. 5682 Identity tlsIdentity = sCallerIdentity.get(); 5683 if (tlsIdentity != null) { 5684 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5685 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5686 uid = tlsIdentity.uid; 5687 pid = tlsIdentity.pid; 5688 } 5689 5690 if (pid == MY_PID) { 5691 return PackageManager.PERMISSION_GRANTED; 5692 } 5693 5694 return ActivityManager.checkComponentPermission(permission, uid, 5695 owningUid, exported); 5696 } 5697 5698 /** 5699 * As the only public entry point for permissions checking, this method 5700 * can enforce the semantic that requesting a check on a null global 5701 * permission is automatically denied. (Internally a null permission 5702 * string is used when calling {@link #checkComponentPermission} in cases 5703 * when only uid-based security is needed.) 5704 * 5705 * This can be called with or without the global lock held. 5706 */ 5707 @Override 5708 public int checkPermission(String permission, int pid, int uid) { 5709 if (permission == null) { 5710 return PackageManager.PERMISSION_DENIED; 5711 } 5712 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5713 } 5714 5715 /** 5716 * Binder IPC calls go through the public entry point. 5717 * This can be called with or without the global lock held. 5718 */ 5719 int checkCallingPermission(String permission) { 5720 return checkPermission(permission, 5721 Binder.getCallingPid(), 5722 UserHandle.getAppId(Binder.getCallingUid())); 5723 } 5724 5725 /** 5726 * This can be called with or without the global lock held. 5727 */ 5728 void enforceCallingPermission(String permission, String func) { 5729 if (checkCallingPermission(permission) 5730 == PackageManager.PERMISSION_GRANTED) { 5731 return; 5732 } 5733 5734 String msg = "Permission Denial: " + func + " from pid=" 5735 + Binder.getCallingPid() 5736 + ", uid=" + Binder.getCallingUid() 5737 + " requires " + permission; 5738 Slog.w(TAG, msg); 5739 throw new SecurityException(msg); 5740 } 5741 5742 /** 5743 * Determine if UID is holding permissions required to access {@link Uri} in 5744 * the given {@link ProviderInfo}. Final permission checking is always done 5745 * in {@link ContentProvider}. 5746 */ 5747 private final boolean checkHoldingPermissionsLocked( 5748 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5749 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5750 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5751 5752 if (pi.applicationInfo.uid == uid) { 5753 return true; 5754 } else if (!pi.exported) { 5755 return false; 5756 } 5757 5758 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5759 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5760 try { 5761 // check if target holds top-level <provider> permissions 5762 if (!readMet && pi.readPermission != null 5763 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5764 readMet = true; 5765 } 5766 if (!writeMet && pi.writePermission != null 5767 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5768 writeMet = true; 5769 } 5770 5771 // track if unprotected read/write is allowed; any denied 5772 // <path-permission> below removes this ability 5773 boolean allowDefaultRead = pi.readPermission == null; 5774 boolean allowDefaultWrite = pi.writePermission == null; 5775 5776 // check if target holds any <path-permission> that match uri 5777 final PathPermission[] pps = pi.pathPermissions; 5778 if (pps != null) { 5779 final String path = uri.getPath(); 5780 int i = pps.length; 5781 while (i > 0 && (!readMet || !writeMet)) { 5782 i--; 5783 PathPermission pp = pps[i]; 5784 if (pp.match(path)) { 5785 if (!readMet) { 5786 final String pprperm = pp.getReadPermission(); 5787 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5788 + pprperm + " for " + pp.getPath() 5789 + ": match=" + pp.match(path) 5790 + " check=" + pm.checkUidPermission(pprperm, uid)); 5791 if (pprperm != null) { 5792 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5793 readMet = true; 5794 } else { 5795 allowDefaultRead = false; 5796 } 5797 } 5798 } 5799 if (!writeMet) { 5800 final String ppwperm = pp.getWritePermission(); 5801 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5802 + ppwperm + " for " + pp.getPath() 5803 + ": match=" + pp.match(path) 5804 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5805 if (ppwperm != null) { 5806 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5807 writeMet = true; 5808 } else { 5809 allowDefaultWrite = false; 5810 } 5811 } 5812 } 5813 } 5814 } 5815 } 5816 5817 // grant unprotected <provider> read/write, if not blocked by 5818 // <path-permission> above 5819 if (allowDefaultRead) readMet = true; 5820 if (allowDefaultWrite) writeMet = true; 5821 5822 } catch (RemoteException e) { 5823 return false; 5824 } 5825 5826 return readMet && writeMet; 5827 } 5828 5829 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5830 ProviderInfo pi = null; 5831 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5832 if (cpr != null) { 5833 pi = cpr.info; 5834 } else { 5835 try { 5836 pi = AppGlobals.getPackageManager().resolveContentProvider( 5837 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5838 } catch (RemoteException ex) { 5839 } 5840 } 5841 return pi; 5842 } 5843 5844 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5845 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5846 if (targetUris != null) { 5847 return targetUris.get(uri); 5848 } else { 5849 return null; 5850 } 5851 } 5852 5853 private UriPermission findOrCreateUriPermissionLocked( 5854 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5855 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5856 if (targetUris == null) { 5857 targetUris = Maps.newArrayMap(); 5858 mGrantedUriPermissions.put(targetUid, targetUris); 5859 } 5860 5861 UriPermission perm = targetUris.get(uri); 5862 if (perm == null) { 5863 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5864 targetUris.put(uri, perm); 5865 } 5866 5867 return perm; 5868 } 5869 5870 private final boolean checkUriPermissionLocked( 5871 Uri uri, int uid, int modeFlags, int minStrength) { 5872 // Root gets to do everything. 5873 if (uid == 0) { 5874 return true; 5875 } 5876 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5877 if (perms == null) return false; 5878 UriPermission perm = perms.get(uri); 5879 if (perm == null) return false; 5880 return perm.getStrength(modeFlags) >= minStrength; 5881 } 5882 5883 @Override 5884 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5885 enforceNotIsolatedCaller("checkUriPermission"); 5886 5887 // Another redirected-binder-call permissions check as in 5888 // {@link checkComponentPermission}. 5889 Identity tlsIdentity = sCallerIdentity.get(); 5890 if (tlsIdentity != null) { 5891 uid = tlsIdentity.uid; 5892 pid = tlsIdentity.pid; 5893 } 5894 5895 // Our own process gets to do everything. 5896 if (pid == MY_PID) { 5897 return PackageManager.PERMISSION_GRANTED; 5898 } 5899 synchronized(this) { 5900 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5901 ? PackageManager.PERMISSION_GRANTED 5902 : PackageManager.PERMISSION_DENIED; 5903 } 5904 } 5905 5906 /** 5907 * Check if the targetPkg can be granted permission to access uri by 5908 * the callingUid using the given modeFlags. Throws a security exception 5909 * if callingUid is not allowed to do this. Returns the uid of the target 5910 * if the URI permission grant should be performed; returns -1 if it is not 5911 * needed (for example targetPkg already has permission to access the URI). 5912 * If you already know the uid of the target, you can supply it in 5913 * lastTargetUid else set that to -1. 5914 */ 5915 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5916 Uri uri, int modeFlags, int lastTargetUid) { 5917 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5918 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5919 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5920 if (modeFlags == 0) { 5921 return -1; 5922 } 5923 5924 if (targetPkg != null) { 5925 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5926 "Checking grant " + targetPkg + " permission to " + uri); 5927 } 5928 5929 final IPackageManager pm = AppGlobals.getPackageManager(); 5930 5931 // If this is not a content: uri, we can't do anything with it. 5932 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5933 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5934 "Can't grant URI permission for non-content URI: " + uri); 5935 return -1; 5936 } 5937 5938 final String authority = uri.getAuthority(); 5939 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 5940 if (pi == null) { 5941 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5942 return -1; 5943 } 5944 5945 int targetUid = lastTargetUid; 5946 if (targetUid < 0 && targetPkg != null) { 5947 try { 5948 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5949 if (targetUid < 0) { 5950 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5951 "Can't grant URI permission no uid for: " + targetPkg); 5952 return -1; 5953 } 5954 } catch (RemoteException ex) { 5955 return -1; 5956 } 5957 } 5958 5959 if (targetUid >= 0) { 5960 // First... does the target actually need this permission? 5961 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5962 // No need to grant the target this permission. 5963 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5964 "Target " + targetPkg + " already has full permission to " + uri); 5965 return -1; 5966 } 5967 } else { 5968 // First... there is no target package, so can anyone access it? 5969 boolean allowed = pi.exported; 5970 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5971 if (pi.readPermission != null) { 5972 allowed = false; 5973 } 5974 } 5975 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5976 if (pi.writePermission != null) { 5977 allowed = false; 5978 } 5979 } 5980 if (allowed) { 5981 return -1; 5982 } 5983 } 5984 5985 // Second... is the provider allowing granting of URI permissions? 5986 if (!pi.grantUriPermissions) { 5987 throw new SecurityException("Provider " + pi.packageName 5988 + "/" + pi.name 5989 + " does not allow granting of Uri permissions (uri " 5990 + uri + ")"); 5991 } 5992 if (pi.uriPermissionPatterns != null) { 5993 final int N = pi.uriPermissionPatterns.length; 5994 boolean allowed = false; 5995 for (int i=0; i<N; i++) { 5996 if (pi.uriPermissionPatterns[i] != null 5997 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5998 allowed = true; 5999 break; 6000 } 6001 } 6002 if (!allowed) { 6003 throw new SecurityException("Provider " + pi.packageName 6004 + "/" + pi.name 6005 + " does not allow granting of permission to path of Uri " 6006 + uri); 6007 } 6008 } 6009 6010 // Third... does the caller itself have permission to access 6011 // this uri? 6012 if (callingUid != Process.myUid()) { 6013 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6014 // Require they hold a strong enough Uri permission 6015 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6016 : UriPermission.STRENGTH_OWNED; 6017 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6018 throw new SecurityException("Uid " + callingUid 6019 + " does not have permission to uri " + uri); 6020 } 6021 } 6022 } 6023 6024 return targetUid; 6025 } 6026 6027 @Override 6028 public int checkGrantUriPermission(int callingUid, String targetPkg, 6029 Uri uri, int modeFlags) { 6030 enforceNotIsolatedCaller("checkGrantUriPermission"); 6031 synchronized(this) { 6032 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6033 } 6034 } 6035 6036 void grantUriPermissionUncheckedLocked( 6037 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6038 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6039 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6040 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6041 if (modeFlags == 0) { 6042 return; 6043 } 6044 6045 // So here we are: the caller has the assumed permission 6046 // to the uri, and the target doesn't. Let's now give this to 6047 // the target. 6048 6049 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6050 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6051 6052 final String authority = uri.getAuthority(); 6053 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6054 if (pi == null) { 6055 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6056 return; 6057 } 6058 6059 final UriPermission perm = findOrCreateUriPermissionLocked( 6060 pi.packageName, targetPkg, targetUid, uri); 6061 perm.grantModes(modeFlags, persistable, owner); 6062 } 6063 6064 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6065 int modeFlags, UriPermissionOwner owner) { 6066 if (targetPkg == null) { 6067 throw new NullPointerException("targetPkg"); 6068 } 6069 6070 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6071 if (targetUid < 0) { 6072 return; 6073 } 6074 6075 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6076 } 6077 6078 static class NeededUriGrants extends ArrayList<Uri> { 6079 final String targetPkg; 6080 final int targetUid; 6081 final int flags; 6082 6083 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6084 this.targetPkg = targetPkg; 6085 this.targetUid = targetUid; 6086 this.flags = flags; 6087 } 6088 } 6089 6090 /** 6091 * Like checkGrantUriPermissionLocked, but takes an Intent. 6092 */ 6093 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6094 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6095 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6096 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6097 + " clip=" + (intent != null ? intent.getClipData() : null) 6098 + " from " + intent + "; flags=0x" 6099 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6100 6101 if (targetPkg == null) { 6102 throw new NullPointerException("targetPkg"); 6103 } 6104 6105 if (intent == null) { 6106 return null; 6107 } 6108 Uri data = intent.getData(); 6109 ClipData clip = intent.getClipData(); 6110 if (data == null && clip == null) { 6111 return null; 6112 } 6113 6114 if (data != null) { 6115 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6116 mode, needed != null ? needed.targetUid : -1); 6117 if (targetUid > 0) { 6118 if (needed == null) { 6119 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6120 } 6121 needed.add(data); 6122 } 6123 } 6124 if (clip != null) { 6125 for (int i=0; i<clip.getItemCount(); i++) { 6126 Uri uri = clip.getItemAt(i).getUri(); 6127 if (uri != null) { 6128 int targetUid = -1; 6129 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6130 mode, needed != null ? needed.targetUid : -1); 6131 if (targetUid > 0) { 6132 if (needed == null) { 6133 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6134 } 6135 needed.add(uri); 6136 } 6137 } else { 6138 Intent clipIntent = clip.getItemAt(i).getIntent(); 6139 if (clipIntent != null) { 6140 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6141 callingUid, targetPkg, clipIntent, mode, needed); 6142 if (newNeeded != null) { 6143 needed = newNeeded; 6144 } 6145 } 6146 } 6147 } 6148 } 6149 6150 return needed; 6151 } 6152 6153 /** 6154 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6155 */ 6156 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6157 UriPermissionOwner owner) { 6158 if (needed != null) { 6159 for (int i=0; i<needed.size(); i++) { 6160 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6161 needed.get(i), needed.flags, owner); 6162 } 6163 } 6164 } 6165 6166 void grantUriPermissionFromIntentLocked(int callingUid, 6167 String targetPkg, Intent intent, UriPermissionOwner owner) { 6168 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6169 intent, intent != null ? intent.getFlags() : 0, null); 6170 if (needed == null) { 6171 return; 6172 } 6173 6174 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6175 } 6176 6177 @Override 6178 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6179 Uri uri, int modeFlags) { 6180 enforceNotIsolatedCaller("grantUriPermission"); 6181 synchronized(this) { 6182 final ProcessRecord r = getRecordForAppLocked(caller); 6183 if (r == null) { 6184 throw new SecurityException("Unable to find app for caller " 6185 + caller 6186 + " when granting permission to uri " + uri); 6187 } 6188 if (targetPkg == null) { 6189 throw new IllegalArgumentException("null target"); 6190 } 6191 if (uri == null) { 6192 throw new IllegalArgumentException("null uri"); 6193 } 6194 6195 // Persistable only supported through Intents 6196 Preconditions.checkFlagsArgument(modeFlags, 6197 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6198 6199 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6200 null); 6201 } 6202 } 6203 6204 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6205 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6206 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6207 ArrayMap<Uri, UriPermission> perms 6208 = mGrantedUriPermissions.get(perm.targetUid); 6209 if (perms != null) { 6210 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6211 "Removing " + perm.targetUid + " permission to " + perm.uri); 6212 perms.remove(perm.uri); 6213 if (perms.size() == 0) { 6214 mGrantedUriPermissions.remove(perm.targetUid); 6215 } 6216 } 6217 } 6218 } 6219 6220 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6221 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6222 6223 final IPackageManager pm = AppGlobals.getPackageManager(); 6224 final String authority = uri.getAuthority(); 6225 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6226 if (pi == null) { 6227 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6228 return; 6229 } 6230 6231 // Does the caller have this permission on the URI? 6232 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6233 // Right now, if you are not the original owner of the permission, 6234 // you are not allowed to revoke it. 6235 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6236 throw new SecurityException("Uid " + callingUid 6237 + " does not have permission to uri " + uri); 6238 //} 6239 } 6240 6241 boolean persistChanged = false; 6242 6243 // Go through all of the permissions and remove any that match. 6244 final List<String> SEGMENTS = uri.getPathSegments(); 6245 if (SEGMENTS != null) { 6246 final int NS = SEGMENTS.size(); 6247 int N = mGrantedUriPermissions.size(); 6248 for (int i=0; i<N; i++) { 6249 ArrayMap<Uri, UriPermission> perms 6250 = mGrantedUriPermissions.valueAt(i); 6251 Iterator<UriPermission> it = perms.values().iterator(); 6252 toploop: 6253 while (it.hasNext()) { 6254 UriPermission perm = it.next(); 6255 Uri targetUri = perm.uri; 6256 if (!authority.equals(targetUri.getAuthority())) { 6257 continue; 6258 } 6259 List<String> targetSegments = targetUri.getPathSegments(); 6260 if (targetSegments == null) { 6261 continue; 6262 } 6263 if (targetSegments.size() < NS) { 6264 continue; 6265 } 6266 for (int j=0; j<NS; j++) { 6267 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6268 continue toploop; 6269 } 6270 } 6271 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6272 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6273 persistChanged |= perm.clearModes(modeFlags, true); 6274 if (perm.modeFlags == 0) { 6275 it.remove(); 6276 } 6277 } 6278 if (perms.size() == 0) { 6279 mGrantedUriPermissions.remove( 6280 mGrantedUriPermissions.keyAt(i)); 6281 N--; 6282 i--; 6283 } 6284 } 6285 } 6286 6287 if (persistChanged) { 6288 schedulePersistUriGrants(); 6289 } 6290 } 6291 6292 @Override 6293 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6294 int modeFlags) { 6295 enforceNotIsolatedCaller("revokeUriPermission"); 6296 synchronized(this) { 6297 final ProcessRecord r = getRecordForAppLocked(caller); 6298 if (r == null) { 6299 throw new SecurityException("Unable to find app for caller " 6300 + caller 6301 + " when revoking permission to uri " + uri); 6302 } 6303 if (uri == null) { 6304 Slog.w(TAG, "revokeUriPermission: null uri"); 6305 return; 6306 } 6307 6308 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6309 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6310 if (modeFlags == 0) { 6311 return; 6312 } 6313 6314 final IPackageManager pm = AppGlobals.getPackageManager(); 6315 final String authority = uri.getAuthority(); 6316 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6317 if (pi == null) { 6318 Slog.w(TAG, "No content provider found for permission revoke: " 6319 + uri.toSafeString()); 6320 return; 6321 } 6322 6323 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6324 } 6325 } 6326 6327 /** 6328 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6329 * given package. 6330 * 6331 * @param packageName Package name to match, or {@code null} to apply to all 6332 * packages. 6333 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6334 * to all users. 6335 * @param persistable If persistable grants should be removed. 6336 */ 6337 private void removeUriPermissionsForPackageLocked( 6338 String packageName, int userHandle, boolean persistable) { 6339 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6340 throw new IllegalArgumentException("Must narrow by either package or user"); 6341 } 6342 6343 boolean persistChanged = false; 6344 6345 final int size = mGrantedUriPermissions.size(); 6346 for (int i = 0; i < size; i++) { 6347 // Only inspect grants matching user 6348 if (userHandle == UserHandle.USER_ALL 6349 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6350 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6351 .values().iterator(); 6352 while (it.hasNext()) { 6353 final UriPermission perm = it.next(); 6354 6355 // Only inspect grants matching package 6356 if (packageName == null || perm.sourcePkg.equals(packageName) 6357 || perm.targetPkg.equals(packageName)) { 6358 persistChanged |= perm.clearModes(~0, persistable); 6359 6360 // Only remove when no modes remain; any persisted grants 6361 // will keep this alive. 6362 if (perm.modeFlags == 0) { 6363 it.remove(); 6364 } 6365 } 6366 } 6367 } 6368 } 6369 6370 if (persistChanged) { 6371 schedulePersistUriGrants(); 6372 } 6373 } 6374 6375 @Override 6376 public IBinder newUriPermissionOwner(String name) { 6377 enforceNotIsolatedCaller("newUriPermissionOwner"); 6378 synchronized(this) { 6379 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6380 return owner.getExternalTokenLocked(); 6381 } 6382 } 6383 6384 @Override 6385 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6386 Uri uri, int modeFlags) { 6387 synchronized(this) { 6388 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6389 if (owner == null) { 6390 throw new IllegalArgumentException("Unknown owner: " + token); 6391 } 6392 if (fromUid != Binder.getCallingUid()) { 6393 if (Binder.getCallingUid() != Process.myUid()) { 6394 // Only system code can grant URI permissions on behalf 6395 // of other users. 6396 throw new SecurityException("nice try"); 6397 } 6398 } 6399 if (targetPkg == null) { 6400 throw new IllegalArgumentException("null target"); 6401 } 6402 if (uri == null) { 6403 throw new IllegalArgumentException("null uri"); 6404 } 6405 6406 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6407 } 6408 } 6409 6410 @Override 6411 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6412 synchronized(this) { 6413 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6414 if (owner == null) { 6415 throw new IllegalArgumentException("Unknown owner: " + token); 6416 } 6417 6418 if (uri == null) { 6419 owner.removeUriPermissionsLocked(mode); 6420 } else { 6421 owner.removeUriPermissionLocked(uri, mode); 6422 } 6423 } 6424 } 6425 6426 private void schedulePersistUriGrants() { 6427 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6428 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6429 10 * DateUtils.SECOND_IN_MILLIS); 6430 } 6431 } 6432 6433 private void writeGrantedUriPermissions() { 6434 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6435 6436 // Snapshot permissions so we can persist without lock 6437 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6438 synchronized (this) { 6439 final int size = mGrantedUriPermissions.size(); 6440 for (int i = 0 ; i < size; i++) { 6441 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6442 if (perm.persistedModeFlags != 0) { 6443 persist.add(perm.snapshot()); 6444 } 6445 } 6446 } 6447 } 6448 6449 FileOutputStream fos = null; 6450 try { 6451 fos = mGrantFile.startWrite(); 6452 6453 XmlSerializer out = new FastXmlSerializer(); 6454 out.setOutput(fos, "utf-8"); 6455 out.startDocument(null, true); 6456 out.startTag(null, TAG_URI_GRANTS); 6457 for (UriPermission.Snapshot perm : persist) { 6458 out.startTag(null, TAG_URI_GRANT); 6459 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6460 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6461 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6462 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6463 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6464 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6465 out.endTag(null, TAG_URI_GRANT); 6466 } 6467 out.endTag(null, TAG_URI_GRANTS); 6468 out.endDocument(); 6469 6470 mGrantFile.finishWrite(fos); 6471 } catch (IOException e) { 6472 if (fos != null) { 6473 mGrantFile.failWrite(fos); 6474 } 6475 } 6476 } 6477 6478 private void readGrantedUriPermissionsLocked() { 6479 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6480 6481 final long now = System.currentTimeMillis(); 6482 6483 FileInputStream fis = null; 6484 try { 6485 fis = mGrantFile.openRead(); 6486 final XmlPullParser in = Xml.newPullParser(); 6487 in.setInput(fis, null); 6488 6489 int type; 6490 while ((type = in.next()) != END_DOCUMENT) { 6491 final String tag = in.getName(); 6492 if (type == START_TAG) { 6493 if (TAG_URI_GRANT.equals(tag)) { 6494 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6495 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6496 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6497 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6498 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6499 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6500 6501 // Sanity check that provider still belongs to source package 6502 final ProviderInfo pi = getProviderInfoLocked( 6503 uri.getAuthority(), userHandle); 6504 if (pi != null && sourcePkg.equals(pi.packageName)) { 6505 int targetUid = -1; 6506 try { 6507 targetUid = AppGlobals.getPackageManager() 6508 .getPackageUid(targetPkg, userHandle); 6509 } catch (RemoteException e) { 6510 } 6511 if (targetUid != -1) { 6512 final UriPermission perm = findOrCreateUriPermissionLocked( 6513 sourcePkg, targetPkg, targetUid, uri); 6514 perm.initPersistedModes(modeFlags, createdTime); 6515 } 6516 } else { 6517 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6518 + " but instead found " + pi); 6519 } 6520 } 6521 } 6522 } 6523 } catch (FileNotFoundException e) { 6524 // Missing grants is okay 6525 } catch (IOException e) { 6526 Log.wtf(TAG, "Failed reading Uri grants", e); 6527 } catch (XmlPullParserException e) { 6528 Log.wtf(TAG, "Failed reading Uri grants", e); 6529 } finally { 6530 IoUtils.closeQuietly(fis); 6531 } 6532 } 6533 6534 @Override 6535 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6536 enforceNotIsolatedCaller("takePersistableUriPermission"); 6537 6538 Preconditions.checkFlagsArgument(modeFlags, 6539 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6540 6541 synchronized (this) { 6542 final int callingUid = Binder.getCallingUid(); 6543 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6544 if (perm == null) { 6545 throw new SecurityException("No permission grant found for UID " + callingUid 6546 + " and Uri " + uri.toSafeString()); 6547 } 6548 6549 boolean persistChanged = perm.takePersistableModes(modeFlags); 6550 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6551 6552 if (persistChanged) { 6553 schedulePersistUriGrants(); 6554 } 6555 } 6556 } 6557 6558 @Override 6559 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6560 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6561 6562 Preconditions.checkFlagsArgument(modeFlags, 6563 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6564 6565 synchronized (this) { 6566 final int callingUid = Binder.getCallingUid(); 6567 6568 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6569 if (perm == null) { 6570 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6571 + uri.toSafeString()); 6572 return; 6573 } 6574 6575 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6576 removeUriPermissionIfNeededLocked(perm); 6577 if (persistChanged) { 6578 schedulePersistUriGrants(); 6579 } 6580 } 6581 } 6582 6583 /** 6584 * Prune any older {@link UriPermission} for the given UID until outstanding 6585 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6586 * 6587 * @return if any mutations occured that require persisting. 6588 */ 6589 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6590 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6591 if (perms == null) return false; 6592 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6593 6594 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6595 for (UriPermission perm : perms.values()) { 6596 if (perm.persistedModeFlags != 0) { 6597 persisted.add(perm); 6598 } 6599 } 6600 6601 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6602 if (trimCount <= 0) return false; 6603 6604 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6605 for (int i = 0; i < trimCount; i++) { 6606 final UriPermission perm = persisted.get(i); 6607 6608 if (DEBUG_URI_PERMISSION) { 6609 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6610 } 6611 6612 perm.releasePersistableModes(~0); 6613 removeUriPermissionIfNeededLocked(perm); 6614 } 6615 6616 return true; 6617 } 6618 6619 @Override 6620 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6621 String packageName, boolean incoming) { 6622 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6623 Preconditions.checkNotNull(packageName, "packageName"); 6624 6625 final int callingUid = Binder.getCallingUid(); 6626 final IPackageManager pm = AppGlobals.getPackageManager(); 6627 try { 6628 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6629 if (packageUid != callingUid) { 6630 throw new SecurityException( 6631 "Package " + packageName + " does not belong to calling UID " + callingUid); 6632 } 6633 } catch (RemoteException e) { 6634 throw new SecurityException("Failed to verify package name ownership"); 6635 } 6636 6637 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6638 synchronized (this) { 6639 if (incoming) { 6640 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6641 if (perms == null) { 6642 Slog.w(TAG, "No permission grants found for " + packageName); 6643 } else { 6644 final int size = perms.size(); 6645 for (int i = 0; i < size; i++) { 6646 final UriPermission perm = perms.valueAt(i); 6647 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6648 result.add(perm.buildPersistedPublicApiObject()); 6649 } 6650 } 6651 } 6652 } else { 6653 final int size = mGrantedUriPermissions.size(); 6654 for (int i = 0; i < size; i++) { 6655 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6656 final int permsSize = perms.size(); 6657 for (int j = 0; j < permsSize; j++) { 6658 final UriPermission perm = perms.valueAt(j); 6659 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6660 result.add(perm.buildPersistedPublicApiObject()); 6661 } 6662 } 6663 } 6664 } 6665 } 6666 return new ParceledListSlice<android.content.UriPermission>(result); 6667 } 6668 6669 @Override 6670 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6671 synchronized (this) { 6672 ProcessRecord app = 6673 who != null ? getRecordForAppLocked(who) : null; 6674 if (app == null) return; 6675 6676 Message msg = Message.obtain(); 6677 msg.what = WAIT_FOR_DEBUGGER_MSG; 6678 msg.obj = app; 6679 msg.arg1 = waiting ? 1 : 0; 6680 mHandler.sendMessage(msg); 6681 } 6682 } 6683 6684 @Override 6685 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6686 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6687 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6688 outInfo.availMem = Process.getFreeMemory(); 6689 outInfo.totalMem = Process.getTotalMemory(); 6690 outInfo.threshold = homeAppMem; 6691 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6692 outInfo.hiddenAppThreshold = cachedAppMem; 6693 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6694 ProcessList.SERVICE_ADJ); 6695 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6696 ProcessList.VISIBLE_APP_ADJ); 6697 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6698 ProcessList.FOREGROUND_APP_ADJ); 6699 } 6700 6701 // ========================================================= 6702 // TASK MANAGEMENT 6703 // ========================================================= 6704 6705 @Override 6706 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6707 IThumbnailReceiver receiver) { 6708 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6709 6710 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6711 ActivityRecord topRecord = null; 6712 6713 synchronized(this) { 6714 if (localLOGV) Slog.v( 6715 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6716 + ", receiver=" + receiver); 6717 6718 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6719 != PackageManager.PERMISSION_GRANTED) { 6720 if (receiver != null) { 6721 // If the caller wants to wait for pending thumbnails, 6722 // it ain't gonna get them. 6723 try { 6724 receiver.finished(); 6725 } catch (RemoteException ex) { 6726 } 6727 } 6728 String msg = "Permission Denial: getTasks() from pid=" 6729 + Binder.getCallingPid() 6730 + ", uid=" + Binder.getCallingUid() 6731 + " requires " + android.Manifest.permission.GET_TASKS; 6732 Slog.w(TAG, msg); 6733 throw new SecurityException(msg); 6734 } 6735 6736 // TODO: Improve with MRU list from all ActivityStacks. 6737 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6738 6739 if (!pending.pendingRecords.isEmpty()) { 6740 mPendingThumbnails.add(pending); 6741 } 6742 } 6743 6744 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6745 6746 if (topRecord != null) { 6747 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6748 try { 6749 IApplicationThread topThumbnail = topRecord.app.thread; 6750 topThumbnail.requestThumbnail(topRecord.appToken); 6751 } catch (Exception e) { 6752 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6753 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6754 } 6755 } 6756 6757 if (pending == null && receiver != null) { 6758 // In this case all thumbnails were available and the client 6759 // is being asked to be told when the remaining ones come in... 6760 // which is unusually, since the top-most currently running 6761 // activity should never have a canned thumbnail! Oh well. 6762 try { 6763 receiver.finished(); 6764 } catch (RemoteException ex) { 6765 } 6766 } 6767 6768 return list; 6769 } 6770 6771 TaskRecord getMostRecentTask() { 6772 return mRecentTasks.get(0); 6773 } 6774 6775 @Override 6776 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6777 int flags, int userId) { 6778 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6779 false, true, "getRecentTasks", null); 6780 6781 synchronized (this) { 6782 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6783 "getRecentTasks()"); 6784 final boolean detailed = checkCallingPermission( 6785 android.Manifest.permission.GET_DETAILED_TASKS) 6786 == PackageManager.PERMISSION_GRANTED; 6787 6788 IPackageManager pm = AppGlobals.getPackageManager(); 6789 6790 final int N = mRecentTasks.size(); 6791 ArrayList<ActivityManager.RecentTaskInfo> res 6792 = new ArrayList<ActivityManager.RecentTaskInfo>( 6793 maxNum < N ? maxNum : N); 6794 for (int i=0; i<N && maxNum > 0; i++) { 6795 TaskRecord tr = mRecentTasks.get(i); 6796 // Only add calling user's recent tasks 6797 if (tr.userId != userId) continue; 6798 // Return the entry if desired by the caller. We always return 6799 // the first entry, because callers always expect this to be the 6800 // foreground app. We may filter others if the caller has 6801 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6802 // we should exclude the entry. 6803 6804 if (i == 0 6805 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6806 || (tr.intent == null) 6807 || ((tr.intent.getFlags() 6808 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6809 ActivityManager.RecentTaskInfo rti 6810 = new ActivityManager.RecentTaskInfo(); 6811 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6812 rti.persistentId = tr.taskId; 6813 rti.baseIntent = new Intent( 6814 tr.intent != null ? tr.intent : tr.affinityIntent); 6815 if (!detailed) { 6816 rti.baseIntent.replaceExtras((Bundle)null); 6817 } 6818 rti.origActivity = tr.origActivity; 6819 rti.description = tr.lastDescription; 6820 rti.stackId = tr.stack.mStackId; 6821 6822 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6823 // Check whether this activity is currently available. 6824 try { 6825 if (rti.origActivity != null) { 6826 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6827 == null) { 6828 continue; 6829 } 6830 } else if (rti.baseIntent != null) { 6831 if (pm.queryIntentActivities(rti.baseIntent, 6832 null, 0, userId) == null) { 6833 continue; 6834 } 6835 } 6836 } catch (RemoteException e) { 6837 // Will never happen. 6838 } 6839 } 6840 6841 res.add(rti); 6842 maxNum--; 6843 } 6844 } 6845 return res; 6846 } 6847 } 6848 6849 private TaskRecord recentTaskForIdLocked(int id) { 6850 final int N = mRecentTasks.size(); 6851 for (int i=0; i<N; i++) { 6852 TaskRecord tr = mRecentTasks.get(i); 6853 if (tr.taskId == id) { 6854 return tr; 6855 } 6856 } 6857 return null; 6858 } 6859 6860 @Override 6861 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6862 synchronized (this) { 6863 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6864 "getTaskThumbnails()"); 6865 TaskRecord tr = recentTaskForIdLocked(id); 6866 if (tr != null) { 6867 return tr.getTaskThumbnailsLocked(); 6868 } 6869 } 6870 return null; 6871 } 6872 6873 @Override 6874 public Bitmap getTaskTopThumbnail(int id) { 6875 synchronized (this) { 6876 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6877 "getTaskTopThumbnail()"); 6878 TaskRecord tr = recentTaskForIdLocked(id); 6879 if (tr != null) { 6880 return tr.getTaskTopThumbnailLocked(); 6881 } 6882 } 6883 return null; 6884 } 6885 6886 @Override 6887 public boolean removeSubTask(int taskId, int subTaskIndex) { 6888 synchronized (this) { 6889 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6890 "removeSubTask()"); 6891 long ident = Binder.clearCallingIdentity(); 6892 try { 6893 TaskRecord tr = recentTaskForIdLocked(taskId); 6894 if (tr != null) { 6895 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6896 } 6897 return false; 6898 } finally { 6899 Binder.restoreCallingIdentity(ident); 6900 } 6901 } 6902 } 6903 6904 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6905 if (!pr.killedByAm) { 6906 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6907 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6908 pr.processName, pr.setAdj, reason); 6909 pr.killedByAm = true; 6910 Process.killProcessQuiet(pr.pid); 6911 } 6912 } 6913 6914 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6915 tr.disposeThumbnail(); 6916 mRecentTasks.remove(tr); 6917 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6918 Intent baseIntent = new Intent( 6919 tr.intent != null ? tr.intent : tr.affinityIntent); 6920 ComponentName component = baseIntent.getComponent(); 6921 if (component == null) { 6922 Slog.w(TAG, "Now component for base intent of task: " + tr); 6923 return; 6924 } 6925 6926 // Find any running services associated with this app. 6927 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6928 6929 if (killProcesses) { 6930 // Find any running processes associated with this app. 6931 final String pkg = component.getPackageName(); 6932 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6933 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 6934 for (int i=0; i<pmap.size(); i++) { 6935 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 6936 for (int j=0; j<uids.size(); j++) { 6937 ProcessRecord proc = uids.valueAt(j); 6938 if (proc.userId != tr.userId) { 6939 continue; 6940 } 6941 if (!proc.pkgList.containsKey(pkg)) { 6942 continue; 6943 } 6944 procs.add(proc); 6945 } 6946 } 6947 6948 // Kill the running processes. 6949 for (int i=0; i<procs.size(); i++) { 6950 ProcessRecord pr = procs.get(i); 6951 if (pr == mHomeProcess) { 6952 // Don't kill the home process along with tasks from the same package. 6953 continue; 6954 } 6955 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 6956 killUnneededProcessLocked(pr, "remove task"); 6957 } else { 6958 pr.waitingToKill = "remove task"; 6959 } 6960 } 6961 } 6962 } 6963 6964 @Override 6965 public boolean removeTask(int taskId, int flags) { 6966 synchronized (this) { 6967 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6968 "removeTask()"); 6969 long ident = Binder.clearCallingIdentity(); 6970 try { 6971 TaskRecord tr = recentTaskForIdLocked(taskId); 6972 if (tr != null) { 6973 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 6974 if (r != null) { 6975 cleanUpRemovedTaskLocked(tr, flags); 6976 return true; 6977 } 6978 if (tr.mActivities.size() == 0) { 6979 // Caller is just removing a recent task that is 6980 // not actively running. That is easy! 6981 cleanUpRemovedTaskLocked(tr, flags); 6982 return true; 6983 } 6984 Slog.w(TAG, "removeTask: task " + taskId 6985 + " does not have activities to remove, " 6986 + " but numActivities=" + tr.numActivities 6987 + ": " + tr); 6988 } 6989 } finally { 6990 Binder.restoreCallingIdentity(ident); 6991 } 6992 } 6993 return false; 6994 } 6995 6996 /** 6997 * TODO: Add mController hook 6998 */ 6999 @Override 7000 public void moveTaskToFront(int task, int flags, Bundle options) { 7001 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7002 "moveTaskToFront()"); 7003 7004 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task); 7005 synchronized(this) { 7006 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7007 Binder.getCallingUid(), "Task to front")) { 7008 ActivityOptions.abort(options); 7009 return; 7010 } 7011 final long origId = Binder.clearCallingIdentity(); 7012 try { 7013 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7014 } finally { 7015 Binder.restoreCallingIdentity(origId); 7016 } 7017 ActivityOptions.abort(options); 7018 } 7019 } 7020 7021 @Override 7022 public void moveTaskToBack(int taskId) { 7023 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7024 "moveTaskToBack()"); 7025 7026 synchronized(this) { 7027 TaskRecord tr = recentTaskForIdLocked(taskId); 7028 if (tr != null) { 7029 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7030 ActivityStack stack = tr.stack; 7031 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7032 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7033 Binder.getCallingUid(), "Task to back")) { 7034 return; 7035 } 7036 } 7037 final long origId = Binder.clearCallingIdentity(); 7038 try { 7039 stack.moveTaskToBackLocked(taskId, null); 7040 } finally { 7041 Binder.restoreCallingIdentity(origId); 7042 } 7043 } 7044 } 7045 } 7046 7047 /** 7048 * Moves an activity, and all of the other activities within the same task, to the bottom 7049 * of the history stack. The activity's order within the task is unchanged. 7050 * 7051 * @param token A reference to the activity we wish to move 7052 * @param nonRoot If false then this only works if the activity is the root 7053 * of a task; if true it will work for any activity in a task. 7054 * @return Returns true if the move completed, false if not. 7055 */ 7056 @Override 7057 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7058 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7059 synchronized(this) { 7060 final long origId = Binder.clearCallingIdentity(); 7061 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7062 if (taskId >= 0) { 7063 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7064 } 7065 Binder.restoreCallingIdentity(origId); 7066 } 7067 return false; 7068 } 7069 7070 @Override 7071 public void moveTaskBackwards(int task) { 7072 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7073 "moveTaskBackwards()"); 7074 7075 synchronized(this) { 7076 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7077 Binder.getCallingUid(), "Task backwards")) { 7078 return; 7079 } 7080 final long origId = Binder.clearCallingIdentity(); 7081 moveTaskBackwardsLocked(task); 7082 Binder.restoreCallingIdentity(origId); 7083 } 7084 } 7085 7086 private final void moveTaskBackwardsLocked(int task) { 7087 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7088 } 7089 7090 @Override 7091 public IBinder getHomeActivityToken() throws RemoteException { 7092 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7093 "getHomeActivityToken()"); 7094 synchronized (this) { 7095 return mStackSupervisor.getHomeActivityToken(); 7096 } 7097 } 7098 7099 @Override 7100 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7101 IActivityContainerCallback callback) throws RemoteException { 7102 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7103 "createActivityContainer()"); 7104 synchronized (this) { 7105 if (parentActivityToken == null) { 7106 throw new IllegalArgumentException("parent token must not be null"); 7107 } 7108 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7109 if (r == null) { 7110 return null; 7111 } 7112 if (callback == null) { 7113 throw new IllegalArgumentException("callback must not be null"); 7114 } 7115 return mStackSupervisor.createActivityContainer(r, callback); 7116 } 7117 } 7118 7119 @Override 7120 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7121 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7122 "deleteActivityContainer()"); 7123 synchronized (this) { 7124 mStackSupervisor.deleteActivityContainer(container); 7125 } 7126 } 7127 7128 @Override 7129 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7130 throws RemoteException { 7131 synchronized (this) { 7132 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7133 if (stack != null) { 7134 return stack.mActivityContainer; 7135 } 7136 return null; 7137 } 7138 } 7139 7140 @Override 7141 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7142 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7143 "moveTaskToStack()"); 7144 if (stackId == HOME_STACK_ID) { 7145 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7146 new RuntimeException("here").fillInStackTrace()); 7147 } 7148 synchronized (this) { 7149 long ident = Binder.clearCallingIdentity(); 7150 try { 7151 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7152 + stackId + " toTop=" + toTop); 7153 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7154 } finally { 7155 Binder.restoreCallingIdentity(ident); 7156 } 7157 } 7158 } 7159 7160 @Override 7161 public void resizeStack(int stackBoxId, Rect bounds) { 7162 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7163 "resizeStackBox()"); 7164 long ident = Binder.clearCallingIdentity(); 7165 try { 7166 mWindowManager.resizeStack(stackBoxId, bounds); 7167 } finally { 7168 Binder.restoreCallingIdentity(ident); 7169 } 7170 } 7171 7172 @Override 7173 public List<StackInfo> getAllStackInfos() { 7174 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7175 "getAllStackInfos()"); 7176 long ident = Binder.clearCallingIdentity(); 7177 try { 7178 synchronized (this) { 7179 return mStackSupervisor.getAllStackInfosLocked(); 7180 } 7181 } finally { 7182 Binder.restoreCallingIdentity(ident); 7183 } 7184 } 7185 7186 @Override 7187 public StackInfo getStackInfo(int stackId) { 7188 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7189 "getStackInfo()"); 7190 long ident = Binder.clearCallingIdentity(); 7191 try { 7192 synchronized (this) { 7193 return mStackSupervisor.getStackInfoLocked(stackId); 7194 } 7195 } finally { 7196 Binder.restoreCallingIdentity(ident); 7197 } 7198 } 7199 7200 @Override 7201 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7202 synchronized(this) { 7203 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7204 } 7205 } 7206 7207 // ========================================================= 7208 // THUMBNAILS 7209 // ========================================================= 7210 7211 public void reportThumbnail(IBinder token, 7212 Bitmap thumbnail, CharSequence description) { 7213 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7214 final long origId = Binder.clearCallingIdentity(); 7215 sendPendingThumbnail(null, token, thumbnail, description, true); 7216 Binder.restoreCallingIdentity(origId); 7217 } 7218 7219 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7220 Bitmap thumbnail, CharSequence description, boolean always) { 7221 TaskRecord task; 7222 ArrayList<PendingThumbnailsRecord> receivers = null; 7223 7224 //System.out.println("Send pending thumbnail: " + r); 7225 7226 synchronized(this) { 7227 if (r == null) { 7228 r = ActivityRecord.isInStackLocked(token); 7229 if (r == null) { 7230 return; 7231 } 7232 } 7233 if (thumbnail == null && r.thumbHolder != null) { 7234 thumbnail = r.thumbHolder.lastThumbnail; 7235 description = r.thumbHolder.lastDescription; 7236 } 7237 if (thumbnail == null && !always) { 7238 // If there is no thumbnail, and this entry is not actually 7239 // going away, then abort for now and pick up the next 7240 // thumbnail we get. 7241 return; 7242 } 7243 task = r.task; 7244 7245 int N = mPendingThumbnails.size(); 7246 int i=0; 7247 while (i<N) { 7248 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7249 //System.out.println("Looking in " + pr.pendingRecords); 7250 if (pr.pendingRecords.remove(r)) { 7251 if (receivers == null) { 7252 receivers = new ArrayList<PendingThumbnailsRecord>(); 7253 } 7254 receivers.add(pr); 7255 if (pr.pendingRecords.size() == 0) { 7256 pr.finished = true; 7257 mPendingThumbnails.remove(i); 7258 N--; 7259 continue; 7260 } 7261 } 7262 i++; 7263 } 7264 } 7265 7266 if (receivers != null) { 7267 final int N = receivers.size(); 7268 for (int i=0; i<N; i++) { 7269 try { 7270 PendingThumbnailsRecord pr = receivers.get(i); 7271 pr.receiver.newThumbnail( 7272 task != null ? task.taskId : -1, thumbnail, description); 7273 if (pr.finished) { 7274 pr.receiver.finished(); 7275 } 7276 } catch (Exception e) { 7277 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7278 } 7279 } 7280 } 7281 } 7282 7283 // ========================================================= 7284 // CONTENT PROVIDERS 7285 // ========================================================= 7286 7287 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7288 List<ProviderInfo> providers = null; 7289 try { 7290 providers = AppGlobals.getPackageManager(). 7291 queryContentProviders(app.processName, app.uid, 7292 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7293 } catch (RemoteException ex) { 7294 } 7295 if (DEBUG_MU) 7296 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7297 int userId = app.userId; 7298 if (providers != null) { 7299 int N = providers.size(); 7300 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7301 for (int i=0; i<N; i++) { 7302 ProviderInfo cpi = 7303 (ProviderInfo)providers.get(i); 7304 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7305 cpi.name, cpi.flags); 7306 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7307 // This is a singleton provider, but a user besides the 7308 // default user is asking to initialize a process it runs 7309 // in... well, no, it doesn't actually run in this process, 7310 // it runs in the process of the default user. Get rid of it. 7311 providers.remove(i); 7312 N--; 7313 i--; 7314 continue; 7315 } 7316 7317 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7318 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7319 if (cpr == null) { 7320 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7321 mProviderMap.putProviderByClass(comp, cpr); 7322 } 7323 if (DEBUG_MU) 7324 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7325 app.pubProviders.put(cpi.name, cpr); 7326 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7327 // Don't add this if it is a platform component that is marked 7328 // to run in multiple processes, because this is actually 7329 // part of the framework so doesn't make sense to track as a 7330 // separate apk in the process. 7331 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7332 } 7333 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7334 } 7335 } 7336 return providers; 7337 } 7338 7339 /** 7340 * Check if {@link ProcessRecord} has a possible chance at accessing the 7341 * given {@link ProviderInfo}. Final permission checking is always done 7342 * in {@link ContentProvider}. 7343 */ 7344 private final String checkContentProviderPermissionLocked( 7345 ProviderInfo cpi, ProcessRecord r) { 7346 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7347 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7348 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7349 cpi.applicationInfo.uid, cpi.exported) 7350 == PackageManager.PERMISSION_GRANTED) { 7351 return null; 7352 } 7353 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7354 cpi.applicationInfo.uid, cpi.exported) 7355 == PackageManager.PERMISSION_GRANTED) { 7356 return null; 7357 } 7358 7359 PathPermission[] pps = cpi.pathPermissions; 7360 if (pps != null) { 7361 int i = pps.length; 7362 while (i > 0) { 7363 i--; 7364 PathPermission pp = pps[i]; 7365 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7366 cpi.applicationInfo.uid, cpi.exported) 7367 == PackageManager.PERMISSION_GRANTED) { 7368 return null; 7369 } 7370 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7371 cpi.applicationInfo.uid, cpi.exported) 7372 == PackageManager.PERMISSION_GRANTED) { 7373 return null; 7374 } 7375 } 7376 } 7377 7378 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7379 if (perms != null) { 7380 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7381 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7382 return null; 7383 } 7384 } 7385 } 7386 7387 String msg; 7388 if (!cpi.exported) { 7389 msg = "Permission Denial: opening provider " + cpi.name 7390 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7391 + ", uid=" + callingUid + ") that is not exported from uid " 7392 + cpi.applicationInfo.uid; 7393 } else { 7394 msg = "Permission Denial: opening provider " + cpi.name 7395 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7396 + ", uid=" + callingUid + ") requires " 7397 + cpi.readPermission + " or " + cpi.writePermission; 7398 } 7399 Slog.w(TAG, msg); 7400 return msg; 7401 } 7402 7403 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7404 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7405 if (r != null) { 7406 for (int i=0; i<r.conProviders.size(); i++) { 7407 ContentProviderConnection conn = r.conProviders.get(i); 7408 if (conn.provider == cpr) { 7409 if (DEBUG_PROVIDER) Slog.v(TAG, 7410 "Adding provider requested by " 7411 + r.processName + " from process " 7412 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7413 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7414 if (stable) { 7415 conn.stableCount++; 7416 conn.numStableIncs++; 7417 } else { 7418 conn.unstableCount++; 7419 conn.numUnstableIncs++; 7420 } 7421 return conn; 7422 } 7423 } 7424 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7425 if (stable) { 7426 conn.stableCount = 1; 7427 conn.numStableIncs = 1; 7428 } else { 7429 conn.unstableCount = 1; 7430 conn.numUnstableIncs = 1; 7431 } 7432 cpr.connections.add(conn); 7433 r.conProviders.add(conn); 7434 return conn; 7435 } 7436 cpr.addExternalProcessHandleLocked(externalProcessToken); 7437 return null; 7438 } 7439 7440 boolean decProviderCountLocked(ContentProviderConnection conn, 7441 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7442 if (conn != null) { 7443 cpr = conn.provider; 7444 if (DEBUG_PROVIDER) Slog.v(TAG, 7445 "Removing provider requested by " 7446 + conn.client.processName + " from process " 7447 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7448 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7449 if (stable) { 7450 conn.stableCount--; 7451 } else { 7452 conn.unstableCount--; 7453 } 7454 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7455 cpr.connections.remove(conn); 7456 conn.client.conProviders.remove(conn); 7457 return true; 7458 } 7459 return false; 7460 } 7461 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7462 return false; 7463 } 7464 7465 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7466 String name, IBinder token, boolean stable, int userId) { 7467 ContentProviderRecord cpr; 7468 ContentProviderConnection conn = null; 7469 ProviderInfo cpi = null; 7470 7471 synchronized(this) { 7472 ProcessRecord r = null; 7473 if (caller != null) { 7474 r = getRecordForAppLocked(caller); 7475 if (r == null) { 7476 throw new SecurityException( 7477 "Unable to find app for caller " + caller 7478 + " (pid=" + Binder.getCallingPid() 7479 + ") when getting content provider " + name); 7480 } 7481 } 7482 7483 // First check if this content provider has been published... 7484 cpr = mProviderMap.getProviderByName(name, userId); 7485 boolean providerRunning = cpr != null; 7486 if (providerRunning) { 7487 cpi = cpr.info; 7488 String msg; 7489 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7490 throw new SecurityException(msg); 7491 } 7492 7493 if (r != null && cpr.canRunHere(r)) { 7494 // This provider has been published or is in the process 7495 // of being published... but it is also allowed to run 7496 // in the caller's process, so don't make a connection 7497 // and just let the caller instantiate its own instance. 7498 ContentProviderHolder holder = cpr.newHolder(null); 7499 // don't give caller the provider object, it needs 7500 // to make its own. 7501 holder.provider = null; 7502 return holder; 7503 } 7504 7505 final long origId = Binder.clearCallingIdentity(); 7506 7507 // In this case the provider instance already exists, so we can 7508 // return it right away. 7509 conn = incProviderCountLocked(r, cpr, token, stable); 7510 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7511 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7512 // If this is a perceptible app accessing the provider, 7513 // make sure to count it as being accessed and thus 7514 // back up on the LRU list. This is good because 7515 // content providers are often expensive to start. 7516 updateLruProcessLocked(cpr.proc, false, null); 7517 } 7518 } 7519 7520 if (cpr.proc != null) { 7521 if (false) { 7522 if (cpr.name.flattenToShortString().equals( 7523 "com.android.providers.calendar/.CalendarProvider2")) { 7524 Slog.v(TAG, "****************** KILLING " 7525 + cpr.name.flattenToShortString()); 7526 Process.killProcess(cpr.proc.pid); 7527 } 7528 } 7529 boolean success = updateOomAdjLocked(cpr.proc); 7530 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7531 // NOTE: there is still a race here where a signal could be 7532 // pending on the process even though we managed to update its 7533 // adj level. Not sure what to do about this, but at least 7534 // the race is now smaller. 7535 if (!success) { 7536 // Uh oh... it looks like the provider's process 7537 // has been killed on us. We need to wait for a new 7538 // process to be started, and make sure its death 7539 // doesn't kill our process. 7540 Slog.i(TAG, 7541 "Existing provider " + cpr.name.flattenToShortString() 7542 + " is crashing; detaching " + r); 7543 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7544 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7545 if (!lastRef) { 7546 // This wasn't the last ref our process had on 7547 // the provider... we have now been killed, bail. 7548 return null; 7549 } 7550 providerRunning = false; 7551 conn = null; 7552 } 7553 } 7554 7555 Binder.restoreCallingIdentity(origId); 7556 } 7557 7558 boolean singleton; 7559 if (!providerRunning) { 7560 try { 7561 cpi = AppGlobals.getPackageManager(). 7562 resolveContentProvider(name, 7563 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7564 } catch (RemoteException ex) { 7565 } 7566 if (cpi == null) { 7567 return null; 7568 } 7569 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7570 cpi.name, cpi.flags); 7571 if (singleton) { 7572 userId = 0; 7573 } 7574 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7575 7576 String msg; 7577 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7578 throw new SecurityException(msg); 7579 } 7580 7581 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7582 && !cpi.processName.equals("system")) { 7583 // If this content provider does not run in the system 7584 // process, and the system is not yet ready to run other 7585 // processes, then fail fast instead of hanging. 7586 throw new IllegalArgumentException( 7587 "Attempt to launch content provider before system ready"); 7588 } 7589 7590 // Make sure that the user who owns this provider is started. If not, 7591 // we don't want to allow it to run. 7592 if (mStartedUsers.get(userId) == null) { 7593 Slog.w(TAG, "Unable to launch app " 7594 + cpi.applicationInfo.packageName + "/" 7595 + cpi.applicationInfo.uid + " for provider " 7596 + name + ": user " + userId + " is stopped"); 7597 return null; 7598 } 7599 7600 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7601 cpr = mProviderMap.getProviderByClass(comp, userId); 7602 final boolean firstClass = cpr == null; 7603 if (firstClass) { 7604 try { 7605 ApplicationInfo ai = 7606 AppGlobals.getPackageManager(). 7607 getApplicationInfo( 7608 cpi.applicationInfo.packageName, 7609 STOCK_PM_FLAGS, userId); 7610 if (ai == null) { 7611 Slog.w(TAG, "No package info for content provider " 7612 + cpi.name); 7613 return null; 7614 } 7615 ai = getAppInfoForUser(ai, userId); 7616 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7617 } catch (RemoteException ex) { 7618 // pm is in same process, this will never happen. 7619 } 7620 } 7621 7622 if (r != null && cpr.canRunHere(r)) { 7623 // If this is a multiprocess provider, then just return its 7624 // info and allow the caller to instantiate it. Only do 7625 // this if the provider is the same user as the caller's 7626 // process, or can run as root (so can be in any process). 7627 return cpr.newHolder(null); 7628 } 7629 7630 if (DEBUG_PROVIDER) { 7631 RuntimeException e = new RuntimeException("here"); 7632 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7633 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7634 } 7635 7636 // This is single process, and our app is now connecting to it. 7637 // See if we are already in the process of launching this 7638 // provider. 7639 final int N = mLaunchingProviders.size(); 7640 int i; 7641 for (i=0; i<N; i++) { 7642 if (mLaunchingProviders.get(i) == cpr) { 7643 break; 7644 } 7645 } 7646 7647 // If the provider is not already being launched, then get it 7648 // started. 7649 if (i >= N) { 7650 final long origId = Binder.clearCallingIdentity(); 7651 7652 try { 7653 // Content provider is now in use, its package can't be stopped. 7654 try { 7655 AppGlobals.getPackageManager().setPackageStoppedState( 7656 cpr.appInfo.packageName, false, userId); 7657 } catch (RemoteException e) { 7658 } catch (IllegalArgumentException e) { 7659 Slog.w(TAG, "Failed trying to unstop package " 7660 + cpr.appInfo.packageName + ": " + e); 7661 } 7662 7663 // Use existing process if already started 7664 ProcessRecord proc = getProcessRecordLocked( 7665 cpi.processName, cpr.appInfo.uid, false); 7666 if (proc != null && proc.thread != null) { 7667 if (DEBUG_PROVIDER) { 7668 Slog.d(TAG, "Installing in existing process " + proc); 7669 } 7670 proc.pubProviders.put(cpi.name, cpr); 7671 try { 7672 proc.thread.scheduleInstallProvider(cpi); 7673 } catch (RemoteException e) { 7674 } 7675 } else { 7676 proc = startProcessLocked(cpi.processName, 7677 cpr.appInfo, false, 0, "content provider", 7678 new ComponentName(cpi.applicationInfo.packageName, 7679 cpi.name), false, false, false); 7680 if (proc == null) { 7681 Slog.w(TAG, "Unable to launch app " 7682 + cpi.applicationInfo.packageName + "/" 7683 + cpi.applicationInfo.uid + " for provider " 7684 + name + ": process is bad"); 7685 return null; 7686 } 7687 } 7688 cpr.launchingApp = proc; 7689 mLaunchingProviders.add(cpr); 7690 } finally { 7691 Binder.restoreCallingIdentity(origId); 7692 } 7693 } 7694 7695 // Make sure the provider is published (the same provider class 7696 // may be published under multiple names). 7697 if (firstClass) { 7698 mProviderMap.putProviderByClass(comp, cpr); 7699 } 7700 7701 mProviderMap.putProviderByName(name, cpr); 7702 conn = incProviderCountLocked(r, cpr, token, stable); 7703 if (conn != null) { 7704 conn.waiting = true; 7705 } 7706 } 7707 } 7708 7709 // Wait for the provider to be published... 7710 synchronized (cpr) { 7711 while (cpr.provider == null) { 7712 if (cpr.launchingApp == null) { 7713 Slog.w(TAG, "Unable to launch app " 7714 + cpi.applicationInfo.packageName + "/" 7715 + cpi.applicationInfo.uid + " for provider " 7716 + name + ": launching app became null"); 7717 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7718 UserHandle.getUserId(cpi.applicationInfo.uid), 7719 cpi.applicationInfo.packageName, 7720 cpi.applicationInfo.uid, name); 7721 return null; 7722 } 7723 try { 7724 if (DEBUG_MU) { 7725 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7726 + cpr.launchingApp); 7727 } 7728 if (conn != null) { 7729 conn.waiting = true; 7730 } 7731 cpr.wait(); 7732 } catch (InterruptedException ex) { 7733 } finally { 7734 if (conn != null) { 7735 conn.waiting = false; 7736 } 7737 } 7738 } 7739 } 7740 return cpr != null ? cpr.newHolder(conn) : null; 7741 } 7742 7743 public final ContentProviderHolder getContentProvider( 7744 IApplicationThread caller, String name, int userId, boolean stable) { 7745 enforceNotIsolatedCaller("getContentProvider"); 7746 if (caller == null) { 7747 String msg = "null IApplicationThread when getting content provider " 7748 + name; 7749 Slog.w(TAG, msg); 7750 throw new SecurityException(msg); 7751 } 7752 7753 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7754 false, true, "getContentProvider", null); 7755 return getContentProviderImpl(caller, name, null, stable, userId); 7756 } 7757 7758 public ContentProviderHolder getContentProviderExternal( 7759 String name, int userId, IBinder token) { 7760 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7761 "Do not have permission in call getContentProviderExternal()"); 7762 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7763 false, true, "getContentProvider", null); 7764 return getContentProviderExternalUnchecked(name, token, userId); 7765 } 7766 7767 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7768 IBinder token, int userId) { 7769 return getContentProviderImpl(null, name, token, true, userId); 7770 } 7771 7772 /** 7773 * Drop a content provider from a ProcessRecord's bookkeeping 7774 */ 7775 public void removeContentProvider(IBinder connection, boolean stable) { 7776 enforceNotIsolatedCaller("removeContentProvider"); 7777 synchronized (this) { 7778 ContentProviderConnection conn; 7779 try { 7780 conn = (ContentProviderConnection)connection; 7781 } catch (ClassCastException e) { 7782 String msg ="removeContentProvider: " + connection 7783 + " not a ContentProviderConnection"; 7784 Slog.w(TAG, msg); 7785 throw new IllegalArgumentException(msg); 7786 } 7787 if (conn == null) { 7788 throw new NullPointerException("connection is null"); 7789 } 7790 if (decProviderCountLocked(conn, null, null, stable)) { 7791 updateOomAdjLocked(); 7792 } 7793 } 7794 } 7795 7796 public void removeContentProviderExternal(String name, IBinder token) { 7797 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7798 "Do not have permission in call removeContentProviderExternal()"); 7799 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7800 } 7801 7802 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7803 synchronized (this) { 7804 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7805 if(cpr == null) { 7806 //remove from mProvidersByClass 7807 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7808 return; 7809 } 7810 7811 //update content provider record entry info 7812 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7813 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7814 if (localCpr.hasExternalProcessHandles()) { 7815 if (localCpr.removeExternalProcessHandleLocked(token)) { 7816 updateOomAdjLocked(); 7817 } else { 7818 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7819 + " with no external reference for token: " 7820 + token + "."); 7821 } 7822 } else { 7823 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7824 + " with no external references."); 7825 } 7826 } 7827 } 7828 7829 public final void publishContentProviders(IApplicationThread caller, 7830 List<ContentProviderHolder> providers) { 7831 if (providers == null) { 7832 return; 7833 } 7834 7835 enforceNotIsolatedCaller("publishContentProviders"); 7836 synchronized (this) { 7837 final ProcessRecord r = getRecordForAppLocked(caller); 7838 if (DEBUG_MU) 7839 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 7840 if (r == null) { 7841 throw new SecurityException( 7842 "Unable to find app for caller " + caller 7843 + " (pid=" + Binder.getCallingPid() 7844 + ") when publishing content providers"); 7845 } 7846 7847 final long origId = Binder.clearCallingIdentity(); 7848 7849 final int N = providers.size(); 7850 for (int i=0; i<N; i++) { 7851 ContentProviderHolder src = providers.get(i); 7852 if (src == null || src.info == null || src.provider == null) { 7853 continue; 7854 } 7855 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 7856 if (DEBUG_MU) 7857 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 7858 if (dst != null) { 7859 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 7860 mProviderMap.putProviderByClass(comp, dst); 7861 String names[] = dst.info.authority.split(";"); 7862 for (int j = 0; j < names.length; j++) { 7863 mProviderMap.putProviderByName(names[j], dst); 7864 } 7865 7866 int NL = mLaunchingProviders.size(); 7867 int j; 7868 for (j=0; j<NL; j++) { 7869 if (mLaunchingProviders.get(j) == dst) { 7870 mLaunchingProviders.remove(j); 7871 j--; 7872 NL--; 7873 } 7874 } 7875 synchronized (dst) { 7876 dst.provider = src.provider; 7877 dst.proc = r; 7878 dst.notifyAll(); 7879 } 7880 updateOomAdjLocked(r); 7881 } 7882 } 7883 7884 Binder.restoreCallingIdentity(origId); 7885 } 7886 } 7887 7888 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 7889 ContentProviderConnection conn; 7890 try { 7891 conn = (ContentProviderConnection)connection; 7892 } catch (ClassCastException e) { 7893 String msg ="refContentProvider: " + connection 7894 + " not a ContentProviderConnection"; 7895 Slog.w(TAG, msg); 7896 throw new IllegalArgumentException(msg); 7897 } 7898 if (conn == null) { 7899 throw new NullPointerException("connection is null"); 7900 } 7901 7902 synchronized (this) { 7903 if (stable > 0) { 7904 conn.numStableIncs += stable; 7905 } 7906 stable = conn.stableCount + stable; 7907 if (stable < 0) { 7908 throw new IllegalStateException("stableCount < 0: " + stable); 7909 } 7910 7911 if (unstable > 0) { 7912 conn.numUnstableIncs += unstable; 7913 } 7914 unstable = conn.unstableCount + unstable; 7915 if (unstable < 0) { 7916 throw new IllegalStateException("unstableCount < 0: " + unstable); 7917 } 7918 7919 if ((stable+unstable) <= 0) { 7920 throw new IllegalStateException("ref counts can't go to zero here: stable=" 7921 + stable + " unstable=" + unstable); 7922 } 7923 conn.stableCount = stable; 7924 conn.unstableCount = unstable; 7925 return !conn.dead; 7926 } 7927 } 7928 7929 public void unstableProviderDied(IBinder connection) { 7930 ContentProviderConnection conn; 7931 try { 7932 conn = (ContentProviderConnection)connection; 7933 } catch (ClassCastException e) { 7934 String msg ="refContentProvider: " + connection 7935 + " not a ContentProviderConnection"; 7936 Slog.w(TAG, msg); 7937 throw new IllegalArgumentException(msg); 7938 } 7939 if (conn == null) { 7940 throw new NullPointerException("connection is null"); 7941 } 7942 7943 // Safely retrieve the content provider associated with the connection. 7944 IContentProvider provider; 7945 synchronized (this) { 7946 provider = conn.provider.provider; 7947 } 7948 7949 if (provider == null) { 7950 // Um, yeah, we're way ahead of you. 7951 return; 7952 } 7953 7954 // Make sure the caller is being honest with us. 7955 if (provider.asBinder().pingBinder()) { 7956 // Er, no, still looks good to us. 7957 synchronized (this) { 7958 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 7959 + " says " + conn + " died, but we don't agree"); 7960 return; 7961 } 7962 } 7963 7964 // Well look at that! It's dead! 7965 synchronized (this) { 7966 if (conn.provider.provider != provider) { 7967 // But something changed... good enough. 7968 return; 7969 } 7970 7971 ProcessRecord proc = conn.provider.proc; 7972 if (proc == null || proc.thread == null) { 7973 // Seems like the process is already cleaned up. 7974 return; 7975 } 7976 7977 // As far as we're concerned, this is just like receiving a 7978 // death notification... just a bit prematurely. 7979 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 7980 + ") early provider death"); 7981 final long ident = Binder.clearCallingIdentity(); 7982 try { 7983 appDiedLocked(proc, proc.pid, proc.thread); 7984 } finally { 7985 Binder.restoreCallingIdentity(ident); 7986 } 7987 } 7988 } 7989 7990 @Override 7991 public void appNotRespondingViaProvider(IBinder connection) { 7992 enforceCallingPermission( 7993 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 7994 7995 final ContentProviderConnection conn = (ContentProviderConnection) connection; 7996 if (conn == null) { 7997 Slog.w(TAG, "ContentProviderConnection is null"); 7998 return; 7999 } 8000 8001 final ProcessRecord host = conn.provider.proc; 8002 if (host == null) { 8003 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8004 return; 8005 } 8006 8007 final long token = Binder.clearCallingIdentity(); 8008 try { 8009 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8010 } finally { 8011 Binder.restoreCallingIdentity(token); 8012 } 8013 } 8014 8015 public final void installSystemProviders() { 8016 List<ProviderInfo> providers; 8017 synchronized (this) { 8018 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8019 providers = generateApplicationProvidersLocked(app); 8020 if (providers != null) { 8021 for (int i=providers.size()-1; i>=0; i--) { 8022 ProviderInfo pi = (ProviderInfo)providers.get(i); 8023 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8024 Slog.w(TAG, "Not installing system proc provider " + pi.name 8025 + ": not system .apk"); 8026 providers.remove(i); 8027 } 8028 } 8029 } 8030 } 8031 if (providers != null) { 8032 mSystemThread.installSystemProviders(providers); 8033 } 8034 8035 mCoreSettingsObserver = new CoreSettingsObserver(this); 8036 8037 mUsageStatsService.monitorPackages(); 8038 } 8039 8040 /** 8041 * Allows app to retrieve the MIME type of a URI without having permission 8042 * to access its content provider. 8043 * 8044 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8045 * 8046 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8047 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8048 */ 8049 public String getProviderMimeType(Uri uri, int userId) { 8050 enforceNotIsolatedCaller("getProviderMimeType"); 8051 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8052 userId, false, true, "getProviderMimeType", null); 8053 final String name = uri.getAuthority(); 8054 final long ident = Binder.clearCallingIdentity(); 8055 ContentProviderHolder holder = null; 8056 8057 try { 8058 holder = getContentProviderExternalUnchecked(name, null, userId); 8059 if (holder != null) { 8060 return holder.provider.getType(uri); 8061 } 8062 } catch (RemoteException e) { 8063 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8064 return null; 8065 } finally { 8066 if (holder != null) { 8067 removeContentProviderExternalUnchecked(name, null, userId); 8068 } 8069 Binder.restoreCallingIdentity(ident); 8070 } 8071 8072 return null; 8073 } 8074 8075 // ========================================================= 8076 // GLOBAL MANAGEMENT 8077 // ========================================================= 8078 8079 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8080 boolean isolated) { 8081 String proc = customProcess != null ? customProcess : info.processName; 8082 BatteryStatsImpl.Uid.Proc ps = null; 8083 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8084 int uid = info.uid; 8085 if (isolated) { 8086 int userId = UserHandle.getUserId(uid); 8087 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8088 while (true) { 8089 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8090 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8091 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8092 } 8093 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8094 mNextIsolatedProcessUid++; 8095 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8096 // No process for this uid, use it. 8097 break; 8098 } 8099 stepsLeft--; 8100 if (stepsLeft <= 0) { 8101 return null; 8102 } 8103 } 8104 } 8105 return new ProcessRecord(stats, info, proc, uid); 8106 } 8107 8108 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 8109 String abiOverride) { 8110 ProcessRecord app; 8111 if (!isolated) { 8112 app = getProcessRecordLocked(info.processName, info.uid, true); 8113 } else { 8114 app = null; 8115 } 8116 8117 if (app == null) { 8118 app = newProcessRecordLocked(info, null, isolated); 8119 mProcessNames.put(info.processName, app.uid, app); 8120 if (isolated) { 8121 mIsolatedProcesses.put(app.uid, app); 8122 } 8123 updateLruProcessLocked(app, false, null); 8124 updateOomAdjLocked(); 8125 } 8126 8127 // This package really, really can not be stopped. 8128 try { 8129 AppGlobals.getPackageManager().setPackageStoppedState( 8130 info.packageName, false, UserHandle.getUserId(app.uid)); 8131 } catch (RemoteException e) { 8132 } catch (IllegalArgumentException e) { 8133 Slog.w(TAG, "Failed trying to unstop package " 8134 + info.packageName + ": " + e); 8135 } 8136 8137 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8138 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8139 app.persistent = true; 8140 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8141 } 8142 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8143 mPersistentStartingProcesses.add(app); 8144 startProcessLocked(app, "added application", app.processName, 8145 abiOverride); 8146 } 8147 8148 return app; 8149 } 8150 8151 public void unhandledBack() { 8152 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8153 "unhandledBack()"); 8154 8155 synchronized(this) { 8156 final long origId = Binder.clearCallingIdentity(); 8157 try { 8158 getFocusedStack().unhandledBackLocked(); 8159 } finally { 8160 Binder.restoreCallingIdentity(origId); 8161 } 8162 } 8163 } 8164 8165 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8166 enforceNotIsolatedCaller("openContentUri"); 8167 final int userId = UserHandle.getCallingUserId(); 8168 String name = uri.getAuthority(); 8169 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8170 ParcelFileDescriptor pfd = null; 8171 if (cph != null) { 8172 // We record the binder invoker's uid in thread-local storage before 8173 // going to the content provider to open the file. Later, in the code 8174 // that handles all permissions checks, we look for this uid and use 8175 // that rather than the Activity Manager's own uid. The effect is that 8176 // we do the check against the caller's permissions even though it looks 8177 // to the content provider like the Activity Manager itself is making 8178 // the request. 8179 sCallerIdentity.set(new Identity( 8180 Binder.getCallingPid(), Binder.getCallingUid())); 8181 try { 8182 pfd = cph.provider.openFile(null, uri, "r", null); 8183 } catch (FileNotFoundException e) { 8184 // do nothing; pfd will be returned null 8185 } finally { 8186 // Ensure that whatever happens, we clean up the identity state 8187 sCallerIdentity.remove(); 8188 } 8189 8190 // We've got the fd now, so we're done with the provider. 8191 removeContentProviderExternalUnchecked(name, null, userId); 8192 } else { 8193 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8194 } 8195 return pfd; 8196 } 8197 8198 // Actually is sleeping or shutting down or whatever else in the future 8199 // is an inactive state. 8200 public boolean isSleepingOrShuttingDown() { 8201 return mSleeping || mShuttingDown; 8202 } 8203 8204 void goingToSleep() { 8205 synchronized(this) { 8206 mWentToSleep = true; 8207 updateEventDispatchingLocked(); 8208 8209 if (!mSleeping) { 8210 mSleeping = true; 8211 mStackSupervisor.goingToSleepLocked(); 8212 8213 // Initialize the wake times of all processes. 8214 checkExcessivePowerUsageLocked(false); 8215 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8216 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8217 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8218 } 8219 } 8220 } 8221 8222 @Override 8223 public boolean shutdown(int timeout) { 8224 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8225 != PackageManager.PERMISSION_GRANTED) { 8226 throw new SecurityException("Requires permission " 8227 + android.Manifest.permission.SHUTDOWN); 8228 } 8229 8230 boolean timedout = false; 8231 8232 synchronized(this) { 8233 mShuttingDown = true; 8234 updateEventDispatchingLocked(); 8235 timedout = mStackSupervisor.shutdownLocked(timeout); 8236 } 8237 8238 mAppOpsService.shutdown(); 8239 mUsageStatsService.shutdown(); 8240 mBatteryStatsService.shutdown(); 8241 synchronized (this) { 8242 mProcessStats.shutdownLocked(); 8243 } 8244 8245 return timedout; 8246 } 8247 8248 public final void activitySlept(IBinder token) { 8249 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8250 8251 final long origId = Binder.clearCallingIdentity(); 8252 8253 synchronized (this) { 8254 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8255 if (r != null) { 8256 mStackSupervisor.activitySleptLocked(r); 8257 } 8258 } 8259 8260 Binder.restoreCallingIdentity(origId); 8261 } 8262 8263 void logLockScreen(String msg) { 8264 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8265 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8266 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8267 mStackSupervisor.mDismissKeyguardOnNextActivity); 8268 } 8269 8270 private void comeOutOfSleepIfNeededLocked() { 8271 if (!mWentToSleep && !mLockScreenShown) { 8272 if (mSleeping) { 8273 mSleeping = false; 8274 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8275 } 8276 } 8277 } 8278 8279 void wakingUp() { 8280 synchronized(this) { 8281 mWentToSleep = false; 8282 updateEventDispatchingLocked(); 8283 comeOutOfSleepIfNeededLocked(); 8284 } 8285 } 8286 8287 private void updateEventDispatchingLocked() { 8288 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8289 } 8290 8291 public void setLockScreenShown(boolean shown) { 8292 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8293 != PackageManager.PERMISSION_GRANTED) { 8294 throw new SecurityException("Requires permission " 8295 + android.Manifest.permission.DEVICE_POWER); 8296 } 8297 8298 synchronized(this) { 8299 long ident = Binder.clearCallingIdentity(); 8300 try { 8301 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8302 mLockScreenShown = shown; 8303 comeOutOfSleepIfNeededLocked(); 8304 } finally { 8305 Binder.restoreCallingIdentity(ident); 8306 } 8307 } 8308 } 8309 8310 public void stopAppSwitches() { 8311 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8312 != PackageManager.PERMISSION_GRANTED) { 8313 throw new SecurityException("Requires permission " 8314 + android.Manifest.permission.STOP_APP_SWITCHES); 8315 } 8316 8317 synchronized(this) { 8318 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8319 + APP_SWITCH_DELAY_TIME; 8320 mDidAppSwitch = false; 8321 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8322 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8323 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8324 } 8325 } 8326 8327 public void resumeAppSwitches() { 8328 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8329 != PackageManager.PERMISSION_GRANTED) { 8330 throw new SecurityException("Requires permission " 8331 + android.Manifest.permission.STOP_APP_SWITCHES); 8332 } 8333 8334 synchronized(this) { 8335 // Note that we don't execute any pending app switches... we will 8336 // let those wait until either the timeout, or the next start 8337 // activity request. 8338 mAppSwitchesAllowedTime = 0; 8339 } 8340 } 8341 8342 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8343 String name) { 8344 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8345 return true; 8346 } 8347 8348 final int perm = checkComponentPermission( 8349 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8350 callingUid, -1, true); 8351 if (perm == PackageManager.PERMISSION_GRANTED) { 8352 return true; 8353 } 8354 8355 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8356 return false; 8357 } 8358 8359 public void setDebugApp(String packageName, boolean waitForDebugger, 8360 boolean persistent) { 8361 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8362 "setDebugApp()"); 8363 8364 long ident = Binder.clearCallingIdentity(); 8365 try { 8366 // Note that this is not really thread safe if there are multiple 8367 // callers into it at the same time, but that's not a situation we 8368 // care about. 8369 if (persistent) { 8370 final ContentResolver resolver = mContext.getContentResolver(); 8371 Settings.Global.putString( 8372 resolver, Settings.Global.DEBUG_APP, 8373 packageName); 8374 Settings.Global.putInt( 8375 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8376 waitForDebugger ? 1 : 0); 8377 } 8378 8379 synchronized (this) { 8380 if (!persistent) { 8381 mOrigDebugApp = mDebugApp; 8382 mOrigWaitForDebugger = mWaitForDebugger; 8383 } 8384 mDebugApp = packageName; 8385 mWaitForDebugger = waitForDebugger; 8386 mDebugTransient = !persistent; 8387 if (packageName != null) { 8388 forceStopPackageLocked(packageName, -1, false, false, true, true, 8389 UserHandle.USER_ALL, "set debug app"); 8390 } 8391 } 8392 } finally { 8393 Binder.restoreCallingIdentity(ident); 8394 } 8395 } 8396 8397 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8398 synchronized (this) { 8399 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8400 if (!isDebuggable) { 8401 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8402 throw new SecurityException("Process not debuggable: " + app.packageName); 8403 } 8404 } 8405 8406 mOpenGlTraceApp = processName; 8407 } 8408 } 8409 8410 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8411 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8412 synchronized (this) { 8413 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8414 if (!isDebuggable) { 8415 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8416 throw new SecurityException("Process not debuggable: " + app.packageName); 8417 } 8418 } 8419 mProfileApp = processName; 8420 mProfileFile = profileFile; 8421 if (mProfileFd != null) { 8422 try { 8423 mProfileFd.close(); 8424 } catch (IOException e) { 8425 } 8426 mProfileFd = null; 8427 } 8428 mProfileFd = profileFd; 8429 mProfileType = 0; 8430 mAutoStopProfiler = autoStopProfiler; 8431 } 8432 } 8433 8434 @Override 8435 public void setAlwaysFinish(boolean enabled) { 8436 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8437 "setAlwaysFinish()"); 8438 8439 Settings.Global.putInt( 8440 mContext.getContentResolver(), 8441 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8442 8443 synchronized (this) { 8444 mAlwaysFinishActivities = enabled; 8445 } 8446 } 8447 8448 @Override 8449 public void setActivityController(IActivityController controller) { 8450 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8451 "setActivityController()"); 8452 synchronized (this) { 8453 mController = controller; 8454 Watchdog.getInstance().setActivityController(controller); 8455 } 8456 } 8457 8458 @Override 8459 public void setUserIsMonkey(boolean userIsMonkey) { 8460 synchronized (this) { 8461 synchronized (mPidsSelfLocked) { 8462 final int callingPid = Binder.getCallingPid(); 8463 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8464 if (precessRecord == null) { 8465 throw new SecurityException("Unknown process: " + callingPid); 8466 } 8467 if (precessRecord.instrumentationUiAutomationConnection == null) { 8468 throw new SecurityException("Only an instrumentation process " 8469 + "with a UiAutomation can call setUserIsMonkey"); 8470 } 8471 } 8472 mUserIsMonkey = userIsMonkey; 8473 } 8474 } 8475 8476 @Override 8477 public boolean isUserAMonkey() { 8478 synchronized (this) { 8479 // If there is a controller also implies the user is a monkey. 8480 return (mUserIsMonkey || mController != null); 8481 } 8482 } 8483 8484 public void requestBugReport() { 8485 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8486 SystemProperties.set("ctl.start", "bugreport"); 8487 } 8488 8489 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8490 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8491 } 8492 8493 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8494 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8495 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8496 } 8497 return KEY_DISPATCHING_TIMEOUT; 8498 } 8499 8500 @Override 8501 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8502 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8503 != PackageManager.PERMISSION_GRANTED) { 8504 throw new SecurityException("Requires permission " 8505 + android.Manifest.permission.FILTER_EVENTS); 8506 } 8507 ProcessRecord proc; 8508 long timeout; 8509 synchronized (this) { 8510 synchronized (mPidsSelfLocked) { 8511 proc = mPidsSelfLocked.get(pid); 8512 } 8513 timeout = getInputDispatchingTimeoutLocked(proc); 8514 } 8515 8516 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8517 return -1; 8518 } 8519 8520 return timeout; 8521 } 8522 8523 /** 8524 * Handle input dispatching timeouts. 8525 * Returns whether input dispatching should be aborted or not. 8526 */ 8527 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8528 final ActivityRecord activity, final ActivityRecord parent, 8529 final boolean aboveSystem, String reason) { 8530 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8531 != PackageManager.PERMISSION_GRANTED) { 8532 throw new SecurityException("Requires permission " 8533 + android.Manifest.permission.FILTER_EVENTS); 8534 } 8535 8536 final String annotation; 8537 if (reason == null) { 8538 annotation = "Input dispatching timed out"; 8539 } else { 8540 annotation = "Input dispatching timed out (" + reason + ")"; 8541 } 8542 8543 if (proc != null) { 8544 synchronized (this) { 8545 if (proc.debugging) { 8546 return false; 8547 } 8548 8549 if (mDidDexOpt) { 8550 // Give more time since we were dexopting. 8551 mDidDexOpt = false; 8552 return false; 8553 } 8554 8555 if (proc.instrumentationClass != null) { 8556 Bundle info = new Bundle(); 8557 info.putString("shortMsg", "keyDispatchingTimedOut"); 8558 info.putString("longMsg", annotation); 8559 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8560 return true; 8561 } 8562 } 8563 mHandler.post(new Runnable() { 8564 @Override 8565 public void run() { 8566 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8567 } 8568 }); 8569 } 8570 8571 return true; 8572 } 8573 8574 public Bundle getAssistContextExtras(int requestType) { 8575 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8576 "getAssistContextExtras()"); 8577 PendingAssistExtras pae; 8578 Bundle extras = new Bundle(); 8579 synchronized (this) { 8580 ActivityRecord activity = getFocusedStack().mResumedActivity; 8581 if (activity == null) { 8582 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8583 return null; 8584 } 8585 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8586 if (activity.app == null || activity.app.thread == null) { 8587 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8588 return extras; 8589 } 8590 if (activity.app.pid == Binder.getCallingPid()) { 8591 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8592 return extras; 8593 } 8594 pae = new PendingAssistExtras(activity); 8595 try { 8596 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8597 requestType); 8598 mPendingAssistExtras.add(pae); 8599 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8600 } catch (RemoteException e) { 8601 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8602 return extras; 8603 } 8604 } 8605 synchronized (pae) { 8606 while (!pae.haveResult) { 8607 try { 8608 pae.wait(); 8609 } catch (InterruptedException e) { 8610 } 8611 } 8612 if (pae.result != null) { 8613 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8614 } 8615 } 8616 synchronized (this) { 8617 mPendingAssistExtras.remove(pae); 8618 mHandler.removeCallbacks(pae); 8619 } 8620 return extras; 8621 } 8622 8623 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8624 PendingAssistExtras pae = (PendingAssistExtras)token; 8625 synchronized (pae) { 8626 pae.result = extras; 8627 pae.haveResult = true; 8628 pae.notifyAll(); 8629 } 8630 } 8631 8632 public void registerProcessObserver(IProcessObserver observer) { 8633 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8634 "registerProcessObserver()"); 8635 synchronized (this) { 8636 mProcessObservers.register(observer); 8637 } 8638 } 8639 8640 @Override 8641 public void unregisterProcessObserver(IProcessObserver observer) { 8642 synchronized (this) { 8643 mProcessObservers.unregister(observer); 8644 } 8645 } 8646 8647 @Override 8648 public boolean convertFromTranslucent(IBinder token) { 8649 final long origId = Binder.clearCallingIdentity(); 8650 try { 8651 synchronized (this) { 8652 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8653 if (r == null) { 8654 return false; 8655 } 8656 if (r.changeWindowTranslucency(true)) { 8657 mWindowManager.setAppFullscreen(token, true); 8658 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8659 return true; 8660 } 8661 return false; 8662 } 8663 } finally { 8664 Binder.restoreCallingIdentity(origId); 8665 } 8666 } 8667 8668 @Override 8669 public boolean convertToTranslucent(IBinder token) { 8670 final long origId = Binder.clearCallingIdentity(); 8671 try { 8672 synchronized (this) { 8673 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8674 if (r == null) { 8675 return false; 8676 } 8677 if (r.changeWindowTranslucency(false)) { 8678 r.task.stack.convertToTranslucent(r); 8679 mWindowManager.setAppFullscreen(token, false); 8680 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8681 return true; 8682 } 8683 return false; 8684 } 8685 } finally { 8686 Binder.restoreCallingIdentity(origId); 8687 } 8688 } 8689 8690 @Override 8691 public void setImmersive(IBinder token, boolean immersive) { 8692 synchronized(this) { 8693 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8694 if (r == null) { 8695 throw new IllegalArgumentException(); 8696 } 8697 r.immersive = immersive; 8698 8699 // update associated state if we're frontmost 8700 if (r == mFocusedActivity) { 8701 if (DEBUG_IMMERSIVE) { 8702 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8703 } 8704 applyUpdateLockStateLocked(r); 8705 } 8706 } 8707 } 8708 8709 @Override 8710 public boolean isImmersive(IBinder token) { 8711 synchronized (this) { 8712 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8713 if (r == null) { 8714 throw new IllegalArgumentException(); 8715 } 8716 return r.immersive; 8717 } 8718 } 8719 8720 public boolean isTopActivityImmersive() { 8721 enforceNotIsolatedCaller("startActivity"); 8722 synchronized (this) { 8723 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8724 return (r != null) ? r.immersive : false; 8725 } 8726 } 8727 8728 public final void enterSafeMode() { 8729 synchronized(this) { 8730 // It only makes sense to do this before the system is ready 8731 // and started launching other packages. 8732 if (!mSystemReady) { 8733 try { 8734 AppGlobals.getPackageManager().enterSafeMode(); 8735 } catch (RemoteException e) { 8736 } 8737 } 8738 8739 mSafeMode = true; 8740 } 8741 } 8742 8743 public final void showSafeModeOverlay() { 8744 View v = LayoutInflater.from(mContext).inflate( 8745 com.android.internal.R.layout.safe_mode, null); 8746 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8747 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8748 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8749 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8750 lp.gravity = Gravity.BOTTOM | Gravity.START; 8751 lp.format = v.getBackground().getOpacity(); 8752 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8753 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8754 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8755 ((WindowManager)mContext.getSystemService( 8756 Context.WINDOW_SERVICE)).addView(v, lp); 8757 } 8758 8759 public void noteWakeupAlarm(IIntentSender sender) { 8760 if (!(sender instanceof PendingIntentRecord)) { 8761 return; 8762 } 8763 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8764 synchronized (stats) { 8765 if (mBatteryStatsService.isOnBattery()) { 8766 mBatteryStatsService.enforceCallingPermission(); 8767 PendingIntentRecord rec = (PendingIntentRecord)sender; 8768 int MY_UID = Binder.getCallingUid(); 8769 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8770 BatteryStatsImpl.Uid.Pkg pkg = 8771 stats.getPackageStatsLocked(uid, rec.key.packageName); 8772 pkg.incWakeupsLocked(); 8773 } 8774 } 8775 } 8776 8777 public boolean killPids(int[] pids, String pReason, boolean secure) { 8778 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8779 throw new SecurityException("killPids only available to the system"); 8780 } 8781 String reason = (pReason == null) ? "Unknown" : pReason; 8782 // XXX Note: don't acquire main activity lock here, because the window 8783 // manager calls in with its locks held. 8784 8785 boolean killed = false; 8786 synchronized (mPidsSelfLocked) { 8787 int[] types = new int[pids.length]; 8788 int worstType = 0; 8789 for (int i=0; i<pids.length; i++) { 8790 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8791 if (proc != null) { 8792 int type = proc.setAdj; 8793 types[i] = type; 8794 if (type > worstType) { 8795 worstType = type; 8796 } 8797 } 8798 } 8799 8800 // If the worst oom_adj is somewhere in the cached proc LRU range, 8801 // then constrain it so we will kill all cached procs. 8802 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8803 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8804 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8805 } 8806 8807 // If this is not a secure call, don't let it kill processes that 8808 // are important. 8809 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8810 worstType = ProcessList.SERVICE_ADJ; 8811 } 8812 8813 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8814 for (int i=0; i<pids.length; i++) { 8815 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8816 if (proc == null) { 8817 continue; 8818 } 8819 int adj = proc.setAdj; 8820 if (adj >= worstType && !proc.killedByAm) { 8821 killUnneededProcessLocked(proc, reason); 8822 killed = true; 8823 } 8824 } 8825 } 8826 return killed; 8827 } 8828 8829 @Override 8830 public void killUid(int uid, String reason) { 8831 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8832 throw new SecurityException("killUid only available to the system"); 8833 } 8834 synchronized (this) { 8835 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 8836 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 8837 reason != null ? reason : "kill uid"); 8838 } 8839 } 8840 8841 @Override 8842 public boolean killProcessesBelowForeground(String reason) { 8843 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8844 throw new SecurityException("killProcessesBelowForeground() only available to system"); 8845 } 8846 8847 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 8848 } 8849 8850 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 8851 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8852 throw new SecurityException("killProcessesBelowAdj() only available to system"); 8853 } 8854 8855 boolean killed = false; 8856 synchronized (mPidsSelfLocked) { 8857 final int size = mPidsSelfLocked.size(); 8858 for (int i = 0; i < size; i++) { 8859 final int pid = mPidsSelfLocked.keyAt(i); 8860 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8861 if (proc == null) continue; 8862 8863 final int adj = proc.setAdj; 8864 if (adj > belowAdj && !proc.killedByAm) { 8865 killUnneededProcessLocked(proc, reason); 8866 killed = true; 8867 } 8868 } 8869 } 8870 return killed; 8871 } 8872 8873 @Override 8874 public void hang(final IBinder who, boolean allowRestart) { 8875 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8876 != PackageManager.PERMISSION_GRANTED) { 8877 throw new SecurityException("Requires permission " 8878 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8879 } 8880 8881 final IBinder.DeathRecipient death = new DeathRecipient() { 8882 @Override 8883 public void binderDied() { 8884 synchronized (this) { 8885 notifyAll(); 8886 } 8887 } 8888 }; 8889 8890 try { 8891 who.linkToDeath(death, 0); 8892 } catch (RemoteException e) { 8893 Slog.w(TAG, "hang: given caller IBinder is already dead."); 8894 return; 8895 } 8896 8897 synchronized (this) { 8898 Watchdog.getInstance().setAllowRestart(allowRestart); 8899 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 8900 synchronized (death) { 8901 while (who.isBinderAlive()) { 8902 try { 8903 death.wait(); 8904 } catch (InterruptedException e) { 8905 } 8906 } 8907 } 8908 Watchdog.getInstance().setAllowRestart(true); 8909 } 8910 } 8911 8912 @Override 8913 public void restart() { 8914 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8915 != PackageManager.PERMISSION_GRANTED) { 8916 throw new SecurityException("Requires permission " 8917 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8918 } 8919 8920 Log.i(TAG, "Sending shutdown broadcast..."); 8921 8922 BroadcastReceiver br = new BroadcastReceiver() { 8923 @Override public void onReceive(Context context, Intent intent) { 8924 // Now the broadcast is done, finish up the low-level shutdown. 8925 Log.i(TAG, "Shutting down activity manager..."); 8926 shutdown(10000); 8927 Log.i(TAG, "Shutdown complete, restarting!"); 8928 Process.killProcess(Process.myPid()); 8929 System.exit(10); 8930 } 8931 }; 8932 8933 // First send the high-level shut down broadcast. 8934 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 8935 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 8936 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 8937 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 8938 mContext.sendOrderedBroadcastAsUser(intent, 8939 UserHandle.ALL, null, br, mHandler, 0, null, null); 8940 */ 8941 br.onReceive(mContext, intent); 8942 } 8943 8944 private long getLowRamTimeSinceIdle(long now) { 8945 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 8946 } 8947 8948 @Override 8949 public void performIdleMaintenance() { 8950 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8951 != PackageManager.PERMISSION_GRANTED) { 8952 throw new SecurityException("Requires permission " 8953 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8954 } 8955 8956 synchronized (this) { 8957 final long now = SystemClock.uptimeMillis(); 8958 final long timeSinceLastIdle = now - mLastIdleTime; 8959 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 8960 mLastIdleTime = now; 8961 mLowRamTimeSinceLastIdle = 0; 8962 if (mLowRamStartTime != 0) { 8963 mLowRamStartTime = now; 8964 } 8965 8966 StringBuilder sb = new StringBuilder(128); 8967 sb.append("Idle maintenance over "); 8968 TimeUtils.formatDuration(timeSinceLastIdle, sb); 8969 sb.append(" low RAM for "); 8970 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 8971 Slog.i(TAG, sb.toString()); 8972 8973 // If at least 1/3 of our time since the last idle period has been spent 8974 // with RAM low, then we want to kill processes. 8975 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 8976 8977 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 8978 ProcessRecord proc = mLruProcesses.get(i); 8979 if (proc.notCachedSinceIdle) { 8980 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 8981 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 8982 if (doKilling && proc.initialIdlePss != 0 8983 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 8984 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 8985 + " from " + proc.initialIdlePss + ")"); 8986 } 8987 } 8988 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 8989 proc.notCachedSinceIdle = true; 8990 proc.initialIdlePss = 0; 8991 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 8992 mSleeping, now); 8993 } 8994 } 8995 8996 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 8997 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 8998 } 8999 } 9000 9001 private void retrieveSettings() { 9002 final ContentResolver resolver = mContext.getContentResolver(); 9003 String debugApp = Settings.Global.getString( 9004 resolver, Settings.Global.DEBUG_APP); 9005 boolean waitForDebugger = Settings.Global.getInt( 9006 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9007 boolean alwaysFinishActivities = Settings.Global.getInt( 9008 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9009 boolean forceRtl = Settings.Global.getInt( 9010 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9011 // Transfer any global setting for forcing RTL layout, into a System Property 9012 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9013 9014 Configuration configuration = new Configuration(); 9015 Settings.System.getConfiguration(resolver, configuration); 9016 if (forceRtl) { 9017 // This will take care of setting the correct layout direction flags 9018 configuration.setLayoutDirection(configuration.locale); 9019 } 9020 9021 synchronized (this) { 9022 mDebugApp = mOrigDebugApp = debugApp; 9023 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9024 mAlwaysFinishActivities = alwaysFinishActivities; 9025 // This happens before any activities are started, so we can 9026 // change mConfiguration in-place. 9027 updateConfigurationLocked(configuration, null, false, true); 9028 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9029 } 9030 } 9031 9032 public boolean testIsSystemReady() { 9033 // no need to synchronize(this) just to read & return the value 9034 return mSystemReady; 9035 } 9036 9037 private static File getCalledPreBootReceiversFile() { 9038 File dataDir = Environment.getDataDirectory(); 9039 File systemDir = new File(dataDir, "system"); 9040 File fname = new File(systemDir, "called_pre_boots.dat"); 9041 return fname; 9042 } 9043 9044 static final int LAST_DONE_VERSION = 10000; 9045 9046 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9047 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9048 File file = getCalledPreBootReceiversFile(); 9049 FileInputStream fis = null; 9050 try { 9051 fis = new FileInputStream(file); 9052 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9053 int fvers = dis.readInt(); 9054 if (fvers == LAST_DONE_VERSION) { 9055 String vers = dis.readUTF(); 9056 String codename = dis.readUTF(); 9057 String build = dis.readUTF(); 9058 if (android.os.Build.VERSION.RELEASE.equals(vers) 9059 && android.os.Build.VERSION.CODENAME.equals(codename) 9060 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9061 int num = dis.readInt(); 9062 while (num > 0) { 9063 num--; 9064 String pkg = dis.readUTF(); 9065 String cls = dis.readUTF(); 9066 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9067 } 9068 } 9069 } 9070 } catch (FileNotFoundException e) { 9071 } catch (IOException e) { 9072 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9073 } finally { 9074 if (fis != null) { 9075 try { 9076 fis.close(); 9077 } catch (IOException e) { 9078 } 9079 } 9080 } 9081 return lastDoneReceivers; 9082 } 9083 9084 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9085 File file = getCalledPreBootReceiversFile(); 9086 FileOutputStream fos = null; 9087 DataOutputStream dos = null; 9088 try { 9089 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9090 fos = new FileOutputStream(file); 9091 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9092 dos.writeInt(LAST_DONE_VERSION); 9093 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9094 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9095 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9096 dos.writeInt(list.size()); 9097 for (int i=0; i<list.size(); i++) { 9098 dos.writeUTF(list.get(i).getPackageName()); 9099 dos.writeUTF(list.get(i).getClassName()); 9100 } 9101 } catch (IOException e) { 9102 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9103 file.delete(); 9104 } finally { 9105 FileUtils.sync(fos); 9106 if (dos != null) { 9107 try { 9108 dos.close(); 9109 } catch (IOException e) { 9110 // TODO Auto-generated catch block 9111 e.printStackTrace(); 9112 } 9113 } 9114 } 9115 } 9116 9117 public void systemReady(final Runnable goingCallback) { 9118 synchronized(this) { 9119 if (mSystemReady) { 9120 if (goingCallback != null) goingCallback.run(); 9121 return; 9122 } 9123 9124 // Check to see if there are any update receivers to run. 9125 if (!mDidUpdate) { 9126 if (mWaitingUpdate) { 9127 return; 9128 } 9129 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9130 List<ResolveInfo> ris = null; 9131 try { 9132 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9133 intent, null, 0, 0); 9134 } catch (RemoteException e) { 9135 } 9136 if (ris != null) { 9137 for (int i=ris.size()-1; i>=0; i--) { 9138 if ((ris.get(i).activityInfo.applicationInfo.flags 9139 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9140 ris.remove(i); 9141 } 9142 } 9143 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9144 9145 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9146 9147 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9148 for (int i=0; i<ris.size(); i++) { 9149 ActivityInfo ai = ris.get(i).activityInfo; 9150 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9151 if (lastDoneReceivers.contains(comp)) { 9152 // We already did the pre boot receiver for this app with the current 9153 // platform version, so don't do it again... 9154 ris.remove(i); 9155 i--; 9156 // ...however, do keep it as one that has been done, so we don't 9157 // forget about it when rewriting the file of last done receivers. 9158 doneReceivers.add(comp); 9159 } 9160 } 9161 9162 final int[] users = getUsersLocked(); 9163 for (int i=0; i<ris.size(); i++) { 9164 ActivityInfo ai = ris.get(i).activityInfo; 9165 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9166 doneReceivers.add(comp); 9167 intent.setComponent(comp); 9168 for (int j=0; j<users.length; j++) { 9169 IIntentReceiver finisher = null; 9170 if (i == ris.size()-1 && j == users.length-1) { 9171 finisher = new IIntentReceiver.Stub() { 9172 public void performReceive(Intent intent, int resultCode, 9173 String data, Bundle extras, boolean ordered, 9174 boolean sticky, int sendingUser) { 9175 // The raw IIntentReceiver interface is called 9176 // with the AM lock held, so redispatch to 9177 // execute our code without the lock. 9178 mHandler.post(new Runnable() { 9179 public void run() { 9180 synchronized (ActivityManagerService.this) { 9181 mDidUpdate = true; 9182 } 9183 writeLastDonePreBootReceivers(doneReceivers); 9184 showBootMessage(mContext.getText( 9185 R.string.android_upgrading_complete), 9186 false); 9187 systemReady(goingCallback); 9188 } 9189 }); 9190 } 9191 }; 9192 } 9193 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9194 + " for user " + users[j]); 9195 broadcastIntentLocked(null, null, intent, null, finisher, 9196 0, null, null, null, AppOpsManager.OP_NONE, 9197 true, false, MY_PID, Process.SYSTEM_UID, 9198 users[j]); 9199 if (finisher != null) { 9200 mWaitingUpdate = true; 9201 } 9202 } 9203 } 9204 } 9205 if (mWaitingUpdate) { 9206 return; 9207 } 9208 mDidUpdate = true; 9209 } 9210 9211 mAppOpsService.systemReady(); 9212 mSystemReady = true; 9213 } 9214 9215 ArrayList<ProcessRecord> procsToKill = null; 9216 synchronized(mPidsSelfLocked) { 9217 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9218 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9219 if (!isAllowedWhileBooting(proc.info)){ 9220 if (procsToKill == null) { 9221 procsToKill = new ArrayList<ProcessRecord>(); 9222 } 9223 procsToKill.add(proc); 9224 } 9225 } 9226 } 9227 9228 synchronized(this) { 9229 if (procsToKill != null) { 9230 for (int i=procsToKill.size()-1; i>=0; i--) { 9231 ProcessRecord proc = procsToKill.get(i); 9232 Slog.i(TAG, "Removing system update proc: " + proc); 9233 removeProcessLocked(proc, true, false, "system update done"); 9234 } 9235 } 9236 9237 // Now that we have cleaned up any update processes, we 9238 // are ready to start launching real processes and know that 9239 // we won't trample on them any more. 9240 mProcessesReady = true; 9241 } 9242 9243 Slog.i(TAG, "System now ready"); 9244 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9245 SystemClock.uptimeMillis()); 9246 9247 synchronized(this) { 9248 // Make sure we have no pre-ready processes sitting around. 9249 9250 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9251 ResolveInfo ri = mContext.getPackageManager() 9252 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9253 STOCK_PM_FLAGS); 9254 CharSequence errorMsg = null; 9255 if (ri != null) { 9256 ActivityInfo ai = ri.activityInfo; 9257 ApplicationInfo app = ai.applicationInfo; 9258 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9259 mTopAction = Intent.ACTION_FACTORY_TEST; 9260 mTopData = null; 9261 mTopComponent = new ComponentName(app.packageName, 9262 ai.name); 9263 } else { 9264 errorMsg = mContext.getResources().getText( 9265 com.android.internal.R.string.factorytest_not_system); 9266 } 9267 } else { 9268 errorMsg = mContext.getResources().getText( 9269 com.android.internal.R.string.factorytest_no_action); 9270 } 9271 if (errorMsg != null) { 9272 mTopAction = null; 9273 mTopData = null; 9274 mTopComponent = null; 9275 Message msg = Message.obtain(); 9276 msg.what = SHOW_FACTORY_ERROR_MSG; 9277 msg.getData().putCharSequence("msg", errorMsg); 9278 mHandler.sendMessage(msg); 9279 } 9280 } 9281 } 9282 9283 retrieveSettings(); 9284 9285 synchronized (this) { 9286 readGrantedUriPermissionsLocked(); 9287 } 9288 9289 if (goingCallback != null) goingCallback.run(); 9290 9291 synchronized (this) { 9292 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9293 try { 9294 List apps = AppGlobals.getPackageManager(). 9295 getPersistentApplications(STOCK_PM_FLAGS); 9296 if (apps != null) { 9297 int N = apps.size(); 9298 int i; 9299 for (i=0; i<N; i++) { 9300 ApplicationInfo info 9301 = (ApplicationInfo)apps.get(i); 9302 if (info != null && 9303 !info.packageName.equals("android")) { 9304 addAppLocked(info, false, null /* ABI override */); 9305 } 9306 } 9307 } 9308 } catch (RemoteException ex) { 9309 // pm is in same process, this will never happen. 9310 } 9311 } 9312 9313 // Start up initial activity. 9314 mBooting = true; 9315 9316 try { 9317 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9318 Message msg = Message.obtain(); 9319 msg.what = SHOW_UID_ERROR_MSG; 9320 mHandler.sendMessage(msg); 9321 } 9322 } catch (RemoteException e) { 9323 } 9324 9325 long ident = Binder.clearCallingIdentity(); 9326 try { 9327 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9328 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9329 | Intent.FLAG_RECEIVER_FOREGROUND); 9330 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9331 broadcastIntentLocked(null, null, intent, 9332 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9333 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9334 intent = new Intent(Intent.ACTION_USER_STARTING); 9335 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9336 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9337 broadcastIntentLocked(null, null, intent, 9338 null, new IIntentReceiver.Stub() { 9339 @Override 9340 public void performReceive(Intent intent, int resultCode, String data, 9341 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9342 throws RemoteException { 9343 } 9344 }, 0, null, null, 9345 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9346 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9347 } finally { 9348 Binder.restoreCallingIdentity(ident); 9349 } 9350 mStackSupervisor.resumeTopActivitiesLocked(); 9351 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9352 } 9353 } 9354 9355 private boolean makeAppCrashingLocked(ProcessRecord app, 9356 String shortMsg, String longMsg, String stackTrace) { 9357 app.crashing = true; 9358 app.crashingReport = generateProcessError(app, 9359 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9360 startAppProblemLocked(app); 9361 app.stopFreezingAllLocked(); 9362 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9363 } 9364 9365 private void makeAppNotRespondingLocked(ProcessRecord app, 9366 String activity, String shortMsg, String longMsg) { 9367 app.notResponding = true; 9368 app.notRespondingReport = generateProcessError(app, 9369 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9370 activity, shortMsg, longMsg, null); 9371 startAppProblemLocked(app); 9372 app.stopFreezingAllLocked(); 9373 } 9374 9375 /** 9376 * Generate a process error record, suitable for attachment to a ProcessRecord. 9377 * 9378 * @param app The ProcessRecord in which the error occurred. 9379 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9380 * ActivityManager.AppErrorStateInfo 9381 * @param activity The activity associated with the crash, if known. 9382 * @param shortMsg Short message describing the crash. 9383 * @param longMsg Long message describing the crash. 9384 * @param stackTrace Full crash stack trace, may be null. 9385 * 9386 * @return Returns a fully-formed AppErrorStateInfo record. 9387 */ 9388 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9389 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9390 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9391 9392 report.condition = condition; 9393 report.processName = app.processName; 9394 report.pid = app.pid; 9395 report.uid = app.info.uid; 9396 report.tag = activity; 9397 report.shortMsg = shortMsg; 9398 report.longMsg = longMsg; 9399 report.stackTrace = stackTrace; 9400 9401 return report; 9402 } 9403 9404 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9405 synchronized (this) { 9406 app.crashing = false; 9407 app.crashingReport = null; 9408 app.notResponding = false; 9409 app.notRespondingReport = null; 9410 if (app.anrDialog == fromDialog) { 9411 app.anrDialog = null; 9412 } 9413 if (app.waitDialog == fromDialog) { 9414 app.waitDialog = null; 9415 } 9416 if (app.pid > 0 && app.pid != MY_PID) { 9417 handleAppCrashLocked(app, null, null, null); 9418 killUnneededProcessLocked(app, "user request after error"); 9419 } 9420 } 9421 } 9422 9423 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9424 String stackTrace) { 9425 long now = SystemClock.uptimeMillis(); 9426 9427 Long crashTime; 9428 if (!app.isolated) { 9429 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9430 } else { 9431 crashTime = null; 9432 } 9433 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9434 // This process loses! 9435 Slog.w(TAG, "Process " + app.info.processName 9436 + " has crashed too many times: killing!"); 9437 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9438 app.userId, app.info.processName, app.uid); 9439 mStackSupervisor.handleAppCrashLocked(app); 9440 if (!app.persistent) { 9441 // We don't want to start this process again until the user 9442 // explicitly does so... but for persistent process, we really 9443 // need to keep it running. If a persistent process is actually 9444 // repeatedly crashing, then badness for everyone. 9445 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9446 app.info.processName); 9447 if (!app.isolated) { 9448 // XXX We don't have a way to mark isolated processes 9449 // as bad, since they don't have a peristent identity. 9450 mBadProcesses.put(app.info.processName, app.uid, 9451 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9452 mProcessCrashTimes.remove(app.info.processName, app.uid); 9453 } 9454 app.bad = true; 9455 app.removed = true; 9456 // Don't let services in this process be restarted and potentially 9457 // annoy the user repeatedly. Unless it is persistent, since those 9458 // processes run critical code. 9459 removeProcessLocked(app, false, false, "crash"); 9460 mStackSupervisor.resumeTopActivitiesLocked(); 9461 return false; 9462 } 9463 mStackSupervisor.resumeTopActivitiesLocked(); 9464 } else { 9465 mStackSupervisor.finishTopRunningActivityLocked(app); 9466 } 9467 9468 // Bump up the crash count of any services currently running in the proc. 9469 for (int i=app.services.size()-1; i>=0; i--) { 9470 // Any services running in the application need to be placed 9471 // back in the pending list. 9472 ServiceRecord sr = app.services.valueAt(i); 9473 sr.crashCount++; 9474 } 9475 9476 // If the crashing process is what we consider to be the "home process" and it has been 9477 // replaced by a third-party app, clear the package preferred activities from packages 9478 // with a home activity running in the process to prevent a repeatedly crashing app 9479 // from blocking the user to manually clear the list. 9480 final ArrayList<ActivityRecord> activities = app.activities; 9481 if (app == mHomeProcess && activities.size() > 0 9482 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9483 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9484 final ActivityRecord r = activities.get(activityNdx); 9485 if (r.isHomeActivity()) { 9486 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9487 try { 9488 ActivityThread.getPackageManager() 9489 .clearPackagePreferredActivities(r.packageName); 9490 } catch (RemoteException c) { 9491 // pm is in same process, this will never happen. 9492 } 9493 } 9494 } 9495 } 9496 9497 if (!app.isolated) { 9498 // XXX Can't keep track of crash times for isolated processes, 9499 // because they don't have a perisistent identity. 9500 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9501 } 9502 9503 return true; 9504 } 9505 9506 void startAppProblemLocked(ProcessRecord app) { 9507 if (app.userId == mCurrentUserId) { 9508 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9509 mContext, app.info.packageName, app.info.flags); 9510 } else { 9511 // If this app is not running under the current user, then we 9512 // can't give it a report button because that would require 9513 // launching the report UI under a different user. 9514 app.errorReportReceiver = null; 9515 } 9516 skipCurrentReceiverLocked(app); 9517 } 9518 9519 void skipCurrentReceiverLocked(ProcessRecord app) { 9520 for (BroadcastQueue queue : mBroadcastQueues) { 9521 queue.skipCurrentReceiverLocked(app); 9522 } 9523 } 9524 9525 /** 9526 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9527 * The application process will exit immediately after this call returns. 9528 * @param app object of the crashing app, null for the system server 9529 * @param crashInfo describing the exception 9530 */ 9531 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9532 ProcessRecord r = findAppProcess(app, "Crash"); 9533 final String processName = app == null ? "system_server" 9534 : (r == null ? "unknown" : r.processName); 9535 9536 handleApplicationCrashInner("crash", r, processName, crashInfo); 9537 } 9538 9539 /* Native crash reporting uses this inner version because it needs to be somewhat 9540 * decoupled from the AM-managed cleanup lifecycle 9541 */ 9542 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9543 ApplicationErrorReport.CrashInfo crashInfo) { 9544 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9545 UserHandle.getUserId(Binder.getCallingUid()), processName, 9546 r == null ? -1 : r.info.flags, 9547 crashInfo.exceptionClassName, 9548 crashInfo.exceptionMessage, 9549 crashInfo.throwFileName, 9550 crashInfo.throwLineNumber); 9551 9552 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9553 9554 crashApplication(r, crashInfo); 9555 } 9556 9557 public void handleApplicationStrictModeViolation( 9558 IBinder app, 9559 int violationMask, 9560 StrictMode.ViolationInfo info) { 9561 ProcessRecord r = findAppProcess(app, "StrictMode"); 9562 if (r == null) { 9563 return; 9564 } 9565 9566 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9567 Integer stackFingerprint = info.hashCode(); 9568 boolean logIt = true; 9569 synchronized (mAlreadyLoggedViolatedStacks) { 9570 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9571 logIt = false; 9572 // TODO: sub-sample into EventLog for these, with 9573 // the info.durationMillis? Then we'd get 9574 // the relative pain numbers, without logging all 9575 // the stack traces repeatedly. We'd want to do 9576 // likewise in the client code, which also does 9577 // dup suppression, before the Binder call. 9578 } else { 9579 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9580 mAlreadyLoggedViolatedStacks.clear(); 9581 } 9582 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9583 } 9584 } 9585 if (logIt) { 9586 logStrictModeViolationToDropBox(r, info); 9587 } 9588 } 9589 9590 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9591 AppErrorResult result = new AppErrorResult(); 9592 synchronized (this) { 9593 final long origId = Binder.clearCallingIdentity(); 9594 9595 Message msg = Message.obtain(); 9596 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9597 HashMap<String, Object> data = new HashMap<String, Object>(); 9598 data.put("result", result); 9599 data.put("app", r); 9600 data.put("violationMask", violationMask); 9601 data.put("info", info); 9602 msg.obj = data; 9603 mHandler.sendMessage(msg); 9604 9605 Binder.restoreCallingIdentity(origId); 9606 } 9607 int res = result.get(); 9608 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9609 } 9610 } 9611 9612 // Depending on the policy in effect, there could be a bunch of 9613 // these in quick succession so we try to batch these together to 9614 // minimize disk writes, number of dropbox entries, and maximize 9615 // compression, by having more fewer, larger records. 9616 private void logStrictModeViolationToDropBox( 9617 ProcessRecord process, 9618 StrictMode.ViolationInfo info) { 9619 if (info == null) { 9620 return; 9621 } 9622 final boolean isSystemApp = process == null || 9623 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9624 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9625 final String processName = process == null ? "unknown" : process.processName; 9626 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9627 final DropBoxManager dbox = (DropBoxManager) 9628 mContext.getSystemService(Context.DROPBOX_SERVICE); 9629 9630 // Exit early if the dropbox isn't configured to accept this report type. 9631 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9632 9633 boolean bufferWasEmpty; 9634 boolean needsFlush; 9635 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9636 synchronized (sb) { 9637 bufferWasEmpty = sb.length() == 0; 9638 appendDropBoxProcessHeaders(process, processName, sb); 9639 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9640 sb.append("System-App: ").append(isSystemApp).append("\n"); 9641 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9642 if (info.violationNumThisLoop != 0) { 9643 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9644 } 9645 if (info.numAnimationsRunning != 0) { 9646 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9647 } 9648 if (info.broadcastIntentAction != null) { 9649 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9650 } 9651 if (info.durationMillis != -1) { 9652 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9653 } 9654 if (info.numInstances != -1) { 9655 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9656 } 9657 if (info.tags != null) { 9658 for (String tag : info.tags) { 9659 sb.append("Span-Tag: ").append(tag).append("\n"); 9660 } 9661 } 9662 sb.append("\n"); 9663 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9664 sb.append(info.crashInfo.stackTrace); 9665 } 9666 sb.append("\n"); 9667 9668 // Only buffer up to ~64k. Various logging bits truncate 9669 // things at 128k. 9670 needsFlush = (sb.length() > 64 * 1024); 9671 } 9672 9673 // Flush immediately if the buffer's grown too large, or this 9674 // is a non-system app. Non-system apps are isolated with a 9675 // different tag & policy and not batched. 9676 // 9677 // Batching is useful during internal testing with 9678 // StrictMode settings turned up high. Without batching, 9679 // thousands of separate files could be created on boot. 9680 if (!isSystemApp || needsFlush) { 9681 new Thread("Error dump: " + dropboxTag) { 9682 @Override 9683 public void run() { 9684 String report; 9685 synchronized (sb) { 9686 report = sb.toString(); 9687 sb.delete(0, sb.length()); 9688 sb.trimToSize(); 9689 } 9690 if (report.length() != 0) { 9691 dbox.addText(dropboxTag, report); 9692 } 9693 } 9694 }.start(); 9695 return; 9696 } 9697 9698 // System app batching: 9699 if (!bufferWasEmpty) { 9700 // An existing dropbox-writing thread is outstanding, so 9701 // we don't need to start it up. The existing thread will 9702 // catch the buffer appends we just did. 9703 return; 9704 } 9705 9706 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9707 // (After this point, we shouldn't access AMS internal data structures.) 9708 new Thread("Error dump: " + dropboxTag) { 9709 @Override 9710 public void run() { 9711 // 5 second sleep to let stacks arrive and be batched together 9712 try { 9713 Thread.sleep(5000); // 5 seconds 9714 } catch (InterruptedException e) {} 9715 9716 String errorReport; 9717 synchronized (mStrictModeBuffer) { 9718 errorReport = mStrictModeBuffer.toString(); 9719 if (errorReport.length() == 0) { 9720 return; 9721 } 9722 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9723 mStrictModeBuffer.trimToSize(); 9724 } 9725 dbox.addText(dropboxTag, errorReport); 9726 } 9727 }.start(); 9728 } 9729 9730 /** 9731 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9732 * @param app object of the crashing app, null for the system server 9733 * @param tag reported by the caller 9734 * @param crashInfo describing the context of the error 9735 * @return true if the process should exit immediately (WTF is fatal) 9736 */ 9737 public boolean handleApplicationWtf(IBinder app, String tag, 9738 ApplicationErrorReport.CrashInfo crashInfo) { 9739 ProcessRecord r = findAppProcess(app, "WTF"); 9740 final String processName = app == null ? "system_server" 9741 : (r == null ? "unknown" : r.processName); 9742 9743 EventLog.writeEvent(EventLogTags.AM_WTF, 9744 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9745 processName, 9746 r == null ? -1 : r.info.flags, 9747 tag, crashInfo.exceptionMessage); 9748 9749 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9750 9751 if (r != null && r.pid != Process.myPid() && 9752 Settings.Global.getInt(mContext.getContentResolver(), 9753 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9754 crashApplication(r, crashInfo); 9755 return true; 9756 } else { 9757 return false; 9758 } 9759 } 9760 9761 /** 9762 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9763 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9764 */ 9765 private ProcessRecord findAppProcess(IBinder app, String reason) { 9766 if (app == null) { 9767 return null; 9768 } 9769 9770 synchronized (this) { 9771 final int NP = mProcessNames.getMap().size(); 9772 for (int ip=0; ip<NP; ip++) { 9773 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9774 final int NA = apps.size(); 9775 for (int ia=0; ia<NA; ia++) { 9776 ProcessRecord p = apps.valueAt(ia); 9777 if (p.thread != null && p.thread.asBinder() == app) { 9778 return p; 9779 } 9780 } 9781 } 9782 9783 Slog.w(TAG, "Can't find mystery application for " + reason 9784 + " from pid=" + Binder.getCallingPid() 9785 + " uid=" + Binder.getCallingUid() + ": " + app); 9786 return null; 9787 } 9788 } 9789 9790 /** 9791 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9792 * to append various headers to the dropbox log text. 9793 */ 9794 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9795 StringBuilder sb) { 9796 // Watchdog thread ends up invoking this function (with 9797 // a null ProcessRecord) to add the stack file to dropbox. 9798 // Do not acquire a lock on this (am) in such cases, as it 9799 // could cause a potential deadlock, if and when watchdog 9800 // is invoked due to unavailability of lock on am and it 9801 // would prevent watchdog from killing system_server. 9802 if (process == null) { 9803 sb.append("Process: ").append(processName).append("\n"); 9804 return; 9805 } 9806 // Note: ProcessRecord 'process' is guarded by the service 9807 // instance. (notably process.pkgList, which could otherwise change 9808 // concurrently during execution of this method) 9809 synchronized (this) { 9810 sb.append("Process: ").append(processName).append("\n"); 9811 int flags = process.info.flags; 9812 IPackageManager pm = AppGlobals.getPackageManager(); 9813 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 9814 for (int ip=0; ip<process.pkgList.size(); ip++) { 9815 String pkg = process.pkgList.keyAt(ip); 9816 sb.append("Package: ").append(pkg); 9817 try { 9818 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 9819 if (pi != null) { 9820 sb.append(" v").append(pi.versionCode); 9821 if (pi.versionName != null) { 9822 sb.append(" (").append(pi.versionName).append(")"); 9823 } 9824 } 9825 } catch (RemoteException e) { 9826 Slog.e(TAG, "Error getting package info: " + pkg, e); 9827 } 9828 sb.append("\n"); 9829 } 9830 } 9831 } 9832 9833 private static String processClass(ProcessRecord process) { 9834 if (process == null || process.pid == MY_PID) { 9835 return "system_server"; 9836 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9837 return "system_app"; 9838 } else { 9839 return "data_app"; 9840 } 9841 } 9842 9843 /** 9844 * Write a description of an error (crash, WTF, ANR) to the drop box. 9845 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 9846 * @param process which caused the error, null means the system server 9847 * @param activity which triggered the error, null if unknown 9848 * @param parent activity related to the error, null if unknown 9849 * @param subject line related to the error, null if absent 9850 * @param report in long form describing the error, null if absent 9851 * @param logFile to include in the report, null if none 9852 * @param crashInfo giving an application stack trace, null if absent 9853 */ 9854 public void addErrorToDropBox(String eventType, 9855 ProcessRecord process, String processName, ActivityRecord activity, 9856 ActivityRecord parent, String subject, 9857 final String report, final File logFile, 9858 final ApplicationErrorReport.CrashInfo crashInfo) { 9859 // NOTE -- this must never acquire the ActivityManagerService lock, 9860 // otherwise the watchdog may be prevented from resetting the system. 9861 9862 final String dropboxTag = processClass(process) + "_" + eventType; 9863 final DropBoxManager dbox = (DropBoxManager) 9864 mContext.getSystemService(Context.DROPBOX_SERVICE); 9865 9866 // Exit early if the dropbox isn't configured to accept this report type. 9867 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9868 9869 final StringBuilder sb = new StringBuilder(1024); 9870 appendDropBoxProcessHeaders(process, processName, sb); 9871 if (activity != null) { 9872 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 9873 } 9874 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 9875 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 9876 } 9877 if (parent != null && parent != activity) { 9878 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 9879 } 9880 if (subject != null) { 9881 sb.append("Subject: ").append(subject).append("\n"); 9882 } 9883 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9884 if (Debug.isDebuggerConnected()) { 9885 sb.append("Debugger: Connected\n"); 9886 } 9887 sb.append("\n"); 9888 9889 // Do the rest in a worker thread to avoid blocking the caller on I/O 9890 // (After this point, we shouldn't access AMS internal data structures.) 9891 Thread worker = new Thread("Error dump: " + dropboxTag) { 9892 @Override 9893 public void run() { 9894 if (report != null) { 9895 sb.append(report); 9896 } 9897 if (logFile != null) { 9898 try { 9899 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 9900 "\n\n[[TRUNCATED]]")); 9901 } catch (IOException e) { 9902 Slog.e(TAG, "Error reading " + logFile, e); 9903 } 9904 } 9905 if (crashInfo != null && crashInfo.stackTrace != null) { 9906 sb.append(crashInfo.stackTrace); 9907 } 9908 9909 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 9910 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 9911 if (lines > 0) { 9912 sb.append("\n"); 9913 9914 // Merge several logcat streams, and take the last N lines 9915 InputStreamReader input = null; 9916 try { 9917 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 9918 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 9919 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 9920 9921 try { logcat.getOutputStream().close(); } catch (IOException e) {} 9922 try { logcat.getErrorStream().close(); } catch (IOException e) {} 9923 input = new InputStreamReader(logcat.getInputStream()); 9924 9925 int num; 9926 char[] buf = new char[8192]; 9927 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 9928 } catch (IOException e) { 9929 Slog.e(TAG, "Error running logcat", e); 9930 } finally { 9931 if (input != null) try { input.close(); } catch (IOException e) {} 9932 } 9933 } 9934 9935 dbox.addText(dropboxTag, sb.toString()); 9936 } 9937 }; 9938 9939 if (process == null) { 9940 // If process is null, we are being called from some internal code 9941 // and may be about to die -- run this synchronously. 9942 worker.run(); 9943 } else { 9944 worker.start(); 9945 } 9946 } 9947 9948 /** 9949 * Bring up the "unexpected error" dialog box for a crashing app. 9950 * Deal with edge cases (intercepts from instrumented applications, 9951 * ActivityController, error intent receivers, that sort of thing). 9952 * @param r the application crashing 9953 * @param crashInfo describing the failure 9954 */ 9955 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 9956 long timeMillis = System.currentTimeMillis(); 9957 String shortMsg = crashInfo.exceptionClassName; 9958 String longMsg = crashInfo.exceptionMessage; 9959 String stackTrace = crashInfo.stackTrace; 9960 if (shortMsg != null && longMsg != null) { 9961 longMsg = shortMsg + ": " + longMsg; 9962 } else if (shortMsg != null) { 9963 longMsg = shortMsg; 9964 } 9965 9966 AppErrorResult result = new AppErrorResult(); 9967 synchronized (this) { 9968 if (mController != null) { 9969 try { 9970 String name = r != null ? r.processName : null; 9971 int pid = r != null ? r.pid : Binder.getCallingPid(); 9972 if (!mController.appCrashed(name, pid, 9973 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 9974 Slog.w(TAG, "Force-killing crashed app " + name 9975 + " at watcher's request"); 9976 Process.killProcess(pid); 9977 return; 9978 } 9979 } catch (RemoteException e) { 9980 mController = null; 9981 Watchdog.getInstance().setActivityController(null); 9982 } 9983 } 9984 9985 final long origId = Binder.clearCallingIdentity(); 9986 9987 // If this process is running instrumentation, finish it. 9988 if (r != null && r.instrumentationClass != null) { 9989 Slog.w(TAG, "Error in app " + r.processName 9990 + " running instrumentation " + r.instrumentationClass + ":"); 9991 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 9992 if (longMsg != null) Slog.w(TAG, " " + longMsg); 9993 Bundle info = new Bundle(); 9994 info.putString("shortMsg", shortMsg); 9995 info.putString("longMsg", longMsg); 9996 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 9997 Binder.restoreCallingIdentity(origId); 9998 return; 9999 } 10000 10001 // If we can't identify the process or it's already exceeded its crash quota, 10002 // quit right away without showing a crash dialog. 10003 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10004 Binder.restoreCallingIdentity(origId); 10005 return; 10006 } 10007 10008 Message msg = Message.obtain(); 10009 msg.what = SHOW_ERROR_MSG; 10010 HashMap data = new HashMap(); 10011 data.put("result", result); 10012 data.put("app", r); 10013 msg.obj = data; 10014 mHandler.sendMessage(msg); 10015 10016 Binder.restoreCallingIdentity(origId); 10017 } 10018 10019 int res = result.get(); 10020 10021 Intent appErrorIntent = null; 10022 synchronized (this) { 10023 if (r != null && !r.isolated) { 10024 // XXX Can't keep track of crash time for isolated processes, 10025 // since they don't have a persistent identity. 10026 mProcessCrashTimes.put(r.info.processName, r.uid, 10027 SystemClock.uptimeMillis()); 10028 } 10029 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10030 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10031 } 10032 } 10033 10034 if (appErrorIntent != null) { 10035 try { 10036 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10037 } catch (ActivityNotFoundException e) { 10038 Slog.w(TAG, "bug report receiver dissappeared", e); 10039 } 10040 } 10041 } 10042 10043 Intent createAppErrorIntentLocked(ProcessRecord r, 10044 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10045 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10046 if (report == null) { 10047 return null; 10048 } 10049 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10050 result.setComponent(r.errorReportReceiver); 10051 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10052 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10053 return result; 10054 } 10055 10056 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10057 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10058 if (r.errorReportReceiver == null) { 10059 return null; 10060 } 10061 10062 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10063 return null; 10064 } 10065 10066 ApplicationErrorReport report = new ApplicationErrorReport(); 10067 report.packageName = r.info.packageName; 10068 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10069 report.processName = r.processName; 10070 report.time = timeMillis; 10071 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10072 10073 if (r.crashing || r.forceCrashReport) { 10074 report.type = ApplicationErrorReport.TYPE_CRASH; 10075 report.crashInfo = crashInfo; 10076 } else if (r.notResponding) { 10077 report.type = ApplicationErrorReport.TYPE_ANR; 10078 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10079 10080 report.anrInfo.activity = r.notRespondingReport.tag; 10081 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10082 report.anrInfo.info = r.notRespondingReport.longMsg; 10083 } 10084 10085 return report; 10086 } 10087 10088 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10089 enforceNotIsolatedCaller("getProcessesInErrorState"); 10090 // assume our apps are happy - lazy create the list 10091 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10092 10093 final boolean allUsers = ActivityManager.checkUidPermission( 10094 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10095 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10096 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10097 10098 synchronized (this) { 10099 10100 // iterate across all processes 10101 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10102 ProcessRecord app = mLruProcesses.get(i); 10103 if (!allUsers && app.userId != userId) { 10104 continue; 10105 } 10106 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10107 // This one's in trouble, so we'll generate a report for it 10108 // crashes are higher priority (in case there's a crash *and* an anr) 10109 ActivityManager.ProcessErrorStateInfo report = null; 10110 if (app.crashing) { 10111 report = app.crashingReport; 10112 } else if (app.notResponding) { 10113 report = app.notRespondingReport; 10114 } 10115 10116 if (report != null) { 10117 if (errList == null) { 10118 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10119 } 10120 errList.add(report); 10121 } else { 10122 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10123 " crashing = " + app.crashing + 10124 " notResponding = " + app.notResponding); 10125 } 10126 } 10127 } 10128 } 10129 10130 return errList; 10131 } 10132 10133 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10134 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10135 if (currApp != null) { 10136 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10137 } 10138 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10139 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10140 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10141 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10142 if (currApp != null) { 10143 currApp.lru = 0; 10144 } 10145 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10146 } else if (adj >= ProcessList.SERVICE_ADJ) { 10147 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10148 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10149 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10150 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10151 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10152 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10153 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10154 } else { 10155 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10156 } 10157 } 10158 10159 private void fillInProcMemInfo(ProcessRecord app, 10160 ActivityManager.RunningAppProcessInfo outInfo) { 10161 outInfo.pid = app.pid; 10162 outInfo.uid = app.info.uid; 10163 if (mHeavyWeightProcess == app) { 10164 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10165 } 10166 if (app.persistent) { 10167 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10168 } 10169 if (app.activities.size() > 0) { 10170 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10171 } 10172 outInfo.lastTrimLevel = app.trimMemoryLevel; 10173 int adj = app.curAdj; 10174 outInfo.importance = oomAdjToImportance(adj, outInfo); 10175 outInfo.importanceReasonCode = app.adjTypeCode; 10176 } 10177 10178 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10179 enforceNotIsolatedCaller("getRunningAppProcesses"); 10180 // Lazy instantiation of list 10181 List<ActivityManager.RunningAppProcessInfo> runList = null; 10182 final boolean allUsers = ActivityManager.checkUidPermission( 10183 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10184 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10185 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10186 synchronized (this) { 10187 // Iterate across all processes 10188 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10189 ProcessRecord app = mLruProcesses.get(i); 10190 if (!allUsers && app.userId != userId) { 10191 continue; 10192 } 10193 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10194 // Generate process state info for running application 10195 ActivityManager.RunningAppProcessInfo currApp = 10196 new ActivityManager.RunningAppProcessInfo(app.processName, 10197 app.pid, app.getPackageList()); 10198 fillInProcMemInfo(app, currApp); 10199 if (app.adjSource instanceof ProcessRecord) { 10200 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10201 currApp.importanceReasonImportance = oomAdjToImportance( 10202 app.adjSourceOom, null); 10203 } else if (app.adjSource instanceof ActivityRecord) { 10204 ActivityRecord r = (ActivityRecord)app.adjSource; 10205 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10206 } 10207 if (app.adjTarget instanceof ComponentName) { 10208 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10209 } 10210 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10211 // + " lru=" + currApp.lru); 10212 if (runList == null) { 10213 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10214 } 10215 runList.add(currApp); 10216 } 10217 } 10218 } 10219 return runList; 10220 } 10221 10222 public List<ApplicationInfo> getRunningExternalApplications() { 10223 enforceNotIsolatedCaller("getRunningExternalApplications"); 10224 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10225 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10226 if (runningApps != null && runningApps.size() > 0) { 10227 Set<String> extList = new HashSet<String>(); 10228 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10229 if (app.pkgList != null) { 10230 for (String pkg : app.pkgList) { 10231 extList.add(pkg); 10232 } 10233 } 10234 } 10235 IPackageManager pm = AppGlobals.getPackageManager(); 10236 for (String pkg : extList) { 10237 try { 10238 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10239 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10240 retList.add(info); 10241 } 10242 } catch (RemoteException e) { 10243 } 10244 } 10245 } 10246 return retList; 10247 } 10248 10249 @Override 10250 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10251 enforceNotIsolatedCaller("getMyMemoryState"); 10252 synchronized (this) { 10253 ProcessRecord proc; 10254 synchronized (mPidsSelfLocked) { 10255 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10256 } 10257 fillInProcMemInfo(proc, outInfo); 10258 } 10259 } 10260 10261 @Override 10262 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10263 if (checkCallingPermission(android.Manifest.permission.DUMP) 10264 != PackageManager.PERMISSION_GRANTED) { 10265 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10266 + Binder.getCallingPid() 10267 + ", uid=" + Binder.getCallingUid() 10268 + " without permission " 10269 + android.Manifest.permission.DUMP); 10270 return; 10271 } 10272 10273 boolean dumpAll = false; 10274 boolean dumpClient = false; 10275 String dumpPackage = null; 10276 10277 int opti = 0; 10278 while (opti < args.length) { 10279 String opt = args[opti]; 10280 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10281 break; 10282 } 10283 opti++; 10284 if ("-a".equals(opt)) { 10285 dumpAll = true; 10286 } else if ("-c".equals(opt)) { 10287 dumpClient = true; 10288 } else if ("-h".equals(opt)) { 10289 pw.println("Activity manager dump options:"); 10290 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10291 pw.println(" cmd may be one of:"); 10292 pw.println(" a[ctivities]: activity stack state"); 10293 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10294 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10295 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10296 pw.println(" o[om]: out of memory management"); 10297 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10298 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10299 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10300 pw.println(" service [COMP_SPEC]: service client-side state"); 10301 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10302 pw.println(" all: dump all activities"); 10303 pw.println(" top: dump the top activity"); 10304 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10305 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10306 pw.println(" a partial substring in a component name, a"); 10307 pw.println(" hex object identifier."); 10308 pw.println(" -a: include all available server state."); 10309 pw.println(" -c: include client state."); 10310 return; 10311 } else { 10312 pw.println("Unknown argument: " + opt + "; use -h for help"); 10313 } 10314 } 10315 10316 long origId = Binder.clearCallingIdentity(); 10317 boolean more = false; 10318 // Is the caller requesting to dump a particular piece of data? 10319 if (opti < args.length) { 10320 String cmd = args[opti]; 10321 opti++; 10322 if ("activities".equals(cmd) || "a".equals(cmd)) { 10323 synchronized (this) { 10324 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10325 } 10326 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10327 String[] newArgs; 10328 String name; 10329 if (opti >= args.length) { 10330 name = null; 10331 newArgs = EMPTY_STRING_ARRAY; 10332 } else { 10333 name = args[opti]; 10334 opti++; 10335 newArgs = new String[args.length - opti]; 10336 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10337 args.length - opti); 10338 } 10339 synchronized (this) { 10340 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10341 } 10342 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10343 String[] newArgs; 10344 String name; 10345 if (opti >= args.length) { 10346 name = null; 10347 newArgs = EMPTY_STRING_ARRAY; 10348 } else { 10349 name = args[opti]; 10350 opti++; 10351 newArgs = new String[args.length - opti]; 10352 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10353 args.length - opti); 10354 } 10355 synchronized (this) { 10356 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10357 } 10358 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10359 String[] newArgs; 10360 String name; 10361 if (opti >= args.length) { 10362 name = null; 10363 newArgs = EMPTY_STRING_ARRAY; 10364 } else { 10365 name = args[opti]; 10366 opti++; 10367 newArgs = new String[args.length - opti]; 10368 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10369 args.length - opti); 10370 } 10371 synchronized (this) { 10372 dumpProcessesLocked(fd, pw, args, opti, true, name); 10373 } 10374 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10375 synchronized (this) { 10376 dumpOomLocked(fd, pw, args, opti, true); 10377 } 10378 } else if ("provider".equals(cmd)) { 10379 String[] newArgs; 10380 String name; 10381 if (opti >= args.length) { 10382 name = null; 10383 newArgs = EMPTY_STRING_ARRAY; 10384 } else { 10385 name = args[opti]; 10386 opti++; 10387 newArgs = new String[args.length - opti]; 10388 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10389 } 10390 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10391 pw.println("No providers match: " + name); 10392 pw.println("Use -h for help."); 10393 } 10394 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10395 synchronized (this) { 10396 dumpProvidersLocked(fd, pw, args, opti, true, null); 10397 } 10398 } else if ("service".equals(cmd)) { 10399 String[] newArgs; 10400 String name; 10401 if (opti >= args.length) { 10402 name = null; 10403 newArgs = EMPTY_STRING_ARRAY; 10404 } else { 10405 name = args[opti]; 10406 opti++; 10407 newArgs = new String[args.length - opti]; 10408 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10409 args.length - opti); 10410 } 10411 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10412 pw.println("No services match: " + name); 10413 pw.println("Use -h for help."); 10414 } 10415 } else if ("package".equals(cmd)) { 10416 String[] newArgs; 10417 if (opti >= args.length) { 10418 pw.println("package: no package name specified"); 10419 pw.println("Use -h for help."); 10420 } else { 10421 dumpPackage = args[opti]; 10422 opti++; 10423 newArgs = new String[args.length - opti]; 10424 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10425 args.length - opti); 10426 args = newArgs; 10427 opti = 0; 10428 more = true; 10429 } 10430 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10431 synchronized (this) { 10432 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10433 } 10434 } else { 10435 // Dumping a single activity? 10436 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10437 pw.println("Bad activity command, or no activities match: " + cmd); 10438 pw.println("Use -h for help."); 10439 } 10440 } 10441 if (!more) { 10442 Binder.restoreCallingIdentity(origId); 10443 return; 10444 } 10445 } 10446 10447 // No piece of data specified, dump everything. 10448 synchronized (this) { 10449 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10450 pw.println(); 10451 if (dumpAll) { 10452 pw.println("-------------------------------------------------------------------------------"); 10453 } 10454 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10455 pw.println(); 10456 if (dumpAll) { 10457 pw.println("-------------------------------------------------------------------------------"); 10458 } 10459 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10460 pw.println(); 10461 if (dumpAll) { 10462 pw.println("-------------------------------------------------------------------------------"); 10463 } 10464 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10465 pw.println(); 10466 if (dumpAll) { 10467 pw.println("-------------------------------------------------------------------------------"); 10468 } 10469 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10470 pw.println(); 10471 if (dumpAll) { 10472 pw.println("-------------------------------------------------------------------------------"); 10473 } 10474 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10475 } 10476 Binder.restoreCallingIdentity(origId); 10477 } 10478 10479 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10480 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10481 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10482 10483 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10484 dumpPackage); 10485 boolean needSep = printedAnything; 10486 10487 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10488 dumpPackage, needSep, " mFocusedActivity: "); 10489 if (printed) { 10490 printedAnything = true; 10491 needSep = false; 10492 } 10493 10494 if (dumpPackage == null) { 10495 if (needSep) { 10496 pw.println(); 10497 } 10498 needSep = true; 10499 printedAnything = true; 10500 mStackSupervisor.dump(pw, " "); 10501 } 10502 10503 if (mRecentTasks.size() > 0) { 10504 boolean printedHeader = false; 10505 10506 final int N = mRecentTasks.size(); 10507 for (int i=0; i<N; i++) { 10508 TaskRecord tr = mRecentTasks.get(i); 10509 if (dumpPackage != null) { 10510 if (tr.realActivity == null || 10511 !dumpPackage.equals(tr.realActivity)) { 10512 continue; 10513 } 10514 } 10515 if (!printedHeader) { 10516 if (needSep) { 10517 pw.println(); 10518 } 10519 pw.println(" Recent tasks:"); 10520 printedHeader = true; 10521 printedAnything = true; 10522 } 10523 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10524 pw.println(tr); 10525 if (dumpAll) { 10526 mRecentTasks.get(i).dump(pw, " "); 10527 } 10528 } 10529 } 10530 10531 if (!printedAnything) { 10532 pw.println(" (nothing)"); 10533 } 10534 } 10535 10536 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10537 int opti, boolean dumpAll, String dumpPackage) { 10538 boolean needSep = false; 10539 boolean printedAnything = false; 10540 int numPers = 0; 10541 10542 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10543 10544 if (dumpAll) { 10545 final int NP = mProcessNames.getMap().size(); 10546 for (int ip=0; ip<NP; ip++) { 10547 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10548 final int NA = procs.size(); 10549 for (int ia=0; ia<NA; ia++) { 10550 ProcessRecord r = procs.valueAt(ia); 10551 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10552 continue; 10553 } 10554 if (!needSep) { 10555 pw.println(" All known processes:"); 10556 needSep = true; 10557 printedAnything = true; 10558 } 10559 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10560 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10561 pw.print(" "); pw.println(r); 10562 r.dump(pw, " "); 10563 if (r.persistent) { 10564 numPers++; 10565 } 10566 } 10567 } 10568 } 10569 10570 if (mIsolatedProcesses.size() > 0) { 10571 boolean printed = false; 10572 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10573 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10574 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10575 continue; 10576 } 10577 if (!printed) { 10578 if (needSep) { 10579 pw.println(); 10580 } 10581 pw.println(" Isolated process list (sorted by uid):"); 10582 printedAnything = true; 10583 printed = true; 10584 needSep = true; 10585 } 10586 pw.println(String.format("%sIsolated #%2d: %s", 10587 " ", i, r.toString())); 10588 } 10589 } 10590 10591 if (mLruProcesses.size() > 0) { 10592 if (needSep) { 10593 pw.println(); 10594 } 10595 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10596 pw.print(" total, non-act at "); 10597 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10598 pw.print(", non-svc at "); 10599 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10600 pw.println("):"); 10601 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10602 needSep = true; 10603 printedAnything = true; 10604 } 10605 10606 if (dumpAll || dumpPackage != null) { 10607 synchronized (mPidsSelfLocked) { 10608 boolean printed = false; 10609 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10610 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10611 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10612 continue; 10613 } 10614 if (!printed) { 10615 if (needSep) pw.println(); 10616 needSep = true; 10617 pw.println(" PID mappings:"); 10618 printed = true; 10619 printedAnything = true; 10620 } 10621 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10622 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10623 } 10624 } 10625 } 10626 10627 if (mForegroundProcesses.size() > 0) { 10628 synchronized (mPidsSelfLocked) { 10629 boolean printed = false; 10630 for (int i=0; i<mForegroundProcesses.size(); i++) { 10631 ProcessRecord r = mPidsSelfLocked.get( 10632 mForegroundProcesses.valueAt(i).pid); 10633 if (dumpPackage != null && (r == null 10634 || !r.pkgList.containsKey(dumpPackage))) { 10635 continue; 10636 } 10637 if (!printed) { 10638 if (needSep) pw.println(); 10639 needSep = true; 10640 pw.println(" Foreground Processes:"); 10641 printed = true; 10642 printedAnything = true; 10643 } 10644 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10645 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10646 } 10647 } 10648 } 10649 10650 if (mPersistentStartingProcesses.size() > 0) { 10651 if (needSep) pw.println(); 10652 needSep = true; 10653 printedAnything = true; 10654 pw.println(" Persisent processes that are starting:"); 10655 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10656 "Starting Norm", "Restarting PERS", dumpPackage); 10657 } 10658 10659 if (mRemovedProcesses.size() > 0) { 10660 if (needSep) pw.println(); 10661 needSep = true; 10662 printedAnything = true; 10663 pw.println(" Processes that are being removed:"); 10664 dumpProcessList(pw, this, mRemovedProcesses, " ", 10665 "Removed Norm", "Removed PERS", dumpPackage); 10666 } 10667 10668 if (mProcessesOnHold.size() > 0) { 10669 if (needSep) pw.println(); 10670 needSep = true; 10671 printedAnything = true; 10672 pw.println(" Processes that are on old until the system is ready:"); 10673 dumpProcessList(pw, this, mProcessesOnHold, " ", 10674 "OnHold Norm", "OnHold PERS", dumpPackage); 10675 } 10676 10677 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10678 10679 if (mProcessCrashTimes.getMap().size() > 0) { 10680 boolean printed = false; 10681 long now = SystemClock.uptimeMillis(); 10682 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10683 final int NP = pmap.size(); 10684 for (int ip=0; ip<NP; ip++) { 10685 String pname = pmap.keyAt(ip); 10686 SparseArray<Long> uids = pmap.valueAt(ip); 10687 final int N = uids.size(); 10688 for (int i=0; i<N; i++) { 10689 int puid = uids.keyAt(i); 10690 ProcessRecord r = mProcessNames.get(pname, puid); 10691 if (dumpPackage != null && (r == null 10692 || !r.pkgList.containsKey(dumpPackage))) { 10693 continue; 10694 } 10695 if (!printed) { 10696 if (needSep) pw.println(); 10697 needSep = true; 10698 pw.println(" Time since processes crashed:"); 10699 printed = true; 10700 printedAnything = true; 10701 } 10702 pw.print(" Process "); pw.print(pname); 10703 pw.print(" uid "); pw.print(puid); 10704 pw.print(": last crashed "); 10705 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10706 pw.println(" ago"); 10707 } 10708 } 10709 } 10710 10711 if (mBadProcesses.getMap().size() > 0) { 10712 boolean printed = false; 10713 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10714 final int NP = pmap.size(); 10715 for (int ip=0; ip<NP; ip++) { 10716 String pname = pmap.keyAt(ip); 10717 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10718 final int N = uids.size(); 10719 for (int i=0; i<N; i++) { 10720 int puid = uids.keyAt(i); 10721 ProcessRecord r = mProcessNames.get(pname, puid); 10722 if (dumpPackage != null && (r == null 10723 || !r.pkgList.containsKey(dumpPackage))) { 10724 continue; 10725 } 10726 if (!printed) { 10727 if (needSep) pw.println(); 10728 needSep = true; 10729 pw.println(" Bad processes:"); 10730 printedAnything = true; 10731 } 10732 BadProcessInfo info = uids.valueAt(i); 10733 pw.print(" Bad process "); pw.print(pname); 10734 pw.print(" uid "); pw.print(puid); 10735 pw.print(": crashed at time "); pw.println(info.time); 10736 if (info.shortMsg != null) { 10737 pw.print(" Short msg: "); pw.println(info.shortMsg); 10738 } 10739 if (info.longMsg != null) { 10740 pw.print(" Long msg: "); pw.println(info.longMsg); 10741 } 10742 if (info.stack != null) { 10743 pw.println(" Stack:"); 10744 int lastPos = 0; 10745 for (int pos=0; pos<info.stack.length(); pos++) { 10746 if (info.stack.charAt(pos) == '\n') { 10747 pw.print(" "); 10748 pw.write(info.stack, lastPos, pos-lastPos); 10749 pw.println(); 10750 lastPos = pos+1; 10751 } 10752 } 10753 if (lastPos < info.stack.length()) { 10754 pw.print(" "); 10755 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10756 pw.println(); 10757 } 10758 } 10759 } 10760 } 10761 } 10762 10763 if (dumpPackage == null) { 10764 pw.println(); 10765 needSep = false; 10766 pw.println(" mStartedUsers:"); 10767 for (int i=0; i<mStartedUsers.size(); i++) { 10768 UserStartedState uss = mStartedUsers.valueAt(i); 10769 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10770 pw.print(": "); uss.dump("", pw); 10771 } 10772 pw.print(" mStartedUserArray: ["); 10773 for (int i=0; i<mStartedUserArray.length; i++) { 10774 if (i > 0) pw.print(", "); 10775 pw.print(mStartedUserArray[i]); 10776 } 10777 pw.println("]"); 10778 pw.print(" mUserLru: ["); 10779 for (int i=0; i<mUserLru.size(); i++) { 10780 if (i > 0) pw.print(", "); 10781 pw.print(mUserLru.get(i)); 10782 } 10783 pw.println("]"); 10784 if (dumpAll) { 10785 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10786 } 10787 } 10788 if (mHomeProcess != null && (dumpPackage == null 10789 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10790 if (needSep) { 10791 pw.println(); 10792 needSep = false; 10793 } 10794 pw.println(" mHomeProcess: " + mHomeProcess); 10795 } 10796 if (mPreviousProcess != null && (dumpPackage == null 10797 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 10798 if (needSep) { 10799 pw.println(); 10800 needSep = false; 10801 } 10802 pw.println(" mPreviousProcess: " + mPreviousProcess); 10803 } 10804 if (dumpAll) { 10805 StringBuilder sb = new StringBuilder(128); 10806 sb.append(" mPreviousProcessVisibleTime: "); 10807 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 10808 pw.println(sb); 10809 } 10810 if (mHeavyWeightProcess != null && (dumpPackage == null 10811 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 10812 if (needSep) { 10813 pw.println(); 10814 needSep = false; 10815 } 10816 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10817 } 10818 if (dumpPackage == null) { 10819 pw.println(" mConfiguration: " + mConfiguration); 10820 } 10821 if (dumpAll) { 10822 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 10823 if (mCompatModePackages.getPackages().size() > 0) { 10824 boolean printed = false; 10825 for (Map.Entry<String, Integer> entry 10826 : mCompatModePackages.getPackages().entrySet()) { 10827 String pkg = entry.getKey(); 10828 int mode = entry.getValue(); 10829 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 10830 continue; 10831 } 10832 if (!printed) { 10833 pw.println(" mScreenCompatPackages:"); 10834 printed = true; 10835 } 10836 pw.print(" "); pw.print(pkg); pw.print(": "); 10837 pw.print(mode); pw.println(); 10838 } 10839 } 10840 } 10841 if (dumpPackage == null) { 10842 if (mSleeping || mWentToSleep || mLockScreenShown) { 10843 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 10844 + " mLockScreenShown " + mLockScreenShown); 10845 } 10846 if (mShuttingDown) { 10847 pw.println(" mShuttingDown=" + mShuttingDown); 10848 } 10849 } 10850 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 10851 || mOrigWaitForDebugger) { 10852 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 10853 || dumpPackage.equals(mOrigDebugApp)) { 10854 if (needSep) { 10855 pw.println(); 10856 needSep = false; 10857 } 10858 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 10859 + " mDebugTransient=" + mDebugTransient 10860 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 10861 } 10862 } 10863 if (mOpenGlTraceApp != null) { 10864 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 10865 if (needSep) { 10866 pw.println(); 10867 needSep = false; 10868 } 10869 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 10870 } 10871 } 10872 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 10873 || mProfileFd != null) { 10874 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 10875 if (needSep) { 10876 pw.println(); 10877 needSep = false; 10878 } 10879 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 10880 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 10881 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 10882 + mAutoStopProfiler); 10883 } 10884 } 10885 if (dumpPackage == null) { 10886 if (mAlwaysFinishActivities || mController != null) { 10887 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 10888 + " mController=" + mController); 10889 } 10890 if (dumpAll) { 10891 pw.println(" Total persistent processes: " + numPers); 10892 pw.println(" mProcessesReady=" + mProcessesReady 10893 + " mSystemReady=" + mSystemReady); 10894 pw.println(" mBooting=" + mBooting 10895 + " mBooted=" + mBooted 10896 + " mFactoryTest=" + mFactoryTest); 10897 pw.print(" mLastPowerCheckRealtime="); 10898 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 10899 pw.println(""); 10900 pw.print(" mLastPowerCheckUptime="); 10901 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 10902 pw.println(""); 10903 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 10904 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 10905 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 10906 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 10907 + " (" + mLruProcesses.size() + " total)" 10908 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 10909 + " mNumServiceProcs=" + mNumServiceProcs 10910 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 10911 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 10912 + " mLastMemoryLevel" + mLastMemoryLevel 10913 + " mLastNumProcesses" + mLastNumProcesses); 10914 long now = SystemClock.uptimeMillis(); 10915 pw.print(" mLastIdleTime="); 10916 TimeUtils.formatDuration(now, mLastIdleTime, pw); 10917 pw.print(" mLowRamSinceLastIdle="); 10918 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 10919 pw.println(); 10920 } 10921 } 10922 10923 if (!printedAnything) { 10924 pw.println(" (nothing)"); 10925 } 10926 } 10927 10928 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 10929 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 10930 if (mProcessesToGc.size() > 0) { 10931 boolean printed = false; 10932 long now = SystemClock.uptimeMillis(); 10933 for (int i=0; i<mProcessesToGc.size(); i++) { 10934 ProcessRecord proc = mProcessesToGc.get(i); 10935 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 10936 continue; 10937 } 10938 if (!printed) { 10939 if (needSep) pw.println(); 10940 needSep = true; 10941 pw.println(" Processes that are waiting to GC:"); 10942 printed = true; 10943 } 10944 pw.print(" Process "); pw.println(proc); 10945 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 10946 pw.print(", last gced="); 10947 pw.print(now-proc.lastRequestedGc); 10948 pw.print(" ms ago, last lowMem="); 10949 pw.print(now-proc.lastLowMemory); 10950 pw.println(" ms ago"); 10951 10952 } 10953 } 10954 return needSep; 10955 } 10956 10957 void printOomLevel(PrintWriter pw, String name, int adj) { 10958 pw.print(" "); 10959 if (adj >= 0) { 10960 pw.print(' '); 10961 if (adj < 10) pw.print(' '); 10962 } else { 10963 if (adj > -10) pw.print(' '); 10964 } 10965 pw.print(adj); 10966 pw.print(": "); 10967 pw.print(name); 10968 pw.print(" ("); 10969 pw.print(mProcessList.getMemLevel(adj)/1024); 10970 pw.println(" kB)"); 10971 } 10972 10973 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10974 int opti, boolean dumpAll) { 10975 boolean needSep = false; 10976 10977 if (mLruProcesses.size() > 0) { 10978 if (needSep) pw.println(); 10979 needSep = true; 10980 pw.println(" OOM levels:"); 10981 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 10982 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 10983 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 10984 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 10985 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 10986 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 10987 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 10988 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 10989 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 10990 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 10991 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 10992 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 10993 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 10994 10995 if (needSep) pw.println(); 10996 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 10997 pw.print(" total, non-act at "); 10998 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10999 pw.print(", non-svc at "); 11000 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11001 pw.println("):"); 11002 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11003 needSep = true; 11004 } 11005 11006 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11007 11008 pw.println(); 11009 pw.println(" mHomeProcess: " + mHomeProcess); 11010 pw.println(" mPreviousProcess: " + mPreviousProcess); 11011 if (mHeavyWeightProcess != null) { 11012 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11013 } 11014 11015 return true; 11016 } 11017 11018 /** 11019 * There are three ways to call this: 11020 * - no provider specified: dump all the providers 11021 * - a flattened component name that matched an existing provider was specified as the 11022 * first arg: dump that one provider 11023 * - the first arg isn't the flattened component name of an existing provider: 11024 * dump all providers whose component contains the first arg as a substring 11025 */ 11026 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11027 int opti, boolean dumpAll) { 11028 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11029 } 11030 11031 static class ItemMatcher { 11032 ArrayList<ComponentName> components; 11033 ArrayList<String> strings; 11034 ArrayList<Integer> objects; 11035 boolean all; 11036 11037 ItemMatcher() { 11038 all = true; 11039 } 11040 11041 void build(String name) { 11042 ComponentName componentName = ComponentName.unflattenFromString(name); 11043 if (componentName != null) { 11044 if (components == null) { 11045 components = new ArrayList<ComponentName>(); 11046 } 11047 components.add(componentName); 11048 all = false; 11049 } else { 11050 int objectId = 0; 11051 // Not a '/' separated full component name; maybe an object ID? 11052 try { 11053 objectId = Integer.parseInt(name, 16); 11054 if (objects == null) { 11055 objects = new ArrayList<Integer>(); 11056 } 11057 objects.add(objectId); 11058 all = false; 11059 } catch (RuntimeException e) { 11060 // Not an integer; just do string match. 11061 if (strings == null) { 11062 strings = new ArrayList<String>(); 11063 } 11064 strings.add(name); 11065 all = false; 11066 } 11067 } 11068 } 11069 11070 int build(String[] args, int opti) { 11071 for (; opti<args.length; opti++) { 11072 String name = args[opti]; 11073 if ("--".equals(name)) { 11074 return opti+1; 11075 } 11076 build(name); 11077 } 11078 return opti; 11079 } 11080 11081 boolean match(Object object, ComponentName comp) { 11082 if (all) { 11083 return true; 11084 } 11085 if (components != null) { 11086 for (int i=0; i<components.size(); i++) { 11087 if (components.get(i).equals(comp)) { 11088 return true; 11089 } 11090 } 11091 } 11092 if (objects != null) { 11093 for (int i=0; i<objects.size(); i++) { 11094 if (System.identityHashCode(object) == objects.get(i)) { 11095 return true; 11096 } 11097 } 11098 } 11099 if (strings != null) { 11100 String flat = comp.flattenToString(); 11101 for (int i=0; i<strings.size(); i++) { 11102 if (flat.contains(strings.get(i))) { 11103 return true; 11104 } 11105 } 11106 } 11107 return false; 11108 } 11109 } 11110 11111 /** 11112 * There are three things that cmd can be: 11113 * - a flattened component name that matches an existing activity 11114 * - the cmd arg isn't the flattened component name of an existing activity: 11115 * dump all activity whose component contains the cmd as a substring 11116 * - A hex number of the ActivityRecord object instance. 11117 */ 11118 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11119 int opti, boolean dumpAll) { 11120 ArrayList<ActivityRecord> activities; 11121 11122 synchronized (this) { 11123 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11124 } 11125 11126 if (activities.size() <= 0) { 11127 return false; 11128 } 11129 11130 String[] newArgs = new String[args.length - opti]; 11131 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11132 11133 TaskRecord lastTask = null; 11134 boolean needSep = false; 11135 for (int i=activities.size()-1; i>=0; i--) { 11136 ActivityRecord r = activities.get(i); 11137 if (needSep) { 11138 pw.println(); 11139 } 11140 needSep = true; 11141 synchronized (this) { 11142 if (lastTask != r.task) { 11143 lastTask = r.task; 11144 pw.print("TASK "); pw.print(lastTask.affinity); 11145 pw.print(" id="); pw.println(lastTask.taskId); 11146 if (dumpAll) { 11147 lastTask.dump(pw, " "); 11148 } 11149 } 11150 } 11151 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11152 } 11153 return true; 11154 } 11155 11156 /** 11157 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11158 * there is a thread associated with the activity. 11159 */ 11160 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11161 final ActivityRecord r, String[] args, boolean dumpAll) { 11162 String innerPrefix = prefix + " "; 11163 synchronized (this) { 11164 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11165 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11166 pw.print(" pid="); 11167 if (r.app != null) pw.println(r.app.pid); 11168 else pw.println("(not running)"); 11169 if (dumpAll) { 11170 r.dump(pw, innerPrefix); 11171 } 11172 } 11173 if (r.app != null && r.app.thread != null) { 11174 // flush anything that is already in the PrintWriter since the thread is going 11175 // to write to the file descriptor directly 11176 pw.flush(); 11177 try { 11178 TransferPipe tp = new TransferPipe(); 11179 try { 11180 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11181 r.appToken, innerPrefix, args); 11182 tp.go(fd); 11183 } finally { 11184 tp.kill(); 11185 } 11186 } catch (IOException e) { 11187 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11188 } catch (RemoteException e) { 11189 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11190 } 11191 } 11192 } 11193 11194 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11195 int opti, boolean dumpAll, String dumpPackage) { 11196 boolean needSep = false; 11197 boolean onlyHistory = false; 11198 boolean printedAnything = false; 11199 11200 if ("history".equals(dumpPackage)) { 11201 if (opti < args.length && "-s".equals(args[opti])) { 11202 dumpAll = false; 11203 } 11204 onlyHistory = true; 11205 dumpPackage = null; 11206 } 11207 11208 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11209 if (!onlyHistory && dumpAll) { 11210 if (mRegisteredReceivers.size() > 0) { 11211 boolean printed = false; 11212 Iterator it = mRegisteredReceivers.values().iterator(); 11213 while (it.hasNext()) { 11214 ReceiverList r = (ReceiverList)it.next(); 11215 if (dumpPackage != null && (r.app == null || 11216 !dumpPackage.equals(r.app.info.packageName))) { 11217 continue; 11218 } 11219 if (!printed) { 11220 pw.println(" Registered Receivers:"); 11221 needSep = true; 11222 printed = true; 11223 printedAnything = true; 11224 } 11225 pw.print(" * "); pw.println(r); 11226 r.dump(pw, " "); 11227 } 11228 } 11229 11230 if (mReceiverResolver.dump(pw, needSep ? 11231 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11232 " ", dumpPackage, false)) { 11233 needSep = true; 11234 printedAnything = true; 11235 } 11236 } 11237 11238 for (BroadcastQueue q : mBroadcastQueues) { 11239 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11240 printedAnything |= needSep; 11241 } 11242 11243 needSep = true; 11244 11245 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11246 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11247 if (needSep) { 11248 pw.println(); 11249 } 11250 needSep = true; 11251 printedAnything = true; 11252 pw.print(" Sticky broadcasts for user "); 11253 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11254 StringBuilder sb = new StringBuilder(128); 11255 for (Map.Entry<String, ArrayList<Intent>> ent 11256 : mStickyBroadcasts.valueAt(user).entrySet()) { 11257 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11258 if (dumpAll) { 11259 pw.println(":"); 11260 ArrayList<Intent> intents = ent.getValue(); 11261 final int N = intents.size(); 11262 for (int i=0; i<N; i++) { 11263 sb.setLength(0); 11264 sb.append(" Intent: "); 11265 intents.get(i).toShortString(sb, false, true, false, false); 11266 pw.println(sb.toString()); 11267 Bundle bundle = intents.get(i).getExtras(); 11268 if (bundle != null) { 11269 pw.print(" "); 11270 pw.println(bundle.toString()); 11271 } 11272 } 11273 } else { 11274 pw.println(""); 11275 } 11276 } 11277 } 11278 } 11279 11280 if (!onlyHistory && dumpAll) { 11281 pw.println(); 11282 for (BroadcastQueue queue : mBroadcastQueues) { 11283 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11284 + queue.mBroadcastsScheduled); 11285 } 11286 pw.println(" mHandler:"); 11287 mHandler.dump(new PrintWriterPrinter(pw), " "); 11288 needSep = true; 11289 printedAnything = true; 11290 } 11291 11292 if (!printedAnything) { 11293 pw.println(" (nothing)"); 11294 } 11295 } 11296 11297 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11298 int opti, boolean dumpAll, String dumpPackage) { 11299 boolean needSep; 11300 boolean printedAnything = false; 11301 11302 ItemMatcher matcher = new ItemMatcher(); 11303 matcher.build(args, opti); 11304 11305 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11306 11307 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11308 printedAnything |= needSep; 11309 11310 if (mLaunchingProviders.size() > 0) { 11311 boolean printed = false; 11312 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11313 ContentProviderRecord r = mLaunchingProviders.get(i); 11314 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11315 continue; 11316 } 11317 if (!printed) { 11318 if (needSep) pw.println(); 11319 needSep = true; 11320 pw.println(" Launching content providers:"); 11321 printed = true; 11322 printedAnything = true; 11323 } 11324 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11325 pw.println(r); 11326 } 11327 } 11328 11329 if (mGrantedUriPermissions.size() > 0) { 11330 boolean printed = false; 11331 int dumpUid = -2; 11332 if (dumpPackage != null) { 11333 try { 11334 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11335 } catch (NameNotFoundException e) { 11336 dumpUid = -1; 11337 } 11338 } 11339 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11340 int uid = mGrantedUriPermissions.keyAt(i); 11341 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11342 continue; 11343 } 11344 ArrayMap<Uri, UriPermission> perms 11345 = mGrantedUriPermissions.valueAt(i); 11346 if (!printed) { 11347 if (needSep) pw.println(); 11348 needSep = true; 11349 pw.println(" Granted Uri Permissions:"); 11350 printed = true; 11351 printedAnything = true; 11352 } 11353 pw.print(" * UID "); pw.print(uid); 11354 pw.println(" holds:"); 11355 for (UriPermission perm : perms.values()) { 11356 pw.print(" "); pw.println(perm); 11357 if (dumpAll) { 11358 perm.dump(pw, " "); 11359 } 11360 } 11361 } 11362 } 11363 11364 if (!printedAnything) { 11365 pw.println(" (nothing)"); 11366 } 11367 } 11368 11369 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11370 int opti, boolean dumpAll, String dumpPackage) { 11371 boolean printed = false; 11372 11373 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11374 11375 if (mIntentSenderRecords.size() > 0) { 11376 Iterator<WeakReference<PendingIntentRecord>> it 11377 = mIntentSenderRecords.values().iterator(); 11378 while (it.hasNext()) { 11379 WeakReference<PendingIntentRecord> ref = it.next(); 11380 PendingIntentRecord rec = ref != null ? ref.get(): null; 11381 if (dumpPackage != null && (rec == null 11382 || !dumpPackage.equals(rec.key.packageName))) { 11383 continue; 11384 } 11385 printed = true; 11386 if (rec != null) { 11387 pw.print(" * "); pw.println(rec); 11388 if (dumpAll) { 11389 rec.dump(pw, " "); 11390 } 11391 } else { 11392 pw.print(" * "); pw.println(ref); 11393 } 11394 } 11395 } 11396 11397 if (!printed) { 11398 pw.println(" (nothing)"); 11399 } 11400 } 11401 11402 private static final int dumpProcessList(PrintWriter pw, 11403 ActivityManagerService service, List list, 11404 String prefix, String normalLabel, String persistentLabel, 11405 String dumpPackage) { 11406 int numPers = 0; 11407 final int N = list.size()-1; 11408 for (int i=N; i>=0; i--) { 11409 ProcessRecord r = (ProcessRecord)list.get(i); 11410 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11411 continue; 11412 } 11413 pw.println(String.format("%s%s #%2d: %s", 11414 prefix, (r.persistent ? persistentLabel : normalLabel), 11415 i, r.toString())); 11416 if (r.persistent) { 11417 numPers++; 11418 } 11419 } 11420 return numPers; 11421 } 11422 11423 private static final boolean dumpProcessOomList(PrintWriter pw, 11424 ActivityManagerService service, List<ProcessRecord> origList, 11425 String prefix, String normalLabel, String persistentLabel, 11426 boolean inclDetails, String dumpPackage) { 11427 11428 ArrayList<Pair<ProcessRecord, Integer>> list 11429 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11430 for (int i=0; i<origList.size(); i++) { 11431 ProcessRecord r = origList.get(i); 11432 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11433 continue; 11434 } 11435 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11436 } 11437 11438 if (list.size() <= 0) { 11439 return false; 11440 } 11441 11442 Comparator<Pair<ProcessRecord, Integer>> comparator 11443 = new Comparator<Pair<ProcessRecord, Integer>>() { 11444 @Override 11445 public int compare(Pair<ProcessRecord, Integer> object1, 11446 Pair<ProcessRecord, Integer> object2) { 11447 if (object1.first.setAdj != object2.first.setAdj) { 11448 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11449 } 11450 if (object1.second.intValue() != object2.second.intValue()) { 11451 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11452 } 11453 return 0; 11454 } 11455 }; 11456 11457 Collections.sort(list, comparator); 11458 11459 final long curRealtime = SystemClock.elapsedRealtime(); 11460 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11461 final long curUptime = SystemClock.uptimeMillis(); 11462 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11463 11464 for (int i=list.size()-1; i>=0; i--) { 11465 ProcessRecord r = list.get(i).first; 11466 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11467 char schedGroup; 11468 switch (r.setSchedGroup) { 11469 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11470 schedGroup = 'B'; 11471 break; 11472 case Process.THREAD_GROUP_DEFAULT: 11473 schedGroup = 'F'; 11474 break; 11475 default: 11476 schedGroup = '?'; 11477 break; 11478 } 11479 char foreground; 11480 if (r.foregroundActivities) { 11481 foreground = 'A'; 11482 } else if (r.foregroundServices) { 11483 foreground = 'S'; 11484 } else { 11485 foreground = ' '; 11486 } 11487 String procState = ProcessList.makeProcStateString(r.curProcState); 11488 pw.print(prefix); 11489 pw.print(r.persistent ? persistentLabel : normalLabel); 11490 pw.print(" #"); 11491 int num = (origList.size()-1)-list.get(i).second; 11492 if (num < 10) pw.print(' '); 11493 pw.print(num); 11494 pw.print(": "); 11495 pw.print(oomAdj); 11496 pw.print(' '); 11497 pw.print(schedGroup); 11498 pw.print('/'); 11499 pw.print(foreground); 11500 pw.print('/'); 11501 pw.print(procState); 11502 pw.print(" trm:"); 11503 if (r.trimMemoryLevel < 10) pw.print(' '); 11504 pw.print(r.trimMemoryLevel); 11505 pw.print(' '); 11506 pw.print(r.toShortString()); 11507 pw.print(" ("); 11508 pw.print(r.adjType); 11509 pw.println(')'); 11510 if (r.adjSource != null || r.adjTarget != null) { 11511 pw.print(prefix); 11512 pw.print(" "); 11513 if (r.adjTarget instanceof ComponentName) { 11514 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11515 } else if (r.adjTarget != null) { 11516 pw.print(r.adjTarget.toString()); 11517 } else { 11518 pw.print("{null}"); 11519 } 11520 pw.print("<="); 11521 if (r.adjSource instanceof ProcessRecord) { 11522 pw.print("Proc{"); 11523 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11524 pw.println("}"); 11525 } else if (r.adjSource != null) { 11526 pw.println(r.adjSource.toString()); 11527 } else { 11528 pw.println("{null}"); 11529 } 11530 } 11531 if (inclDetails) { 11532 pw.print(prefix); 11533 pw.print(" "); 11534 pw.print("oom: max="); pw.print(r.maxAdj); 11535 pw.print(" curRaw="); pw.print(r.curRawAdj); 11536 pw.print(" setRaw="); pw.print(r.setRawAdj); 11537 pw.print(" cur="); pw.print(r.curAdj); 11538 pw.print(" set="); pw.println(r.setAdj); 11539 pw.print(prefix); 11540 pw.print(" "); 11541 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11542 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11543 pw.print(" lastPss="); pw.print(r.lastPss); 11544 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11545 pw.print(prefix); 11546 pw.print(" "); 11547 pw.print("keeping="); pw.print(r.keeping); 11548 pw.print(" cached="); pw.print(r.cached); 11549 pw.print(" empty="); pw.print(r.empty); 11550 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11551 11552 if (!r.keeping) { 11553 if (r.lastWakeTime != 0) { 11554 long wtime; 11555 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11556 synchronized (stats) { 11557 wtime = stats.getProcessWakeTime(r.info.uid, 11558 r.pid, curRealtime); 11559 } 11560 long timeUsed = wtime - r.lastWakeTime; 11561 pw.print(prefix); 11562 pw.print(" "); 11563 pw.print("keep awake over "); 11564 TimeUtils.formatDuration(realtimeSince, pw); 11565 pw.print(" used "); 11566 TimeUtils.formatDuration(timeUsed, pw); 11567 pw.print(" ("); 11568 pw.print((timeUsed*100)/realtimeSince); 11569 pw.println("%)"); 11570 } 11571 if (r.lastCpuTime != 0) { 11572 long timeUsed = r.curCpuTime - r.lastCpuTime; 11573 pw.print(prefix); 11574 pw.print(" "); 11575 pw.print("run cpu over "); 11576 TimeUtils.formatDuration(uptimeSince, pw); 11577 pw.print(" used "); 11578 TimeUtils.formatDuration(timeUsed, pw); 11579 pw.print(" ("); 11580 pw.print((timeUsed*100)/uptimeSince); 11581 pw.println("%)"); 11582 } 11583 } 11584 } 11585 } 11586 return true; 11587 } 11588 11589 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11590 ArrayList<ProcessRecord> procs; 11591 synchronized (this) { 11592 if (args != null && args.length > start 11593 && args[start].charAt(0) != '-') { 11594 procs = new ArrayList<ProcessRecord>(); 11595 int pid = -1; 11596 try { 11597 pid = Integer.parseInt(args[start]); 11598 } catch (NumberFormatException e) { 11599 } 11600 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11601 ProcessRecord proc = mLruProcesses.get(i); 11602 if (proc.pid == pid) { 11603 procs.add(proc); 11604 } else if (proc.processName.equals(args[start])) { 11605 procs.add(proc); 11606 } 11607 } 11608 if (procs.size() <= 0) { 11609 return null; 11610 } 11611 } else { 11612 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11613 } 11614 } 11615 return procs; 11616 } 11617 11618 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11619 PrintWriter pw, String[] args) { 11620 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11621 if (procs == null) { 11622 pw.println("No process found for: " + args[0]); 11623 return; 11624 } 11625 11626 long uptime = SystemClock.uptimeMillis(); 11627 long realtime = SystemClock.elapsedRealtime(); 11628 pw.println("Applications Graphics Acceleration Info:"); 11629 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11630 11631 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11632 ProcessRecord r = procs.get(i); 11633 if (r.thread != null) { 11634 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11635 pw.flush(); 11636 try { 11637 TransferPipe tp = new TransferPipe(); 11638 try { 11639 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11640 tp.go(fd); 11641 } finally { 11642 tp.kill(); 11643 } 11644 } catch (IOException e) { 11645 pw.println("Failure while dumping the app: " + r); 11646 pw.flush(); 11647 } catch (RemoteException e) { 11648 pw.println("Got a RemoteException while dumping the app " + r); 11649 pw.flush(); 11650 } 11651 } 11652 } 11653 } 11654 11655 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11656 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11657 if (procs == null) { 11658 pw.println("No process found for: " + args[0]); 11659 return; 11660 } 11661 11662 pw.println("Applications Database Info:"); 11663 11664 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11665 ProcessRecord r = procs.get(i); 11666 if (r.thread != null) { 11667 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11668 pw.flush(); 11669 try { 11670 TransferPipe tp = new TransferPipe(); 11671 try { 11672 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11673 tp.go(fd); 11674 } finally { 11675 tp.kill(); 11676 } 11677 } catch (IOException e) { 11678 pw.println("Failure while dumping the app: " + r); 11679 pw.flush(); 11680 } catch (RemoteException e) { 11681 pw.println("Got a RemoteException while dumping the app " + r); 11682 pw.flush(); 11683 } 11684 } 11685 } 11686 } 11687 11688 final static class MemItem { 11689 final boolean isProc; 11690 final String label; 11691 final String shortLabel; 11692 final long pss; 11693 final int id; 11694 final boolean hasActivities; 11695 ArrayList<MemItem> subitems; 11696 11697 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11698 boolean _hasActivities) { 11699 isProc = true; 11700 label = _label; 11701 shortLabel = _shortLabel; 11702 pss = _pss; 11703 id = _id; 11704 hasActivities = _hasActivities; 11705 } 11706 11707 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11708 isProc = false; 11709 label = _label; 11710 shortLabel = _shortLabel; 11711 pss = _pss; 11712 id = _id; 11713 hasActivities = false; 11714 } 11715 } 11716 11717 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11718 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11719 if (sort && !isCompact) { 11720 Collections.sort(items, new Comparator<MemItem>() { 11721 @Override 11722 public int compare(MemItem lhs, MemItem rhs) { 11723 if (lhs.pss < rhs.pss) { 11724 return 1; 11725 } else if (lhs.pss > rhs.pss) { 11726 return -1; 11727 } 11728 return 0; 11729 } 11730 }); 11731 } 11732 11733 for (int i=0; i<items.size(); i++) { 11734 MemItem mi = items.get(i); 11735 if (!isCompact) { 11736 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11737 } else if (mi.isProc) { 11738 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11739 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11740 pw.println(mi.hasActivities ? ",a" : ",e"); 11741 } else { 11742 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11743 pw.println(mi.pss); 11744 } 11745 if (mi.subitems != null) { 11746 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11747 true, isCompact); 11748 } 11749 } 11750 } 11751 11752 // These are in KB. 11753 static final long[] DUMP_MEM_BUCKETS = new long[] { 11754 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11755 120*1024, 160*1024, 200*1024, 11756 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11757 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11758 }; 11759 11760 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11761 boolean stackLike) { 11762 int start = label.lastIndexOf('.'); 11763 if (start >= 0) start++; 11764 else start = 0; 11765 int end = label.length(); 11766 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11767 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11768 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11769 out.append(bucket); 11770 out.append(stackLike ? "MB." : "MB "); 11771 out.append(label, start, end); 11772 return; 11773 } 11774 } 11775 out.append(memKB/1024); 11776 out.append(stackLike ? "MB." : "MB "); 11777 out.append(label, start, end); 11778 } 11779 11780 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11781 ProcessList.NATIVE_ADJ, 11782 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11783 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11784 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11785 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11786 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11787 }; 11788 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11789 "Native", 11790 "System", "Persistent", "Foreground", 11791 "Visible", "Perceptible", 11792 "Heavy Weight", "Backup", 11793 "A Services", "Home", 11794 "Previous", "B Services", "Cached" 11795 }; 11796 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 11797 "native", 11798 "sys", "pers", "fore", 11799 "vis", "percept", 11800 "heavy", "backup", 11801 "servicea", "home", 11802 "prev", "serviceb", "cached" 11803 }; 11804 11805 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 11806 long realtime, boolean isCheckinRequest, boolean isCompact) { 11807 if (isCheckinRequest || isCompact) { 11808 // short checkin version 11809 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 11810 } else { 11811 pw.println("Applications Memory Usage (kB):"); 11812 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11813 } 11814 } 11815 11816 final void dumpApplicationMemoryUsage(FileDescriptor fd, 11817 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 11818 boolean dumpDetails = false; 11819 boolean dumpFullDetails = false; 11820 boolean dumpDalvik = false; 11821 boolean oomOnly = false; 11822 boolean isCompact = false; 11823 boolean localOnly = false; 11824 11825 int opti = 0; 11826 while (opti < args.length) { 11827 String opt = args[opti]; 11828 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11829 break; 11830 } 11831 opti++; 11832 if ("-a".equals(opt)) { 11833 dumpDetails = true; 11834 dumpFullDetails = true; 11835 dumpDalvik = true; 11836 } else if ("-d".equals(opt)) { 11837 dumpDalvik = true; 11838 } else if ("-c".equals(opt)) { 11839 isCompact = true; 11840 } else if ("--oom".equals(opt)) { 11841 oomOnly = true; 11842 } else if ("--local".equals(opt)) { 11843 localOnly = true; 11844 } else if ("-h".equals(opt)) { 11845 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 11846 pw.println(" -a: include all available information for each process."); 11847 pw.println(" -d: include dalvik details when dumping process details."); 11848 pw.println(" -c: dump in a compact machine-parseable representation."); 11849 pw.println(" --oom: only show processes organized by oom adj."); 11850 pw.println(" --local: only collect details locally, don't call process."); 11851 pw.println("If [process] is specified it can be the name or "); 11852 pw.println("pid of a specific process to dump."); 11853 return; 11854 } else { 11855 pw.println("Unknown argument: " + opt + "; use -h for help"); 11856 } 11857 } 11858 11859 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 11860 long uptime = SystemClock.uptimeMillis(); 11861 long realtime = SystemClock.elapsedRealtime(); 11862 final long[] tmpLong = new long[1]; 11863 11864 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 11865 if (procs == null) { 11866 // No Java processes. Maybe they want to print a native process. 11867 if (args != null && args.length > opti 11868 && args[opti].charAt(0) != '-') { 11869 ArrayList<ProcessCpuTracker.Stats> nativeProcs 11870 = new ArrayList<ProcessCpuTracker.Stats>(); 11871 updateCpuStatsNow(); 11872 int findPid = -1; 11873 try { 11874 findPid = Integer.parseInt(args[opti]); 11875 } catch (NumberFormatException e) { 11876 } 11877 synchronized (mProcessCpuThread) { 11878 final int N = mProcessCpuTracker.countStats(); 11879 for (int i=0; i<N; i++) { 11880 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 11881 if (st.pid == findPid || (st.baseName != null 11882 && st.baseName.equals(args[opti]))) { 11883 nativeProcs.add(st); 11884 } 11885 } 11886 } 11887 if (nativeProcs.size() > 0) { 11888 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 11889 isCompact); 11890 Debug.MemoryInfo mi = null; 11891 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 11892 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 11893 final int pid = r.pid; 11894 if (!isCheckinRequest && dumpDetails) { 11895 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 11896 } 11897 if (mi == null) { 11898 mi = new Debug.MemoryInfo(); 11899 } 11900 if (dumpDetails || (!brief && !oomOnly)) { 11901 Debug.getMemoryInfo(pid, mi); 11902 } else { 11903 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11904 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11905 } 11906 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11907 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 11908 if (isCheckinRequest) { 11909 pw.println(); 11910 } 11911 } 11912 return; 11913 } 11914 } 11915 pw.println("No process found for: " + args[opti]); 11916 return; 11917 } 11918 11919 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 11920 dumpDetails = true; 11921 } 11922 11923 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 11924 11925 String[] innerArgs = new String[args.length-opti]; 11926 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 11927 11928 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 11929 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 11930 long nativePss=0, dalvikPss=0, otherPss=0; 11931 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 11932 11933 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 11934 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 11935 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 11936 11937 long totalPss = 0; 11938 long cachedPss = 0; 11939 11940 Debug.MemoryInfo mi = null; 11941 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11942 final ProcessRecord r = procs.get(i); 11943 final IApplicationThread thread; 11944 final int pid; 11945 final int oomAdj; 11946 final boolean hasActivities; 11947 synchronized (this) { 11948 thread = r.thread; 11949 pid = r.pid; 11950 oomAdj = r.getSetAdjWithServices(); 11951 hasActivities = r.activities.size() > 0; 11952 } 11953 if (thread != null) { 11954 if (!isCheckinRequest && dumpDetails) { 11955 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 11956 } 11957 if (mi == null) { 11958 mi = new Debug.MemoryInfo(); 11959 } 11960 if (dumpDetails || (!brief && !oomOnly)) { 11961 Debug.getMemoryInfo(pid, mi); 11962 } else { 11963 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11964 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11965 } 11966 if (dumpDetails) { 11967 if (localOnly) { 11968 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11969 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 11970 if (isCheckinRequest) { 11971 pw.println(); 11972 } 11973 } else { 11974 try { 11975 pw.flush(); 11976 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 11977 dumpDalvik, innerArgs); 11978 } catch (RemoteException e) { 11979 if (!isCheckinRequest) { 11980 pw.println("Got RemoteException!"); 11981 pw.flush(); 11982 } 11983 } 11984 } 11985 } 11986 11987 final long myTotalPss = mi.getTotalPss(); 11988 final long myTotalUss = mi.getTotalUss(); 11989 11990 synchronized (this) { 11991 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 11992 // Record this for posterity if the process has been stable. 11993 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 11994 } 11995 } 11996 11997 if (!isCheckinRequest && mi != null) { 11998 totalPss += myTotalPss; 11999 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12000 (hasActivities ? " / activities)" : ")"), 12001 r.processName, myTotalPss, pid, hasActivities); 12002 procMems.add(pssItem); 12003 procMemsMap.put(pid, pssItem); 12004 12005 nativePss += mi.nativePss; 12006 dalvikPss += mi.dalvikPss; 12007 otherPss += mi.otherPss; 12008 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12009 long mem = mi.getOtherPss(j); 12010 miscPss[j] += mem; 12011 otherPss -= mem; 12012 } 12013 12014 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12015 cachedPss += myTotalPss; 12016 } 12017 12018 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12019 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12020 || oomIndex == (oomPss.length-1)) { 12021 oomPss[oomIndex] += myTotalPss; 12022 if (oomProcs[oomIndex] == null) { 12023 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12024 } 12025 oomProcs[oomIndex].add(pssItem); 12026 break; 12027 } 12028 } 12029 } 12030 } 12031 } 12032 12033 if (!isCheckinRequest && procs.size() > 1) { 12034 // If we are showing aggregations, also look for native processes to 12035 // include so that our aggregations are more accurate. 12036 updateCpuStatsNow(); 12037 synchronized (mProcessCpuThread) { 12038 final int N = mProcessCpuTracker.countStats(); 12039 for (int i=0; i<N; i++) { 12040 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12041 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12042 if (mi == null) { 12043 mi = new Debug.MemoryInfo(); 12044 } 12045 if (!brief && !oomOnly) { 12046 Debug.getMemoryInfo(st.pid, mi); 12047 } else { 12048 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12049 mi.nativePrivateDirty = (int)tmpLong[0]; 12050 } 12051 12052 final long myTotalPss = mi.getTotalPss(); 12053 totalPss += myTotalPss; 12054 12055 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12056 st.name, myTotalPss, st.pid, false); 12057 procMems.add(pssItem); 12058 12059 nativePss += mi.nativePss; 12060 dalvikPss += mi.dalvikPss; 12061 otherPss += mi.otherPss; 12062 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12063 long mem = mi.getOtherPss(j); 12064 miscPss[j] += mem; 12065 otherPss -= mem; 12066 } 12067 oomPss[0] += myTotalPss; 12068 if (oomProcs[0] == null) { 12069 oomProcs[0] = new ArrayList<MemItem>(); 12070 } 12071 oomProcs[0].add(pssItem); 12072 } 12073 } 12074 } 12075 12076 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12077 12078 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12079 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12080 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12081 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12082 String label = Debug.MemoryInfo.getOtherLabel(j); 12083 catMems.add(new MemItem(label, label, miscPss[j], j)); 12084 } 12085 12086 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12087 for (int j=0; j<oomPss.length; j++) { 12088 if (oomPss[j] != 0) { 12089 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12090 : DUMP_MEM_OOM_LABEL[j]; 12091 MemItem item = new MemItem(label, label, oomPss[j], 12092 DUMP_MEM_OOM_ADJ[j]); 12093 item.subitems = oomProcs[j]; 12094 oomMems.add(item); 12095 } 12096 } 12097 12098 if (!brief && !oomOnly && !isCompact) { 12099 pw.println(); 12100 pw.println("Total PSS by process:"); 12101 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12102 pw.println(); 12103 } 12104 if (!isCompact) { 12105 pw.println("Total PSS by OOM adjustment:"); 12106 } 12107 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12108 if (!brief && !oomOnly) { 12109 PrintWriter out = categoryPw != null ? categoryPw : pw; 12110 if (!isCompact) { 12111 out.println(); 12112 out.println("Total PSS by category:"); 12113 } 12114 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12115 } 12116 if (!isCompact) { 12117 pw.println(); 12118 } 12119 MemInfoReader memInfo = new MemInfoReader(); 12120 memInfo.readMemInfo(); 12121 if (!brief) { 12122 if (!isCompact) { 12123 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12124 pw.println(" kB"); 12125 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12126 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12127 pw.print(cachedPss); pw.print(" cached pss + "); 12128 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12129 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12130 } else { 12131 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12132 pw.print(cachedPss + memInfo.getCachedSizeKb() 12133 + memInfo.getFreeSizeKb()); pw.print(","); 12134 pw.println(totalPss - cachedPss); 12135 } 12136 } 12137 if (!isCompact) { 12138 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12139 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12140 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12141 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12142 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12143 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12144 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12145 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12146 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12147 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12148 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12149 } 12150 if (!brief) { 12151 if (memInfo.getZramTotalSizeKb() != 0) { 12152 if (!isCompact) { 12153 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12154 pw.print(" kB physical used for "); 12155 pw.print(memInfo.getSwapTotalSizeKb() 12156 - memInfo.getSwapFreeSizeKb()); 12157 pw.print(" kB in swap ("); 12158 pw.print(memInfo.getSwapTotalSizeKb()); 12159 pw.println(" kB total swap)"); 12160 } else { 12161 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12162 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12163 pw.println(memInfo.getSwapFreeSizeKb()); 12164 } 12165 } 12166 final int[] SINGLE_LONG_FORMAT = new int[] { 12167 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12168 }; 12169 long[] longOut = new long[1]; 12170 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12171 SINGLE_LONG_FORMAT, null, longOut, null); 12172 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12173 longOut[0] = 0; 12174 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12175 SINGLE_LONG_FORMAT, null, longOut, null); 12176 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12177 longOut[0] = 0; 12178 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12179 SINGLE_LONG_FORMAT, null, longOut, null); 12180 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12181 longOut[0] = 0; 12182 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12183 SINGLE_LONG_FORMAT, null, longOut, null); 12184 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12185 if (!isCompact) { 12186 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12187 pw.print(" KSM: "); pw.print(sharing); 12188 pw.print(" kB saved from shared "); 12189 pw.print(shared); pw.println(" kB"); 12190 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12191 pw.print(voltile); pw.println(" kB volatile"); 12192 } 12193 pw.print(" Tuning: "); 12194 pw.print(ActivityManager.staticGetMemoryClass()); 12195 pw.print(" (large "); 12196 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12197 pw.print("), oom "); 12198 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12199 pw.print(" kB"); 12200 pw.print(", restore limit "); 12201 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12202 pw.print(" kB"); 12203 if (ActivityManager.isLowRamDeviceStatic()) { 12204 pw.print(" (low-ram)"); 12205 } 12206 if (ActivityManager.isHighEndGfx()) { 12207 pw.print(" (high-end-gfx)"); 12208 } 12209 pw.println(); 12210 } else { 12211 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12212 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12213 pw.println(voltile); 12214 pw.print("tuning,"); 12215 pw.print(ActivityManager.staticGetMemoryClass()); 12216 pw.print(','); 12217 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12218 pw.print(','); 12219 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12220 if (ActivityManager.isLowRamDeviceStatic()) { 12221 pw.print(",low-ram"); 12222 } 12223 if (ActivityManager.isHighEndGfx()) { 12224 pw.print(",high-end-gfx"); 12225 } 12226 pw.println(); 12227 } 12228 } 12229 } 12230 } 12231 12232 /** 12233 * Searches array of arguments for the specified string 12234 * @param args array of argument strings 12235 * @param value value to search for 12236 * @return true if the value is contained in the array 12237 */ 12238 private static boolean scanArgs(String[] args, String value) { 12239 if (args != null) { 12240 for (String arg : args) { 12241 if (value.equals(arg)) { 12242 return true; 12243 } 12244 } 12245 } 12246 return false; 12247 } 12248 12249 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12250 ContentProviderRecord cpr, boolean always) { 12251 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12252 12253 if (!inLaunching || always) { 12254 synchronized (cpr) { 12255 cpr.launchingApp = null; 12256 cpr.notifyAll(); 12257 } 12258 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12259 String names[] = cpr.info.authority.split(";"); 12260 for (int j = 0; j < names.length; j++) { 12261 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12262 } 12263 } 12264 12265 for (int i=0; i<cpr.connections.size(); i++) { 12266 ContentProviderConnection conn = cpr.connections.get(i); 12267 if (conn.waiting) { 12268 // If this connection is waiting for the provider, then we don't 12269 // need to mess with its process unless we are always removing 12270 // or for some reason the provider is not currently launching. 12271 if (inLaunching && !always) { 12272 continue; 12273 } 12274 } 12275 ProcessRecord capp = conn.client; 12276 conn.dead = true; 12277 if (conn.stableCount > 0) { 12278 if (!capp.persistent && capp.thread != null 12279 && capp.pid != 0 12280 && capp.pid != MY_PID) { 12281 killUnneededProcessLocked(capp, "depends on provider " 12282 + cpr.name.flattenToShortString() 12283 + " in dying proc " + (proc != null ? proc.processName : "??")); 12284 } 12285 } else if (capp.thread != null && conn.provider.provider != null) { 12286 try { 12287 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12288 } catch (RemoteException e) { 12289 } 12290 // In the protocol here, we don't expect the client to correctly 12291 // clean up this connection, we'll just remove it. 12292 cpr.connections.remove(i); 12293 conn.client.conProviders.remove(conn); 12294 } 12295 } 12296 12297 if (inLaunching && always) { 12298 mLaunchingProviders.remove(cpr); 12299 } 12300 return inLaunching; 12301 } 12302 12303 /** 12304 * Main code for cleaning up a process when it has gone away. This is 12305 * called both as a result of the process dying, or directly when stopping 12306 * a process when running in single process mode. 12307 */ 12308 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12309 boolean restarting, boolean allowRestart, int index) { 12310 if (index >= 0) { 12311 removeLruProcessLocked(app); 12312 ProcessList.remove(app.pid); 12313 } 12314 12315 mProcessesToGc.remove(app); 12316 mPendingPssProcesses.remove(app); 12317 12318 // Dismiss any open dialogs. 12319 if (app.crashDialog != null && !app.forceCrashReport) { 12320 app.crashDialog.dismiss(); 12321 app.crashDialog = null; 12322 } 12323 if (app.anrDialog != null) { 12324 app.anrDialog.dismiss(); 12325 app.anrDialog = null; 12326 } 12327 if (app.waitDialog != null) { 12328 app.waitDialog.dismiss(); 12329 app.waitDialog = null; 12330 } 12331 12332 app.crashing = false; 12333 app.notResponding = false; 12334 12335 app.resetPackageList(mProcessStats); 12336 app.unlinkDeathRecipient(); 12337 app.makeInactive(mProcessStats); 12338 app.forcingToForeground = null; 12339 app.foregroundServices = false; 12340 app.foregroundActivities = false; 12341 app.hasShownUi = false; 12342 app.hasAboveClient = false; 12343 app.hasClientActivities = false; 12344 12345 mServices.killServicesLocked(app, allowRestart); 12346 12347 boolean restart = false; 12348 12349 // Remove published content providers. 12350 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12351 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12352 final boolean always = app.bad || !allowRestart; 12353 if (removeDyingProviderLocked(app, cpr, always) || always) { 12354 // We left the provider in the launching list, need to 12355 // restart it. 12356 restart = true; 12357 } 12358 12359 cpr.provider = null; 12360 cpr.proc = null; 12361 } 12362 app.pubProviders.clear(); 12363 12364 // Take care of any launching providers waiting for this process. 12365 if (checkAppInLaunchingProvidersLocked(app, false)) { 12366 restart = true; 12367 } 12368 12369 // Unregister from connected content providers. 12370 if (!app.conProviders.isEmpty()) { 12371 for (int i=0; i<app.conProviders.size(); i++) { 12372 ContentProviderConnection conn = app.conProviders.get(i); 12373 conn.provider.connections.remove(conn); 12374 } 12375 app.conProviders.clear(); 12376 } 12377 12378 // At this point there may be remaining entries in mLaunchingProviders 12379 // where we were the only one waiting, so they are no longer of use. 12380 // Look for these and clean up if found. 12381 // XXX Commented out for now. Trying to figure out a way to reproduce 12382 // the actual situation to identify what is actually going on. 12383 if (false) { 12384 for (int i=0; i<mLaunchingProviders.size(); i++) { 12385 ContentProviderRecord cpr = (ContentProviderRecord) 12386 mLaunchingProviders.get(i); 12387 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12388 synchronized (cpr) { 12389 cpr.launchingApp = null; 12390 cpr.notifyAll(); 12391 } 12392 } 12393 } 12394 } 12395 12396 skipCurrentReceiverLocked(app); 12397 12398 // Unregister any receivers. 12399 for (int i=app.receivers.size()-1; i>=0; i--) { 12400 removeReceiverLocked(app.receivers.valueAt(i)); 12401 } 12402 app.receivers.clear(); 12403 12404 // If the app is undergoing backup, tell the backup manager about it 12405 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12406 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12407 + mBackupTarget.appInfo + " died during backup"); 12408 try { 12409 IBackupManager bm = IBackupManager.Stub.asInterface( 12410 ServiceManager.getService(Context.BACKUP_SERVICE)); 12411 bm.agentDisconnected(app.info.packageName); 12412 } catch (RemoteException e) { 12413 // can't happen; backup manager is local 12414 } 12415 } 12416 12417 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12418 ProcessChangeItem item = mPendingProcessChanges.get(i); 12419 if (item.pid == app.pid) { 12420 mPendingProcessChanges.remove(i); 12421 mAvailProcessChanges.add(item); 12422 } 12423 } 12424 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12425 12426 // If the caller is restarting this app, then leave it in its 12427 // current lists and let the caller take care of it. 12428 if (restarting) { 12429 return; 12430 } 12431 12432 if (!app.persistent || app.isolated) { 12433 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12434 "Removing non-persistent process during cleanup: " + app); 12435 mProcessNames.remove(app.processName, app.uid); 12436 mIsolatedProcesses.remove(app.uid); 12437 if (mHeavyWeightProcess == app) { 12438 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12439 mHeavyWeightProcess.userId, 0)); 12440 mHeavyWeightProcess = null; 12441 } 12442 } else if (!app.removed) { 12443 // This app is persistent, so we need to keep its record around. 12444 // If it is not already on the pending app list, add it there 12445 // and start a new process for it. 12446 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12447 mPersistentStartingProcesses.add(app); 12448 restart = true; 12449 } 12450 } 12451 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12452 "Clean-up removing on hold: " + app); 12453 mProcessesOnHold.remove(app); 12454 12455 if (app == mHomeProcess) { 12456 mHomeProcess = null; 12457 } 12458 if (app == mPreviousProcess) { 12459 mPreviousProcess = null; 12460 } 12461 12462 if (restart && !app.isolated) { 12463 // We have components that still need to be running in the 12464 // process, so re-launch it. 12465 mProcessNames.put(app.processName, app.uid, app); 12466 startProcessLocked(app, "restart", app.processName, null /* ABI override */); 12467 } else if (app.pid > 0 && app.pid != MY_PID) { 12468 // Goodbye! 12469 synchronized (mPidsSelfLocked) { 12470 mPidsSelfLocked.remove(app.pid); 12471 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12472 } 12473 app.setPid(0); 12474 } 12475 } 12476 12477 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12478 // Look through the content providers we are waiting to have launched, 12479 // and if any run in this process then either schedule a restart of 12480 // the process or kill the client waiting for it if this process has 12481 // gone bad. 12482 int NL = mLaunchingProviders.size(); 12483 boolean restart = false; 12484 for (int i=0; i<NL; i++) { 12485 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12486 if (cpr.launchingApp == app) { 12487 if (!alwaysBad && !app.bad) { 12488 restart = true; 12489 } else { 12490 removeDyingProviderLocked(app, cpr, true); 12491 // cpr should have been removed from mLaunchingProviders 12492 NL = mLaunchingProviders.size(); 12493 i--; 12494 } 12495 } 12496 } 12497 return restart; 12498 } 12499 12500 // ========================================================= 12501 // SERVICES 12502 // ========================================================= 12503 12504 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12505 int flags) { 12506 enforceNotIsolatedCaller("getServices"); 12507 synchronized (this) { 12508 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12509 } 12510 } 12511 12512 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12513 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12514 synchronized (this) { 12515 return mServices.getRunningServiceControlPanelLocked(name); 12516 } 12517 } 12518 12519 public ComponentName startService(IApplicationThread caller, Intent service, 12520 String resolvedType, int userId) { 12521 enforceNotIsolatedCaller("startService"); 12522 // Refuse possible leaked file descriptors 12523 if (service != null && service.hasFileDescriptors() == true) { 12524 throw new IllegalArgumentException("File descriptors passed in Intent"); 12525 } 12526 12527 if (DEBUG_SERVICE) 12528 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12529 synchronized(this) { 12530 final int callingPid = Binder.getCallingPid(); 12531 final int callingUid = Binder.getCallingUid(); 12532 final long origId = Binder.clearCallingIdentity(); 12533 ComponentName res = mServices.startServiceLocked(caller, service, 12534 resolvedType, callingPid, callingUid, userId); 12535 Binder.restoreCallingIdentity(origId); 12536 return res; 12537 } 12538 } 12539 12540 ComponentName startServiceInPackage(int uid, 12541 Intent service, String resolvedType, int userId) { 12542 synchronized(this) { 12543 if (DEBUG_SERVICE) 12544 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12545 final long origId = Binder.clearCallingIdentity(); 12546 ComponentName res = mServices.startServiceLocked(null, service, 12547 resolvedType, -1, uid, userId); 12548 Binder.restoreCallingIdentity(origId); 12549 return res; 12550 } 12551 } 12552 12553 public int stopService(IApplicationThread caller, Intent service, 12554 String resolvedType, int userId) { 12555 enforceNotIsolatedCaller("stopService"); 12556 // Refuse possible leaked file descriptors 12557 if (service != null && service.hasFileDescriptors() == true) { 12558 throw new IllegalArgumentException("File descriptors passed in Intent"); 12559 } 12560 12561 synchronized(this) { 12562 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12563 } 12564 } 12565 12566 public IBinder peekService(Intent service, String resolvedType) { 12567 enforceNotIsolatedCaller("peekService"); 12568 // Refuse possible leaked file descriptors 12569 if (service != null && service.hasFileDescriptors() == true) { 12570 throw new IllegalArgumentException("File descriptors passed in Intent"); 12571 } 12572 synchronized(this) { 12573 return mServices.peekServiceLocked(service, resolvedType); 12574 } 12575 } 12576 12577 public boolean stopServiceToken(ComponentName className, IBinder token, 12578 int startId) { 12579 synchronized(this) { 12580 return mServices.stopServiceTokenLocked(className, token, startId); 12581 } 12582 } 12583 12584 public void setServiceForeground(ComponentName className, IBinder token, 12585 int id, Notification notification, boolean removeNotification) { 12586 synchronized(this) { 12587 mServices.setServiceForegroundLocked(className, token, id, notification, 12588 removeNotification); 12589 } 12590 } 12591 12592 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12593 boolean requireFull, String name, String callerPackage) { 12594 final int callingUserId = UserHandle.getUserId(callingUid); 12595 if (callingUserId != userId) { 12596 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12597 if ((requireFull || checkComponentPermission( 12598 android.Manifest.permission.INTERACT_ACROSS_USERS, 12599 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12600 && checkComponentPermission( 12601 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12602 callingPid, callingUid, -1, true) 12603 != PackageManager.PERMISSION_GRANTED) { 12604 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12605 // In this case, they would like to just execute as their 12606 // owner user instead of failing. 12607 userId = callingUserId; 12608 } else { 12609 StringBuilder builder = new StringBuilder(128); 12610 builder.append("Permission Denial: "); 12611 builder.append(name); 12612 if (callerPackage != null) { 12613 builder.append(" from "); 12614 builder.append(callerPackage); 12615 } 12616 builder.append(" asks to run as user "); 12617 builder.append(userId); 12618 builder.append(" but is calling from user "); 12619 builder.append(UserHandle.getUserId(callingUid)); 12620 builder.append("; this requires "); 12621 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12622 if (!requireFull) { 12623 builder.append(" or "); 12624 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12625 } 12626 String msg = builder.toString(); 12627 Slog.w(TAG, msg); 12628 throw new SecurityException(msg); 12629 } 12630 } 12631 } 12632 if (userId == UserHandle.USER_CURRENT 12633 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12634 // Note that we may be accessing this outside of a lock... 12635 // shouldn't be a big deal, if this is being called outside 12636 // of a locked context there is intrinsically a race with 12637 // the value the caller will receive and someone else changing it. 12638 userId = mCurrentUserId; 12639 } 12640 if (!allowAll && userId < 0) { 12641 throw new IllegalArgumentException( 12642 "Call does not support special user #" + userId); 12643 } 12644 } 12645 return userId; 12646 } 12647 12648 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12649 String className, int flags) { 12650 boolean result = false; 12651 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12652 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12653 if (ActivityManager.checkUidPermission( 12654 android.Manifest.permission.INTERACT_ACROSS_USERS, 12655 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12656 ComponentName comp = new ComponentName(aInfo.packageName, className); 12657 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12658 + " requests FLAG_SINGLE_USER, but app does not hold " 12659 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12660 Slog.w(TAG, msg); 12661 throw new SecurityException(msg); 12662 } 12663 result = true; 12664 } 12665 } else if (componentProcessName == aInfo.packageName) { 12666 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12667 } else if ("system".equals(componentProcessName)) { 12668 result = true; 12669 } 12670 if (DEBUG_MU) { 12671 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12672 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12673 } 12674 return result; 12675 } 12676 12677 public int bindService(IApplicationThread caller, IBinder token, 12678 Intent service, String resolvedType, 12679 IServiceConnection connection, int flags, int userId) { 12680 enforceNotIsolatedCaller("bindService"); 12681 // Refuse possible leaked file descriptors 12682 if (service != null && service.hasFileDescriptors() == true) { 12683 throw new IllegalArgumentException("File descriptors passed in Intent"); 12684 } 12685 12686 synchronized(this) { 12687 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12688 connection, flags, userId); 12689 } 12690 } 12691 12692 public boolean unbindService(IServiceConnection connection) { 12693 synchronized (this) { 12694 return mServices.unbindServiceLocked(connection); 12695 } 12696 } 12697 12698 public void publishService(IBinder token, Intent intent, IBinder service) { 12699 // Refuse possible leaked file descriptors 12700 if (intent != null && intent.hasFileDescriptors() == true) { 12701 throw new IllegalArgumentException("File descriptors passed in Intent"); 12702 } 12703 12704 synchronized(this) { 12705 if (!(token instanceof ServiceRecord)) { 12706 throw new IllegalArgumentException("Invalid service token"); 12707 } 12708 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12709 } 12710 } 12711 12712 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12713 // Refuse possible leaked file descriptors 12714 if (intent != null && intent.hasFileDescriptors() == true) { 12715 throw new IllegalArgumentException("File descriptors passed in Intent"); 12716 } 12717 12718 synchronized(this) { 12719 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12720 } 12721 } 12722 12723 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12724 synchronized(this) { 12725 if (!(token instanceof ServiceRecord)) { 12726 throw new IllegalArgumentException("Invalid service token"); 12727 } 12728 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12729 } 12730 } 12731 12732 // ========================================================= 12733 // BACKUP AND RESTORE 12734 // ========================================================= 12735 12736 // Cause the target app to be launched if necessary and its backup agent 12737 // instantiated. The backup agent will invoke backupAgentCreated() on the 12738 // activity manager to announce its creation. 12739 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12740 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12741 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12742 12743 synchronized(this) { 12744 // !!! TODO: currently no check here that we're already bound 12745 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12746 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12747 synchronized (stats) { 12748 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12749 } 12750 12751 // Backup agent is now in use, its package can't be stopped. 12752 try { 12753 AppGlobals.getPackageManager().setPackageStoppedState( 12754 app.packageName, false, UserHandle.getUserId(app.uid)); 12755 } catch (RemoteException e) { 12756 } catch (IllegalArgumentException e) { 12757 Slog.w(TAG, "Failed trying to unstop package " 12758 + app.packageName + ": " + e); 12759 } 12760 12761 BackupRecord r = new BackupRecord(ss, app, backupMode); 12762 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12763 ? new ComponentName(app.packageName, app.backupAgentName) 12764 : new ComponentName("android", "FullBackupAgent"); 12765 // startProcessLocked() returns existing proc's record if it's already running 12766 ProcessRecord proc = startProcessLocked(app.processName, app, 12767 false, 0, "backup", hostingName, false, false, false); 12768 if (proc == null) { 12769 Slog.e(TAG, "Unable to start backup agent process " + r); 12770 return false; 12771 } 12772 12773 r.app = proc; 12774 mBackupTarget = r; 12775 mBackupAppName = app.packageName; 12776 12777 // Try not to kill the process during backup 12778 updateOomAdjLocked(proc); 12779 12780 // If the process is already attached, schedule the creation of the backup agent now. 12781 // If it is not yet live, this will be done when it attaches to the framework. 12782 if (proc.thread != null) { 12783 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12784 try { 12785 proc.thread.scheduleCreateBackupAgent(app, 12786 compatibilityInfoForPackageLocked(app), backupMode); 12787 } catch (RemoteException e) { 12788 // Will time out on the backup manager side 12789 } 12790 } else { 12791 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12792 } 12793 // Invariants: at this point, the target app process exists and the application 12794 // is either already running or in the process of coming up. mBackupTarget and 12795 // mBackupAppName describe the app, so that when it binds back to the AM we 12796 // know that it's scheduled for a backup-agent operation. 12797 } 12798 12799 return true; 12800 } 12801 12802 @Override 12803 public void clearPendingBackup() { 12804 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 12805 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 12806 12807 synchronized (this) { 12808 mBackupTarget = null; 12809 mBackupAppName = null; 12810 } 12811 } 12812 12813 // A backup agent has just come up 12814 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12815 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12816 + " = " + agent); 12817 12818 synchronized(this) { 12819 if (!agentPackageName.equals(mBackupAppName)) { 12820 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12821 return; 12822 } 12823 } 12824 12825 long oldIdent = Binder.clearCallingIdentity(); 12826 try { 12827 IBackupManager bm = IBackupManager.Stub.asInterface( 12828 ServiceManager.getService(Context.BACKUP_SERVICE)); 12829 bm.agentConnected(agentPackageName, agent); 12830 } catch (RemoteException e) { 12831 // can't happen; the backup manager service is local 12832 } catch (Exception e) { 12833 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12834 e.printStackTrace(); 12835 } finally { 12836 Binder.restoreCallingIdentity(oldIdent); 12837 } 12838 } 12839 12840 // done with this agent 12841 public void unbindBackupAgent(ApplicationInfo appInfo) { 12842 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12843 if (appInfo == null) { 12844 Slog.w(TAG, "unbind backup agent for null app"); 12845 return; 12846 } 12847 12848 synchronized(this) { 12849 try { 12850 if (mBackupAppName == null) { 12851 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12852 return; 12853 } 12854 12855 if (!mBackupAppName.equals(appInfo.packageName)) { 12856 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12857 return; 12858 } 12859 12860 // Not backing this app up any more; reset its OOM adjustment 12861 final ProcessRecord proc = mBackupTarget.app; 12862 updateOomAdjLocked(proc); 12863 12864 // If the app crashed during backup, 'thread' will be null here 12865 if (proc.thread != null) { 12866 try { 12867 proc.thread.scheduleDestroyBackupAgent(appInfo, 12868 compatibilityInfoForPackageLocked(appInfo)); 12869 } catch (Exception e) { 12870 Slog.e(TAG, "Exception when unbinding backup agent:"); 12871 e.printStackTrace(); 12872 } 12873 } 12874 } finally { 12875 mBackupTarget = null; 12876 mBackupAppName = null; 12877 } 12878 } 12879 } 12880 // ========================================================= 12881 // BROADCASTS 12882 // ========================================================= 12883 12884 private final List getStickiesLocked(String action, IntentFilter filter, 12885 List cur, int userId) { 12886 final ContentResolver resolver = mContext.getContentResolver(); 12887 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12888 if (stickies == null) { 12889 return cur; 12890 } 12891 final ArrayList<Intent> list = stickies.get(action); 12892 if (list == null) { 12893 return cur; 12894 } 12895 int N = list.size(); 12896 for (int i=0; i<N; i++) { 12897 Intent intent = list.get(i); 12898 if (filter.match(resolver, intent, true, TAG) >= 0) { 12899 if (cur == null) { 12900 cur = new ArrayList<Intent>(); 12901 } 12902 cur.add(intent); 12903 } 12904 } 12905 return cur; 12906 } 12907 12908 boolean isPendingBroadcastProcessLocked(int pid) { 12909 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12910 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12911 } 12912 12913 void skipPendingBroadcastLocked(int pid) { 12914 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 12915 for (BroadcastQueue queue : mBroadcastQueues) { 12916 queue.skipPendingBroadcastLocked(pid); 12917 } 12918 } 12919 12920 // The app just attached; send any pending broadcasts that it should receive 12921 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 12922 boolean didSomething = false; 12923 for (BroadcastQueue queue : mBroadcastQueues) { 12924 didSomething |= queue.sendPendingBroadcastsLocked(app); 12925 } 12926 return didSomething; 12927 } 12928 12929 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 12930 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 12931 enforceNotIsolatedCaller("registerReceiver"); 12932 int callingUid; 12933 int callingPid; 12934 synchronized(this) { 12935 ProcessRecord callerApp = null; 12936 if (caller != null) { 12937 callerApp = getRecordForAppLocked(caller); 12938 if (callerApp == null) { 12939 throw new SecurityException( 12940 "Unable to find app for caller " + caller 12941 + " (pid=" + Binder.getCallingPid() 12942 + ") when registering receiver " + receiver); 12943 } 12944 if (callerApp.info.uid != Process.SYSTEM_UID && 12945 !callerApp.pkgList.containsKey(callerPackage) && 12946 !"android".equals(callerPackage)) { 12947 throw new SecurityException("Given caller package " + callerPackage 12948 + " is not running in process " + callerApp); 12949 } 12950 callingUid = callerApp.info.uid; 12951 callingPid = callerApp.pid; 12952 } else { 12953 callerPackage = null; 12954 callingUid = Binder.getCallingUid(); 12955 callingPid = Binder.getCallingPid(); 12956 } 12957 12958 userId = this.handleIncomingUser(callingPid, callingUid, userId, 12959 true, true, "registerReceiver", callerPackage); 12960 12961 List allSticky = null; 12962 12963 // Look for any matching sticky broadcasts... 12964 Iterator actions = filter.actionsIterator(); 12965 if (actions != null) { 12966 while (actions.hasNext()) { 12967 String action = (String)actions.next(); 12968 allSticky = getStickiesLocked(action, filter, allSticky, 12969 UserHandle.USER_ALL); 12970 allSticky = getStickiesLocked(action, filter, allSticky, 12971 UserHandle.getUserId(callingUid)); 12972 } 12973 } else { 12974 allSticky = getStickiesLocked(null, filter, allSticky, 12975 UserHandle.USER_ALL); 12976 allSticky = getStickiesLocked(null, filter, allSticky, 12977 UserHandle.getUserId(callingUid)); 12978 } 12979 12980 // The first sticky in the list is returned directly back to 12981 // the client. 12982 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 12983 12984 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 12985 + ": " + sticky); 12986 12987 if (receiver == null) { 12988 return sticky; 12989 } 12990 12991 ReceiverList rl 12992 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12993 if (rl == null) { 12994 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 12995 userId, receiver); 12996 if (rl.app != null) { 12997 rl.app.receivers.add(rl); 12998 } else { 12999 try { 13000 receiver.asBinder().linkToDeath(rl, 0); 13001 } catch (RemoteException e) { 13002 return sticky; 13003 } 13004 rl.linkedToDeath = true; 13005 } 13006 mRegisteredReceivers.put(receiver.asBinder(), rl); 13007 } else if (rl.uid != callingUid) { 13008 throw new IllegalArgumentException( 13009 "Receiver requested to register for uid " + callingUid 13010 + " was previously registered for uid " + rl.uid); 13011 } else if (rl.pid != callingPid) { 13012 throw new IllegalArgumentException( 13013 "Receiver requested to register for pid " + callingPid 13014 + " was previously registered for pid " + rl.pid); 13015 } else if (rl.userId != userId) { 13016 throw new IllegalArgumentException( 13017 "Receiver requested to register for user " + userId 13018 + " was previously registered for user " + rl.userId); 13019 } 13020 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13021 permission, callingUid, userId); 13022 rl.add(bf); 13023 if (!bf.debugCheck()) { 13024 Slog.w(TAG, "==> For Dynamic broadast"); 13025 } 13026 mReceiverResolver.addFilter(bf); 13027 13028 // Enqueue broadcasts for all existing stickies that match 13029 // this filter. 13030 if (allSticky != null) { 13031 ArrayList receivers = new ArrayList(); 13032 receivers.add(bf); 13033 13034 int N = allSticky.size(); 13035 for (int i=0; i<N; i++) { 13036 Intent intent = (Intent)allSticky.get(i); 13037 BroadcastQueue queue = broadcastQueueForIntent(intent); 13038 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13039 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13040 null, null, false, true, true, -1); 13041 queue.enqueueParallelBroadcastLocked(r); 13042 queue.scheduleBroadcastsLocked(); 13043 } 13044 } 13045 13046 return sticky; 13047 } 13048 } 13049 13050 public void unregisterReceiver(IIntentReceiver receiver) { 13051 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13052 13053 final long origId = Binder.clearCallingIdentity(); 13054 try { 13055 boolean doTrim = false; 13056 13057 synchronized(this) { 13058 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13059 if (rl != null) { 13060 if (rl.curBroadcast != null) { 13061 BroadcastRecord r = rl.curBroadcast; 13062 final boolean doNext = finishReceiverLocked( 13063 receiver.asBinder(), r.resultCode, r.resultData, 13064 r.resultExtras, r.resultAbort); 13065 if (doNext) { 13066 doTrim = true; 13067 r.queue.processNextBroadcast(false); 13068 } 13069 } 13070 13071 if (rl.app != null) { 13072 rl.app.receivers.remove(rl); 13073 } 13074 removeReceiverLocked(rl); 13075 if (rl.linkedToDeath) { 13076 rl.linkedToDeath = false; 13077 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13078 } 13079 } 13080 } 13081 13082 // If we actually concluded any broadcasts, we might now be able 13083 // to trim the recipients' apps from our working set 13084 if (doTrim) { 13085 trimApplications(); 13086 return; 13087 } 13088 13089 } finally { 13090 Binder.restoreCallingIdentity(origId); 13091 } 13092 } 13093 13094 void removeReceiverLocked(ReceiverList rl) { 13095 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13096 int N = rl.size(); 13097 for (int i=0; i<N; i++) { 13098 mReceiverResolver.removeFilter(rl.get(i)); 13099 } 13100 } 13101 13102 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13103 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13104 ProcessRecord r = mLruProcesses.get(i); 13105 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13106 try { 13107 r.thread.dispatchPackageBroadcast(cmd, packages); 13108 } catch (RemoteException ex) { 13109 } 13110 } 13111 } 13112 } 13113 13114 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13115 int[] users) { 13116 List<ResolveInfo> receivers = null; 13117 try { 13118 HashSet<ComponentName> singleUserReceivers = null; 13119 boolean scannedFirstReceivers = false; 13120 for (int user : users) { 13121 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13122 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13123 if (user != 0 && newReceivers != null) { 13124 // If this is not the primary user, we need to check for 13125 // any receivers that should be filtered out. 13126 for (int i=0; i<newReceivers.size(); i++) { 13127 ResolveInfo ri = newReceivers.get(i); 13128 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13129 newReceivers.remove(i); 13130 i--; 13131 } 13132 } 13133 } 13134 if (newReceivers != null && newReceivers.size() == 0) { 13135 newReceivers = null; 13136 } 13137 if (receivers == null) { 13138 receivers = newReceivers; 13139 } else if (newReceivers != null) { 13140 // We need to concatenate the additional receivers 13141 // found with what we have do far. This would be easy, 13142 // but we also need to de-dup any receivers that are 13143 // singleUser. 13144 if (!scannedFirstReceivers) { 13145 // Collect any single user receivers we had already retrieved. 13146 scannedFirstReceivers = true; 13147 for (int i=0; i<receivers.size(); i++) { 13148 ResolveInfo ri = receivers.get(i); 13149 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13150 ComponentName cn = new ComponentName( 13151 ri.activityInfo.packageName, ri.activityInfo.name); 13152 if (singleUserReceivers == null) { 13153 singleUserReceivers = new HashSet<ComponentName>(); 13154 } 13155 singleUserReceivers.add(cn); 13156 } 13157 } 13158 } 13159 // Add the new results to the existing results, tracking 13160 // and de-dupping single user receivers. 13161 for (int i=0; i<newReceivers.size(); i++) { 13162 ResolveInfo ri = newReceivers.get(i); 13163 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13164 ComponentName cn = new ComponentName( 13165 ri.activityInfo.packageName, ri.activityInfo.name); 13166 if (singleUserReceivers == null) { 13167 singleUserReceivers = new HashSet<ComponentName>(); 13168 } 13169 if (!singleUserReceivers.contains(cn)) { 13170 singleUserReceivers.add(cn); 13171 receivers.add(ri); 13172 } 13173 } else { 13174 receivers.add(ri); 13175 } 13176 } 13177 } 13178 } 13179 } catch (RemoteException ex) { 13180 // pm is in same process, this will never happen. 13181 } 13182 return receivers; 13183 } 13184 13185 private final int broadcastIntentLocked(ProcessRecord callerApp, 13186 String callerPackage, Intent intent, String resolvedType, 13187 IIntentReceiver resultTo, int resultCode, String resultData, 13188 Bundle map, String requiredPermission, int appOp, 13189 boolean ordered, boolean sticky, int callingPid, int callingUid, 13190 int userId) { 13191 intent = new Intent(intent); 13192 13193 // By default broadcasts do not go to stopped apps. 13194 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13195 13196 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13197 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13198 + " ordered=" + ordered + " userid=" + userId); 13199 if ((resultTo != null) && !ordered) { 13200 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13201 } 13202 13203 userId = handleIncomingUser(callingPid, callingUid, userId, 13204 true, false, "broadcast", callerPackage); 13205 13206 // Make sure that the user who is receiving this broadcast is started. 13207 // If not, we will just skip it. 13208 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13209 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13210 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13211 Slog.w(TAG, "Skipping broadcast of " + intent 13212 + ": user " + userId + " is stopped"); 13213 return ActivityManager.BROADCAST_SUCCESS; 13214 } 13215 } 13216 13217 /* 13218 * Prevent non-system code (defined here to be non-persistent 13219 * processes) from sending protected broadcasts. 13220 */ 13221 int callingAppId = UserHandle.getAppId(callingUid); 13222 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13223 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13224 callingUid == 0) { 13225 // Always okay. 13226 } else if (callerApp == null || !callerApp.persistent) { 13227 try { 13228 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13229 intent.getAction())) { 13230 String msg = "Permission Denial: not allowed to send broadcast " 13231 + intent.getAction() + " from pid=" 13232 + callingPid + ", uid=" + callingUid; 13233 Slog.w(TAG, msg); 13234 throw new SecurityException(msg); 13235 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13236 // Special case for compatibility: we don't want apps to send this, 13237 // but historically it has not been protected and apps may be using it 13238 // to poke their own app widget. So, instead of making it protected, 13239 // just limit it to the caller. 13240 if (callerApp == null) { 13241 String msg = "Permission Denial: not allowed to send broadcast " 13242 + intent.getAction() + " from unknown caller."; 13243 Slog.w(TAG, msg); 13244 throw new SecurityException(msg); 13245 } else if (intent.getComponent() != null) { 13246 // They are good enough to send to an explicit component... verify 13247 // it is being sent to the calling app. 13248 if (!intent.getComponent().getPackageName().equals( 13249 callerApp.info.packageName)) { 13250 String msg = "Permission Denial: not allowed to send broadcast " 13251 + intent.getAction() + " to " 13252 + intent.getComponent().getPackageName() + " from " 13253 + callerApp.info.packageName; 13254 Slog.w(TAG, msg); 13255 throw new SecurityException(msg); 13256 } 13257 } else { 13258 // Limit broadcast to their own package. 13259 intent.setPackage(callerApp.info.packageName); 13260 } 13261 } 13262 } catch (RemoteException e) { 13263 Slog.w(TAG, "Remote exception", e); 13264 return ActivityManager.BROADCAST_SUCCESS; 13265 } 13266 } 13267 13268 // Handle special intents: if this broadcast is from the package 13269 // manager about a package being removed, we need to remove all of 13270 // its activities from the history stack. 13271 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13272 intent.getAction()); 13273 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13274 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13275 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13276 || uidRemoved) { 13277 if (checkComponentPermission( 13278 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13279 callingPid, callingUid, -1, true) 13280 == PackageManager.PERMISSION_GRANTED) { 13281 if (uidRemoved) { 13282 final Bundle intentExtras = intent.getExtras(); 13283 final int uid = intentExtras != null 13284 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13285 if (uid >= 0) { 13286 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13287 synchronized (bs) { 13288 bs.removeUidStatsLocked(uid); 13289 } 13290 mAppOpsService.uidRemoved(uid); 13291 } 13292 } else { 13293 // If resources are unavailable just force stop all 13294 // those packages and flush the attribute cache as well. 13295 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13296 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13297 if (list != null && (list.length > 0)) { 13298 for (String pkg : list) { 13299 forceStopPackageLocked(pkg, -1, false, true, true, false, userId, 13300 "storage unmount"); 13301 } 13302 sendPackageBroadcastLocked( 13303 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13304 } 13305 } else { 13306 Uri data = intent.getData(); 13307 String ssp; 13308 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13309 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13310 intent.getAction()); 13311 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13312 forceStopPackageLocked(ssp, UserHandle.getAppId( 13313 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13314 false, userId, removed ? "pkg removed" : "pkg changed"); 13315 } 13316 if (removed) { 13317 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13318 new String[] {ssp}, userId); 13319 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13320 mAppOpsService.packageRemoved( 13321 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13322 13323 // Remove all permissions granted from/to this package 13324 removeUriPermissionsForPackageLocked(ssp, userId, true); 13325 } 13326 } 13327 } 13328 } 13329 } 13330 } else { 13331 String msg = "Permission Denial: " + intent.getAction() 13332 + " broadcast from " + callerPackage + " (pid=" + callingPid 13333 + ", uid=" + callingUid + ")" 13334 + " requires " 13335 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13336 Slog.w(TAG, msg); 13337 throw new SecurityException(msg); 13338 } 13339 13340 // Special case for adding a package: by default turn on compatibility 13341 // mode. 13342 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13343 Uri data = intent.getData(); 13344 String ssp; 13345 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13346 mCompatModePackages.handlePackageAddedLocked(ssp, 13347 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13348 } 13349 } 13350 13351 /* 13352 * If this is the time zone changed action, queue up a message that will reset the timezone 13353 * of all currently running processes. This message will get queued up before the broadcast 13354 * happens. 13355 */ 13356 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13357 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13358 } 13359 13360 /* 13361 * If the user set the time, let all running processes know. 13362 */ 13363 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13364 final int is24Hour = intent.getBooleanExtra( 13365 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13366 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13367 } 13368 13369 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13370 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13371 } 13372 13373 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13374 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13375 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13376 } 13377 13378 // Add to the sticky list if requested. 13379 if (sticky) { 13380 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13381 callingPid, callingUid) 13382 != PackageManager.PERMISSION_GRANTED) { 13383 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13384 + callingPid + ", uid=" + callingUid 13385 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13386 Slog.w(TAG, msg); 13387 throw new SecurityException(msg); 13388 } 13389 if (requiredPermission != null) { 13390 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13391 + " and enforce permission " + requiredPermission); 13392 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13393 } 13394 if (intent.getComponent() != null) { 13395 throw new SecurityException( 13396 "Sticky broadcasts can't target a specific component"); 13397 } 13398 // We use userId directly here, since the "all" target is maintained 13399 // as a separate set of sticky broadcasts. 13400 if (userId != UserHandle.USER_ALL) { 13401 // But first, if this is not a broadcast to all users, then 13402 // make sure it doesn't conflict with an existing broadcast to 13403 // all users. 13404 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13405 UserHandle.USER_ALL); 13406 if (stickies != null) { 13407 ArrayList<Intent> list = stickies.get(intent.getAction()); 13408 if (list != null) { 13409 int N = list.size(); 13410 int i; 13411 for (i=0; i<N; i++) { 13412 if (intent.filterEquals(list.get(i))) { 13413 throw new IllegalArgumentException( 13414 "Sticky broadcast " + intent + " for user " 13415 + userId + " conflicts with existing global broadcast"); 13416 } 13417 } 13418 } 13419 } 13420 } 13421 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13422 if (stickies == null) { 13423 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13424 mStickyBroadcasts.put(userId, stickies); 13425 } 13426 ArrayList<Intent> list = stickies.get(intent.getAction()); 13427 if (list == null) { 13428 list = new ArrayList<Intent>(); 13429 stickies.put(intent.getAction(), list); 13430 } 13431 int N = list.size(); 13432 int i; 13433 for (i=0; i<N; i++) { 13434 if (intent.filterEquals(list.get(i))) { 13435 // This sticky already exists, replace it. 13436 list.set(i, new Intent(intent)); 13437 break; 13438 } 13439 } 13440 if (i >= N) { 13441 list.add(new Intent(intent)); 13442 } 13443 } 13444 13445 int[] users; 13446 if (userId == UserHandle.USER_ALL) { 13447 // Caller wants broadcast to go to all started users. 13448 users = mStartedUserArray; 13449 } else { 13450 // Caller wants broadcast to go to one specific user. 13451 users = new int[] {userId}; 13452 } 13453 13454 // Figure out who all will receive this broadcast. 13455 List receivers = null; 13456 List<BroadcastFilter> registeredReceivers = null; 13457 // Need to resolve the intent to interested receivers... 13458 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13459 == 0) { 13460 receivers = collectReceiverComponents(intent, resolvedType, users); 13461 } 13462 if (intent.getComponent() == null) { 13463 registeredReceivers = mReceiverResolver.queryIntent(intent, 13464 resolvedType, false, userId); 13465 } 13466 13467 final boolean replacePending = 13468 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13469 13470 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13471 + " replacePending=" + replacePending); 13472 13473 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13474 if (!ordered && NR > 0) { 13475 // If we are not serializing this broadcast, then send the 13476 // registered receivers separately so they don't wait for the 13477 // components to be launched. 13478 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13479 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13480 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13481 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13482 ordered, sticky, false, userId); 13483 if (DEBUG_BROADCAST) Slog.v( 13484 TAG, "Enqueueing parallel broadcast " + r); 13485 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13486 if (!replaced) { 13487 queue.enqueueParallelBroadcastLocked(r); 13488 queue.scheduleBroadcastsLocked(); 13489 } 13490 registeredReceivers = null; 13491 NR = 0; 13492 } 13493 13494 // Merge into one list. 13495 int ir = 0; 13496 if (receivers != null) { 13497 // A special case for PACKAGE_ADDED: do not allow the package 13498 // being added to see this broadcast. This prevents them from 13499 // using this as a back door to get run as soon as they are 13500 // installed. Maybe in the future we want to have a special install 13501 // broadcast or such for apps, but we'd like to deliberately make 13502 // this decision. 13503 String skipPackages[] = null; 13504 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13505 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13506 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13507 Uri data = intent.getData(); 13508 if (data != null) { 13509 String pkgName = data.getSchemeSpecificPart(); 13510 if (pkgName != null) { 13511 skipPackages = new String[] { pkgName }; 13512 } 13513 } 13514 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13515 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13516 } 13517 if (skipPackages != null && (skipPackages.length > 0)) { 13518 for (String skipPackage : skipPackages) { 13519 if (skipPackage != null) { 13520 int NT = receivers.size(); 13521 for (int it=0; it<NT; it++) { 13522 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13523 if (curt.activityInfo.packageName.equals(skipPackage)) { 13524 receivers.remove(it); 13525 it--; 13526 NT--; 13527 } 13528 } 13529 } 13530 } 13531 } 13532 13533 int NT = receivers != null ? receivers.size() : 0; 13534 int it = 0; 13535 ResolveInfo curt = null; 13536 BroadcastFilter curr = null; 13537 while (it < NT && ir < NR) { 13538 if (curt == null) { 13539 curt = (ResolveInfo)receivers.get(it); 13540 } 13541 if (curr == null) { 13542 curr = registeredReceivers.get(ir); 13543 } 13544 if (curr.getPriority() >= curt.priority) { 13545 // Insert this broadcast record into the final list. 13546 receivers.add(it, curr); 13547 ir++; 13548 curr = null; 13549 it++; 13550 NT++; 13551 } else { 13552 // Skip to the next ResolveInfo in the final list. 13553 it++; 13554 curt = null; 13555 } 13556 } 13557 } 13558 while (ir < NR) { 13559 if (receivers == null) { 13560 receivers = new ArrayList(); 13561 } 13562 receivers.add(registeredReceivers.get(ir)); 13563 ir++; 13564 } 13565 13566 if ((receivers != null && receivers.size() > 0) 13567 || resultTo != null) { 13568 BroadcastQueue queue = broadcastQueueForIntent(intent); 13569 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13570 callerPackage, callingPid, callingUid, resolvedType, 13571 requiredPermission, appOp, receivers, resultTo, resultCode, 13572 resultData, map, ordered, sticky, false, userId); 13573 if (DEBUG_BROADCAST) Slog.v( 13574 TAG, "Enqueueing ordered broadcast " + r 13575 + ": prev had " + queue.mOrderedBroadcasts.size()); 13576 if (DEBUG_BROADCAST) { 13577 int seq = r.intent.getIntExtra("seq", -1); 13578 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13579 } 13580 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13581 if (!replaced) { 13582 queue.enqueueOrderedBroadcastLocked(r); 13583 queue.scheduleBroadcastsLocked(); 13584 } 13585 } 13586 13587 return ActivityManager.BROADCAST_SUCCESS; 13588 } 13589 13590 final Intent verifyBroadcastLocked(Intent intent) { 13591 // Refuse possible leaked file descriptors 13592 if (intent != null && intent.hasFileDescriptors() == true) { 13593 throw new IllegalArgumentException("File descriptors passed in Intent"); 13594 } 13595 13596 int flags = intent.getFlags(); 13597 13598 if (!mProcessesReady) { 13599 // if the caller really truly claims to know what they're doing, go 13600 // ahead and allow the broadcast without launching any receivers 13601 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13602 intent = new Intent(intent); 13603 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13604 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13605 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13606 + " before boot completion"); 13607 throw new IllegalStateException("Cannot broadcast before boot completed"); 13608 } 13609 } 13610 13611 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13612 throw new IllegalArgumentException( 13613 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13614 } 13615 13616 return intent; 13617 } 13618 13619 public final int broadcastIntent(IApplicationThread caller, 13620 Intent intent, String resolvedType, IIntentReceiver resultTo, 13621 int resultCode, String resultData, Bundle map, 13622 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13623 enforceNotIsolatedCaller("broadcastIntent"); 13624 synchronized(this) { 13625 intent = verifyBroadcastLocked(intent); 13626 13627 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13628 final int callingPid = Binder.getCallingPid(); 13629 final int callingUid = Binder.getCallingUid(); 13630 final long origId = Binder.clearCallingIdentity(); 13631 int res = broadcastIntentLocked(callerApp, 13632 callerApp != null ? callerApp.info.packageName : null, 13633 intent, resolvedType, resultTo, 13634 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13635 callingPid, callingUid, userId); 13636 Binder.restoreCallingIdentity(origId); 13637 return res; 13638 } 13639 } 13640 13641 int broadcastIntentInPackage(String packageName, int uid, 13642 Intent intent, String resolvedType, IIntentReceiver resultTo, 13643 int resultCode, String resultData, Bundle map, 13644 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13645 synchronized(this) { 13646 intent = verifyBroadcastLocked(intent); 13647 13648 final long origId = Binder.clearCallingIdentity(); 13649 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13650 resultTo, resultCode, resultData, map, requiredPermission, 13651 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13652 Binder.restoreCallingIdentity(origId); 13653 return res; 13654 } 13655 } 13656 13657 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13658 // Refuse possible leaked file descriptors 13659 if (intent != null && intent.hasFileDescriptors() == true) { 13660 throw new IllegalArgumentException("File descriptors passed in Intent"); 13661 } 13662 13663 userId = handleIncomingUser(Binder.getCallingPid(), 13664 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13665 13666 synchronized(this) { 13667 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13668 != PackageManager.PERMISSION_GRANTED) { 13669 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13670 + Binder.getCallingPid() 13671 + ", uid=" + Binder.getCallingUid() 13672 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13673 Slog.w(TAG, msg); 13674 throw new SecurityException(msg); 13675 } 13676 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13677 if (stickies != null) { 13678 ArrayList<Intent> list = stickies.get(intent.getAction()); 13679 if (list != null) { 13680 int N = list.size(); 13681 int i; 13682 for (i=0; i<N; i++) { 13683 if (intent.filterEquals(list.get(i))) { 13684 list.remove(i); 13685 break; 13686 } 13687 } 13688 if (list.size() <= 0) { 13689 stickies.remove(intent.getAction()); 13690 } 13691 } 13692 if (stickies.size() <= 0) { 13693 mStickyBroadcasts.remove(userId); 13694 } 13695 } 13696 } 13697 } 13698 13699 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13700 String resultData, Bundle resultExtras, boolean resultAbort) { 13701 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13702 if (r == null) { 13703 Slog.w(TAG, "finishReceiver called but not found on queue"); 13704 return false; 13705 } 13706 13707 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13708 } 13709 13710 void backgroundServicesFinishedLocked(int userId) { 13711 for (BroadcastQueue queue : mBroadcastQueues) { 13712 queue.backgroundServicesFinishedLocked(userId); 13713 } 13714 } 13715 13716 public void finishReceiver(IBinder who, int resultCode, String resultData, 13717 Bundle resultExtras, boolean resultAbort) { 13718 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13719 13720 // Refuse possible leaked file descriptors 13721 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13722 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13723 } 13724 13725 final long origId = Binder.clearCallingIdentity(); 13726 try { 13727 boolean doNext = false; 13728 BroadcastRecord r; 13729 13730 synchronized(this) { 13731 r = broadcastRecordForReceiverLocked(who); 13732 if (r != null) { 13733 doNext = r.queue.finishReceiverLocked(r, resultCode, 13734 resultData, resultExtras, resultAbort, true); 13735 } 13736 } 13737 13738 if (doNext) { 13739 r.queue.processNextBroadcast(false); 13740 } 13741 trimApplications(); 13742 } finally { 13743 Binder.restoreCallingIdentity(origId); 13744 } 13745 } 13746 13747 // ========================================================= 13748 // INSTRUMENTATION 13749 // ========================================================= 13750 13751 public boolean startInstrumentation(ComponentName className, 13752 String profileFile, int flags, Bundle arguments, 13753 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13754 int userId, String abiOverride) { 13755 enforceNotIsolatedCaller("startInstrumentation"); 13756 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13757 userId, false, true, "startInstrumentation", null); 13758 // Refuse possible leaked file descriptors 13759 if (arguments != null && arguments.hasFileDescriptors()) { 13760 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13761 } 13762 13763 synchronized(this) { 13764 InstrumentationInfo ii = null; 13765 ApplicationInfo ai = null; 13766 try { 13767 ii = mContext.getPackageManager().getInstrumentationInfo( 13768 className, STOCK_PM_FLAGS); 13769 ai = AppGlobals.getPackageManager().getApplicationInfo( 13770 ii.targetPackage, STOCK_PM_FLAGS, userId); 13771 } catch (PackageManager.NameNotFoundException e) { 13772 } catch (RemoteException e) { 13773 } 13774 if (ii == null) { 13775 reportStartInstrumentationFailure(watcher, className, 13776 "Unable to find instrumentation info for: " + className); 13777 return false; 13778 } 13779 if (ai == null) { 13780 reportStartInstrumentationFailure(watcher, className, 13781 "Unable to find instrumentation target package: " + ii.targetPackage); 13782 return false; 13783 } 13784 13785 int match = mContext.getPackageManager().checkSignatures( 13786 ii.targetPackage, ii.packageName); 13787 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13788 String msg = "Permission Denial: starting instrumentation " 13789 + className + " from pid=" 13790 + Binder.getCallingPid() 13791 + ", uid=" + Binder.getCallingPid() 13792 + " not allowed because package " + ii.packageName 13793 + " does not have a signature matching the target " 13794 + ii.targetPackage; 13795 reportStartInstrumentationFailure(watcher, className, msg); 13796 throw new SecurityException(msg); 13797 } 13798 13799 final long origId = Binder.clearCallingIdentity(); 13800 // Instrumentation can kill and relaunch even persistent processes 13801 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId, 13802 "start instr"); 13803 ProcessRecord app = addAppLocked(ai, false, abiOverride); 13804 app.instrumentationClass = className; 13805 app.instrumentationInfo = ai; 13806 app.instrumentationProfileFile = profileFile; 13807 app.instrumentationArguments = arguments; 13808 app.instrumentationWatcher = watcher; 13809 app.instrumentationUiAutomationConnection = uiAutomationConnection; 13810 app.instrumentationResultClass = className; 13811 Binder.restoreCallingIdentity(origId); 13812 } 13813 13814 return true; 13815 } 13816 13817 /** 13818 * Report errors that occur while attempting to start Instrumentation. Always writes the 13819 * error to the logs, but if somebody is watching, send the report there too. This enables 13820 * the "am" command to report errors with more information. 13821 * 13822 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13823 * @param cn The component name of the instrumentation. 13824 * @param report The error report. 13825 */ 13826 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13827 ComponentName cn, String report) { 13828 Slog.w(TAG, report); 13829 try { 13830 if (watcher != null) { 13831 Bundle results = new Bundle(); 13832 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13833 results.putString("Error", report); 13834 watcher.instrumentationStatus(cn, -1, results); 13835 } 13836 } catch (RemoteException e) { 13837 Slog.w(TAG, e); 13838 } 13839 } 13840 13841 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13842 if (app.instrumentationWatcher != null) { 13843 try { 13844 // NOTE: IInstrumentationWatcher *must* be oneway here 13845 app.instrumentationWatcher.instrumentationFinished( 13846 app.instrumentationClass, 13847 resultCode, 13848 results); 13849 } catch (RemoteException e) { 13850 } 13851 } 13852 if (app.instrumentationUiAutomationConnection != null) { 13853 try { 13854 app.instrumentationUiAutomationConnection.shutdown(); 13855 } catch (RemoteException re) { 13856 /* ignore */ 13857 } 13858 // Only a UiAutomation can set this flag and now that 13859 // it is finished we make sure it is reset to its default. 13860 mUserIsMonkey = false; 13861 } 13862 app.instrumentationWatcher = null; 13863 app.instrumentationUiAutomationConnection = null; 13864 app.instrumentationClass = null; 13865 app.instrumentationInfo = null; 13866 app.instrumentationProfileFile = null; 13867 app.instrumentationArguments = null; 13868 13869 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId, 13870 "finished inst"); 13871 } 13872 13873 public void finishInstrumentation(IApplicationThread target, 13874 int resultCode, Bundle results) { 13875 int userId = UserHandle.getCallingUserId(); 13876 // Refuse possible leaked file descriptors 13877 if (results != null && results.hasFileDescriptors()) { 13878 throw new IllegalArgumentException("File descriptors passed in Intent"); 13879 } 13880 13881 synchronized(this) { 13882 ProcessRecord app = getRecordForAppLocked(target); 13883 if (app == null) { 13884 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13885 return; 13886 } 13887 final long origId = Binder.clearCallingIdentity(); 13888 finishInstrumentationLocked(app, resultCode, results); 13889 Binder.restoreCallingIdentity(origId); 13890 } 13891 } 13892 13893 // ========================================================= 13894 // CONFIGURATION 13895 // ========================================================= 13896 13897 public ConfigurationInfo getDeviceConfigurationInfo() { 13898 ConfigurationInfo config = new ConfigurationInfo(); 13899 synchronized (this) { 13900 config.reqTouchScreen = mConfiguration.touchscreen; 13901 config.reqKeyboardType = mConfiguration.keyboard; 13902 config.reqNavigation = mConfiguration.navigation; 13903 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13904 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13905 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13906 } 13907 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13908 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13909 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13910 } 13911 config.reqGlEsVersion = GL_ES_VERSION; 13912 } 13913 return config; 13914 } 13915 13916 ActivityStack getFocusedStack() { 13917 return mStackSupervisor.getFocusedStack(); 13918 } 13919 13920 public Configuration getConfiguration() { 13921 Configuration ci; 13922 synchronized(this) { 13923 ci = new Configuration(mConfiguration); 13924 } 13925 return ci; 13926 } 13927 13928 public void updatePersistentConfiguration(Configuration values) { 13929 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13930 "updateConfiguration()"); 13931 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 13932 "updateConfiguration()"); 13933 if (values == null) { 13934 throw new NullPointerException("Configuration must not be null"); 13935 } 13936 13937 synchronized(this) { 13938 final long origId = Binder.clearCallingIdentity(); 13939 updateConfigurationLocked(values, null, true, false); 13940 Binder.restoreCallingIdentity(origId); 13941 } 13942 } 13943 13944 public void updateConfiguration(Configuration values) { 13945 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13946 "updateConfiguration()"); 13947 13948 synchronized(this) { 13949 if (values == null && mWindowManager != null) { 13950 // sentinel: fetch the current configuration from the window manager 13951 values = mWindowManager.computeNewConfiguration(); 13952 } 13953 13954 if (mWindowManager != null) { 13955 mProcessList.applyDisplaySize(mWindowManager); 13956 } 13957 13958 final long origId = Binder.clearCallingIdentity(); 13959 if (values != null) { 13960 Settings.System.clearConfiguration(values); 13961 } 13962 updateConfigurationLocked(values, null, false, false); 13963 Binder.restoreCallingIdentity(origId); 13964 } 13965 } 13966 13967 /** 13968 * Do either or both things: (1) change the current configuration, and (2) 13969 * make sure the given activity is running with the (now) current 13970 * configuration. Returns true if the activity has been left running, or 13971 * false if <var>starting</var> is being destroyed to match the new 13972 * configuration. 13973 * @param persistent TODO 13974 */ 13975 boolean updateConfigurationLocked(Configuration values, 13976 ActivityRecord starting, boolean persistent, boolean initLocale) { 13977 int changes = 0; 13978 13979 if (values != null) { 13980 Configuration newConfig = new Configuration(mConfiguration); 13981 changes = newConfig.updateFrom(values); 13982 if (changes != 0) { 13983 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13984 Slog.i(TAG, "Updating configuration to: " + values); 13985 } 13986 13987 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 13988 13989 if (values.locale != null && !initLocale) { 13990 saveLocaleLocked(values.locale, 13991 !values.locale.equals(mConfiguration.locale), 13992 values.userSetLocale); 13993 } 13994 13995 mConfigurationSeq++; 13996 if (mConfigurationSeq <= 0) { 13997 mConfigurationSeq = 1; 13998 } 13999 newConfig.seq = mConfigurationSeq; 14000 mConfiguration = newConfig; 14001 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14002 14003 final Configuration configCopy = new Configuration(mConfiguration); 14004 14005 // TODO: If our config changes, should we auto dismiss any currently 14006 // showing dialogs? 14007 mShowDialogs = shouldShowDialogs(newConfig); 14008 14009 AttributeCache ac = AttributeCache.instance(); 14010 if (ac != null) { 14011 ac.updateConfiguration(configCopy); 14012 } 14013 14014 // Make sure all resources in our process are updated 14015 // right now, so that anyone who is going to retrieve 14016 // resource values after we return will be sure to get 14017 // the new ones. This is especially important during 14018 // boot, where the first config change needs to guarantee 14019 // all resources have that config before following boot 14020 // code is executed. 14021 mSystemThread.applyConfigurationToResources(configCopy); 14022 14023 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14024 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14025 msg.obj = new Configuration(configCopy); 14026 mHandler.sendMessage(msg); 14027 } 14028 14029 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14030 ProcessRecord app = mLruProcesses.get(i); 14031 try { 14032 if (app.thread != null) { 14033 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14034 + app.processName + " new config " + mConfiguration); 14035 app.thread.scheduleConfigurationChanged(configCopy); 14036 } 14037 } catch (Exception e) { 14038 } 14039 } 14040 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14041 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14042 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14043 | Intent.FLAG_RECEIVER_FOREGROUND); 14044 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14045 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14046 Process.SYSTEM_UID, UserHandle.USER_ALL); 14047 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14048 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14049 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14050 broadcastIntentLocked(null, null, intent, 14051 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14052 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14053 } 14054 } 14055 } 14056 14057 boolean kept = true; 14058 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14059 // mainStack is null during startup. 14060 if (mainStack != null) { 14061 if (changes != 0 && starting == null) { 14062 // If the configuration changed, and the caller is not already 14063 // in the process of starting an activity, then find the top 14064 // activity to check if its configuration needs to change. 14065 starting = mainStack.topRunningActivityLocked(null); 14066 } 14067 14068 if (starting != null) { 14069 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14070 // And we need to make sure at this point that all other activities 14071 // are made visible with the correct configuration. 14072 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14073 } 14074 } 14075 14076 if (values != null && mWindowManager != null) { 14077 mWindowManager.setNewConfiguration(mConfiguration); 14078 } 14079 14080 return kept; 14081 } 14082 14083 /** 14084 * Decide based on the configuration whether we should shouw the ANR, 14085 * crash, etc dialogs. The idea is that if there is no affordnace to 14086 * press the on-screen buttons, we shouldn't show the dialog. 14087 * 14088 * A thought: SystemUI might also want to get told about this, the Power 14089 * dialog / global actions also might want different behaviors. 14090 */ 14091 private static final boolean shouldShowDialogs(Configuration config) { 14092 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14093 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14094 } 14095 14096 /** 14097 * Save the locale. You must be inside a synchronized (this) block. 14098 */ 14099 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14100 if(isDiff) { 14101 SystemProperties.set("user.language", l.getLanguage()); 14102 SystemProperties.set("user.region", l.getCountry()); 14103 } 14104 14105 if(isPersist) { 14106 SystemProperties.set("persist.sys.language", l.getLanguage()); 14107 SystemProperties.set("persist.sys.country", l.getCountry()); 14108 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14109 } 14110 } 14111 14112 @Override 14113 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14114 ActivityRecord srec = ActivityRecord.forToken(token); 14115 return srec != null && srec.task.affinity != null && 14116 srec.task.affinity.equals(destAffinity); 14117 } 14118 14119 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14120 Intent resultData) { 14121 14122 synchronized (this) { 14123 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14124 if (stack != null) { 14125 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14126 } 14127 return false; 14128 } 14129 } 14130 14131 public int getLaunchedFromUid(IBinder activityToken) { 14132 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14133 if (srec == null) { 14134 return -1; 14135 } 14136 return srec.launchedFromUid; 14137 } 14138 14139 public String getLaunchedFromPackage(IBinder activityToken) { 14140 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14141 if (srec == null) { 14142 return null; 14143 } 14144 return srec.launchedFromPackage; 14145 } 14146 14147 // ========================================================= 14148 // LIFETIME MANAGEMENT 14149 // ========================================================= 14150 14151 // Returns which broadcast queue the app is the current [or imminent] receiver 14152 // on, or 'null' if the app is not an active broadcast recipient. 14153 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14154 BroadcastRecord r = app.curReceiver; 14155 if (r != null) { 14156 return r.queue; 14157 } 14158 14159 // It's not the current receiver, but it might be starting up to become one 14160 synchronized (this) { 14161 for (BroadcastQueue queue : mBroadcastQueues) { 14162 r = queue.mPendingBroadcast; 14163 if (r != null && r.curApp == app) { 14164 // found it; report which queue it's in 14165 return queue; 14166 } 14167 } 14168 } 14169 14170 return null; 14171 } 14172 14173 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14174 boolean doingAll, long now) { 14175 if (mAdjSeq == app.adjSeq) { 14176 // This adjustment has already been computed. 14177 return app.curRawAdj; 14178 } 14179 14180 if (app.thread == null) { 14181 app.adjSeq = mAdjSeq; 14182 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14183 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14184 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14185 } 14186 14187 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14188 app.adjSource = null; 14189 app.adjTarget = null; 14190 app.empty = false; 14191 app.cached = false; 14192 14193 final int activitiesSize = app.activities.size(); 14194 14195 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14196 // The max adjustment doesn't allow this app to be anything 14197 // below foreground, so it is not worth doing work for it. 14198 app.adjType = "fixed"; 14199 app.adjSeq = mAdjSeq; 14200 app.curRawAdj = app.maxAdj; 14201 app.foregroundActivities = false; 14202 app.keeping = true; 14203 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14204 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14205 // System process can do UI, and when they do we want to have 14206 // them trim their memory after the user leaves the UI. To 14207 // facilitate this, here we need to determine whether or not it 14208 // is currently showing UI. 14209 app.systemNoUi = true; 14210 if (app == TOP_APP) { 14211 app.systemNoUi = false; 14212 } else if (activitiesSize > 0) { 14213 for (int j = 0; j < activitiesSize; j++) { 14214 final ActivityRecord r = app.activities.get(j); 14215 if (r.visible) { 14216 app.systemNoUi = false; 14217 } 14218 } 14219 } 14220 if (!app.systemNoUi) { 14221 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14222 } 14223 return (app.curAdj=app.maxAdj); 14224 } 14225 14226 app.keeping = false; 14227 app.systemNoUi = false; 14228 14229 // Determine the importance of the process, starting with most 14230 // important to least, and assign an appropriate OOM adjustment. 14231 int adj; 14232 int schedGroup; 14233 int procState; 14234 boolean foregroundActivities = false; 14235 boolean interesting = false; 14236 BroadcastQueue queue; 14237 if (app == TOP_APP) { 14238 // The last app on the list is the foreground app. 14239 adj = ProcessList.FOREGROUND_APP_ADJ; 14240 schedGroup = Process.THREAD_GROUP_DEFAULT; 14241 app.adjType = "top-activity"; 14242 foregroundActivities = true; 14243 interesting = true; 14244 procState = ActivityManager.PROCESS_STATE_TOP; 14245 } else if (app.instrumentationClass != null) { 14246 // Don't want to kill running instrumentation. 14247 adj = ProcessList.FOREGROUND_APP_ADJ; 14248 schedGroup = Process.THREAD_GROUP_DEFAULT; 14249 app.adjType = "instrumentation"; 14250 interesting = true; 14251 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14252 } else if ((queue = isReceivingBroadcast(app)) != null) { 14253 // An app that is currently receiving a broadcast also 14254 // counts as being in the foreground for OOM killer purposes. 14255 // It's placed in a sched group based on the nature of the 14256 // broadcast as reflected by which queue it's active in. 14257 adj = ProcessList.FOREGROUND_APP_ADJ; 14258 schedGroup = (queue == mFgBroadcastQueue) 14259 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14260 app.adjType = "broadcast"; 14261 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14262 } else if (app.executingServices.size() > 0) { 14263 // An app that is currently executing a service callback also 14264 // counts as being in the foreground. 14265 adj = ProcessList.FOREGROUND_APP_ADJ; 14266 schedGroup = app.execServicesFg ? 14267 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14268 app.adjType = "exec-service"; 14269 procState = ActivityManager.PROCESS_STATE_SERVICE; 14270 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14271 } else { 14272 // As far as we know the process is empty. We may change our mind later. 14273 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14274 // At this point we don't actually know the adjustment. Use the cached adj 14275 // value that the caller wants us to. 14276 adj = cachedAdj; 14277 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14278 app.cached = true; 14279 app.empty = true; 14280 app.adjType = "cch-empty"; 14281 } 14282 14283 // Examine all activities if not already foreground. 14284 if (!foregroundActivities && activitiesSize > 0) { 14285 for (int j = 0; j < activitiesSize; j++) { 14286 final ActivityRecord r = app.activities.get(j); 14287 if (r.app != app) { 14288 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14289 + app + "?!?"); 14290 continue; 14291 } 14292 if (r.visible) { 14293 // App has a visible activity; only upgrade adjustment. 14294 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14295 adj = ProcessList.VISIBLE_APP_ADJ; 14296 app.adjType = "visible"; 14297 } 14298 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14299 procState = ActivityManager.PROCESS_STATE_TOP; 14300 } 14301 schedGroup = Process.THREAD_GROUP_DEFAULT; 14302 app.cached = false; 14303 app.empty = false; 14304 foregroundActivities = true; 14305 break; 14306 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14307 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14308 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14309 app.adjType = "pausing"; 14310 } 14311 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14312 procState = ActivityManager.PROCESS_STATE_TOP; 14313 } 14314 schedGroup = Process.THREAD_GROUP_DEFAULT; 14315 app.cached = false; 14316 app.empty = false; 14317 foregroundActivities = true; 14318 } else if (r.state == ActivityState.STOPPING) { 14319 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14320 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14321 app.adjType = "stopping"; 14322 } 14323 // For the process state, we will at this point consider the 14324 // process to be cached. It will be cached either as an activity 14325 // or empty depending on whether the activity is finishing. We do 14326 // this so that we can treat the process as cached for purposes of 14327 // memory trimming (determing current memory level, trim command to 14328 // send to process) since there can be an arbitrary number of stopping 14329 // processes and they should soon all go into the cached state. 14330 if (!r.finishing) { 14331 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14332 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14333 } 14334 } 14335 app.cached = false; 14336 app.empty = false; 14337 foregroundActivities = true; 14338 } else { 14339 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14340 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14341 app.adjType = "cch-act"; 14342 } 14343 } 14344 } 14345 } 14346 14347 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14348 if (app.foregroundServices) { 14349 // The user is aware of this app, so make it visible. 14350 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14351 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14352 app.cached = false; 14353 app.adjType = "fg-service"; 14354 schedGroup = Process.THREAD_GROUP_DEFAULT; 14355 } else if (app.forcingToForeground != null) { 14356 // The user is aware of this app, so make it visible. 14357 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14358 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14359 app.cached = false; 14360 app.adjType = "force-fg"; 14361 app.adjSource = app.forcingToForeground; 14362 schedGroup = Process.THREAD_GROUP_DEFAULT; 14363 } 14364 } 14365 14366 if (app.foregroundServices) { 14367 interesting = true; 14368 } 14369 14370 if (app == mHeavyWeightProcess) { 14371 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14372 // We don't want to kill the current heavy-weight process. 14373 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14374 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14375 app.cached = false; 14376 app.adjType = "heavy"; 14377 } 14378 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14379 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14380 } 14381 } 14382 14383 if (app == mHomeProcess) { 14384 if (adj > ProcessList.HOME_APP_ADJ) { 14385 // This process is hosting what we currently consider to be the 14386 // home app, so we don't want to let it go into the background. 14387 adj = ProcessList.HOME_APP_ADJ; 14388 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14389 app.cached = false; 14390 app.adjType = "home"; 14391 } 14392 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14393 procState = ActivityManager.PROCESS_STATE_HOME; 14394 } 14395 } 14396 14397 if (app == mPreviousProcess && app.activities.size() > 0) { 14398 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14399 // This was the previous process that showed UI to the user. 14400 // We want to try to keep it around more aggressively, to give 14401 // a good experience around switching between two apps. 14402 adj = ProcessList.PREVIOUS_APP_ADJ; 14403 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14404 app.cached = false; 14405 app.adjType = "previous"; 14406 } 14407 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14408 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14409 } 14410 } 14411 14412 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14413 + " reason=" + app.adjType); 14414 14415 // By default, we use the computed adjustment. It may be changed if 14416 // there are applications dependent on our services or providers, but 14417 // this gives us a baseline and makes sure we don't get into an 14418 // infinite recursion. 14419 app.adjSeq = mAdjSeq; 14420 app.curRawAdj = adj; 14421 app.hasStartedServices = false; 14422 14423 if (mBackupTarget != null && app == mBackupTarget.app) { 14424 // If possible we want to avoid killing apps while they're being backed up 14425 if (adj > ProcessList.BACKUP_APP_ADJ) { 14426 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14427 adj = ProcessList.BACKUP_APP_ADJ; 14428 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14429 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14430 } 14431 app.adjType = "backup"; 14432 app.cached = false; 14433 } 14434 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14435 procState = ActivityManager.PROCESS_STATE_BACKUP; 14436 } 14437 } 14438 14439 boolean mayBeTop = false; 14440 14441 for (int is = app.services.size()-1; 14442 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14443 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14444 || procState > ActivityManager.PROCESS_STATE_TOP); 14445 is--) { 14446 ServiceRecord s = app.services.valueAt(is); 14447 if (s.startRequested) { 14448 app.hasStartedServices = true; 14449 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14450 procState = ActivityManager.PROCESS_STATE_SERVICE; 14451 } 14452 if (app.hasShownUi && app != mHomeProcess) { 14453 // If this process has shown some UI, let it immediately 14454 // go to the LRU list because it may be pretty heavy with 14455 // UI stuff. We'll tag it with a label just to help 14456 // debug and understand what is going on. 14457 if (adj > ProcessList.SERVICE_ADJ) { 14458 app.adjType = "cch-started-ui-services"; 14459 } 14460 } else { 14461 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14462 // This service has seen some activity within 14463 // recent memory, so we will keep its process ahead 14464 // of the background processes. 14465 if (adj > ProcessList.SERVICE_ADJ) { 14466 adj = ProcessList.SERVICE_ADJ; 14467 app.adjType = "started-services"; 14468 app.cached = false; 14469 } 14470 } 14471 // If we have let the service slide into the background 14472 // state, still have some text describing what it is doing 14473 // even though the service no longer has an impact. 14474 if (adj > ProcessList.SERVICE_ADJ) { 14475 app.adjType = "cch-started-services"; 14476 } 14477 } 14478 // Don't kill this process because it is doing work; it 14479 // has said it is doing work. 14480 app.keeping = true; 14481 } 14482 for (int conni = s.connections.size()-1; 14483 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14484 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14485 || procState > ActivityManager.PROCESS_STATE_TOP); 14486 conni--) { 14487 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14488 for (int i = 0; 14489 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14490 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14491 || procState > ActivityManager.PROCESS_STATE_TOP); 14492 i++) { 14493 // XXX should compute this based on the max of 14494 // all connected clients. 14495 ConnectionRecord cr = clist.get(i); 14496 if (cr.binding.client == app) { 14497 // Binding to ourself is not interesting. 14498 continue; 14499 } 14500 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14501 ProcessRecord client = cr.binding.client; 14502 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14503 TOP_APP, doingAll, now); 14504 int clientProcState = client.curProcState; 14505 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14506 // If the other app is cached for any reason, for purposes here 14507 // we are going to consider it empty. The specific cached state 14508 // doesn't propagate except under certain conditions. 14509 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14510 } 14511 String adjType = null; 14512 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14513 // Not doing bind OOM management, so treat 14514 // this guy more like a started service. 14515 if (app.hasShownUi && app != mHomeProcess) { 14516 // If this process has shown some UI, let it immediately 14517 // go to the LRU list because it may be pretty heavy with 14518 // UI stuff. We'll tag it with a label just to help 14519 // debug and understand what is going on. 14520 if (adj > clientAdj) { 14521 adjType = "cch-bound-ui-services"; 14522 } 14523 app.cached = false; 14524 clientAdj = adj; 14525 clientProcState = procState; 14526 } else { 14527 if (now >= (s.lastActivity 14528 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14529 // This service has not seen activity within 14530 // recent memory, so allow it to drop to the 14531 // LRU list if there is no other reason to keep 14532 // it around. We'll also tag it with a label just 14533 // to help debug and undertand what is going on. 14534 if (adj > clientAdj) { 14535 adjType = "cch-bound-services"; 14536 } 14537 clientAdj = adj; 14538 } 14539 } 14540 } 14541 if (adj > clientAdj) { 14542 // If this process has recently shown UI, and 14543 // the process that is binding to it is less 14544 // important than being visible, then we don't 14545 // care about the binding as much as we care 14546 // about letting this process get into the LRU 14547 // list to be killed and restarted if needed for 14548 // memory. 14549 if (app.hasShownUi && app != mHomeProcess 14550 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14551 adjType = "cch-bound-ui-services"; 14552 } else { 14553 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14554 |Context.BIND_IMPORTANT)) != 0) { 14555 adj = clientAdj; 14556 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14557 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14558 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14559 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14560 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14561 adj = clientAdj; 14562 } else { 14563 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14564 adj = ProcessList.VISIBLE_APP_ADJ; 14565 } 14566 } 14567 if (!client.cached) { 14568 app.cached = false; 14569 } 14570 if (client.keeping) { 14571 app.keeping = true; 14572 } 14573 adjType = "service"; 14574 } 14575 } 14576 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14577 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14578 schedGroup = Process.THREAD_GROUP_DEFAULT; 14579 } 14580 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14581 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14582 // Special handling of clients who are in the top state. 14583 // We *may* want to consider this process to be in the 14584 // top state as well, but only if there is not another 14585 // reason for it to be running. Being on the top is a 14586 // special state, meaning you are specifically running 14587 // for the current top app. If the process is already 14588 // running in the background for some other reason, it 14589 // is more important to continue considering it to be 14590 // in the background state. 14591 mayBeTop = true; 14592 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14593 } else { 14594 // Special handling for above-top states (persistent 14595 // processes). These should not bring the current process 14596 // into the top state, since they are not on top. Instead 14597 // give them the best state after that. 14598 clientProcState = 14599 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14600 } 14601 } 14602 } else { 14603 if (clientProcState < 14604 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14605 clientProcState = 14606 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14607 } 14608 } 14609 if (procState > clientProcState) { 14610 procState = clientProcState; 14611 } 14612 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14613 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14614 app.pendingUiClean = true; 14615 } 14616 if (adjType != null) { 14617 app.adjType = adjType; 14618 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14619 .REASON_SERVICE_IN_USE; 14620 app.adjSource = cr.binding.client; 14621 app.adjSourceOom = clientAdj; 14622 app.adjTarget = s.name; 14623 } 14624 } 14625 final ActivityRecord a = cr.activity; 14626 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14627 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14628 (a.visible || a.state == ActivityState.RESUMED 14629 || a.state == ActivityState.PAUSING)) { 14630 adj = ProcessList.FOREGROUND_APP_ADJ; 14631 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14632 schedGroup = Process.THREAD_GROUP_DEFAULT; 14633 } 14634 app.cached = false; 14635 app.adjType = "service"; 14636 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14637 .REASON_SERVICE_IN_USE; 14638 app.adjSource = a; 14639 app.adjSourceOom = adj; 14640 app.adjTarget = s.name; 14641 } 14642 } 14643 } 14644 } 14645 } 14646 14647 for (int provi = app.pubProviders.size()-1; 14648 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14649 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14650 || procState > ActivityManager.PROCESS_STATE_TOP); 14651 provi--) { 14652 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14653 for (int i = cpr.connections.size()-1; 14654 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14655 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14656 || procState > ActivityManager.PROCESS_STATE_TOP); 14657 i--) { 14658 ContentProviderConnection conn = cpr.connections.get(i); 14659 ProcessRecord client = conn.client; 14660 if (client == app) { 14661 // Being our own client is not interesting. 14662 continue; 14663 } 14664 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14665 int clientProcState = client.curProcState; 14666 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14667 // If the other app is cached for any reason, for purposes here 14668 // we are going to consider it empty. 14669 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14670 } 14671 if (adj > clientAdj) { 14672 if (app.hasShownUi && app != mHomeProcess 14673 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14674 app.adjType = "cch-ui-provider"; 14675 } else { 14676 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14677 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14678 app.adjType = "provider"; 14679 } 14680 app.cached &= client.cached; 14681 app.keeping |= client.keeping; 14682 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14683 .REASON_PROVIDER_IN_USE; 14684 app.adjSource = client; 14685 app.adjSourceOom = clientAdj; 14686 app.adjTarget = cpr.name; 14687 } 14688 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14689 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14690 // Special handling of clients who are in the top state. 14691 // We *may* want to consider this process to be in the 14692 // top state as well, but only if there is not another 14693 // reason for it to be running. Being on the top is a 14694 // special state, meaning you are specifically running 14695 // for the current top app. If the process is already 14696 // running in the background for some other reason, it 14697 // is more important to continue considering it to be 14698 // in the background state. 14699 mayBeTop = true; 14700 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14701 } else { 14702 // Special handling for above-top states (persistent 14703 // processes). These should not bring the current process 14704 // into the top state, since they are not on top. Instead 14705 // give them the best state after that. 14706 clientProcState = 14707 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14708 } 14709 } 14710 if (procState > clientProcState) { 14711 procState = clientProcState; 14712 } 14713 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14714 schedGroup = Process.THREAD_GROUP_DEFAULT; 14715 } 14716 } 14717 // If the provider has external (non-framework) process 14718 // dependencies, ensure that its adjustment is at least 14719 // FOREGROUND_APP_ADJ. 14720 if (cpr.hasExternalProcessHandles()) { 14721 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14722 adj = ProcessList.FOREGROUND_APP_ADJ; 14723 schedGroup = Process.THREAD_GROUP_DEFAULT; 14724 app.cached = false; 14725 app.keeping = true; 14726 app.adjType = "provider"; 14727 app.adjTarget = cpr.name; 14728 } 14729 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14730 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14731 } 14732 } 14733 } 14734 14735 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14736 // A client of one of our services or providers is in the top state. We 14737 // *may* want to be in the top state, but not if we are already running in 14738 // the background for some other reason. For the decision here, we are going 14739 // to pick out a few specific states that we want to remain in when a client 14740 // is top (states that tend to be longer-term) and otherwise allow it to go 14741 // to the top state. 14742 switch (procState) { 14743 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14744 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14745 case ActivityManager.PROCESS_STATE_SERVICE: 14746 // These all are longer-term states, so pull them up to the top 14747 // of the background states, but not all the way to the top state. 14748 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14749 break; 14750 default: 14751 // Otherwise, top is a better choice, so take it. 14752 procState = ActivityManager.PROCESS_STATE_TOP; 14753 break; 14754 } 14755 } 14756 14757 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14758 // This is a cached process, but with client activities. Mark it so. 14759 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14760 app.adjType = "cch-client-act"; 14761 } 14762 14763 if (adj == ProcessList.SERVICE_ADJ) { 14764 if (doingAll) { 14765 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14766 mNewNumServiceProcs++; 14767 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14768 if (!app.serviceb) { 14769 // This service isn't far enough down on the LRU list to 14770 // normally be a B service, but if we are low on RAM and it 14771 // is large we want to force it down since we would prefer to 14772 // keep launcher over it. 14773 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 14774 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 14775 app.serviceHighRam = true; 14776 app.serviceb = true; 14777 //Slog.i(TAG, "ADJ " + app + " high ram!"); 14778 } else { 14779 mNewNumAServiceProcs++; 14780 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 14781 } 14782 } else { 14783 app.serviceHighRam = false; 14784 } 14785 } 14786 if (app.serviceb) { 14787 adj = ProcessList.SERVICE_B_ADJ; 14788 } 14789 } 14790 14791 app.curRawAdj = adj; 14792 14793 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14794 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14795 if (adj > app.maxAdj) { 14796 adj = app.maxAdj; 14797 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14798 schedGroup = Process.THREAD_GROUP_DEFAULT; 14799 } 14800 } 14801 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 14802 app.keeping = true; 14803 } 14804 14805 // Do final modification to adj. Everything we do between here and applying 14806 // the final setAdj must be done in this function, because we will also use 14807 // it when computing the final cached adj later. Note that we don't need to 14808 // worry about this for max adj above, since max adj will always be used to 14809 // keep it out of the cached vaues. 14810 adj = app.modifyRawOomAdj(adj); 14811 14812 app.curProcState = procState; 14813 14814 int importance = app.memImportance; 14815 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14816 app.curAdj = adj; 14817 app.curSchedGroup = schedGroup; 14818 if (!interesting) { 14819 // For this reporting, if there is not something explicitly 14820 // interesting in this process then we will push it to the 14821 // background importance. 14822 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14823 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 14824 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14825 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14826 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14827 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14828 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14829 } else if (adj >= ProcessList.SERVICE_ADJ) { 14830 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14831 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14832 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14833 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14834 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14835 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14836 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14837 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14838 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14839 } else { 14840 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14841 } 14842 } 14843 14844 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14845 if (foregroundActivities != app.foregroundActivities) { 14846 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14847 } 14848 if (changes != 0) { 14849 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14850 app.memImportance = importance; 14851 app.foregroundActivities = foregroundActivities; 14852 int i = mPendingProcessChanges.size()-1; 14853 ProcessChangeItem item = null; 14854 while (i >= 0) { 14855 item = mPendingProcessChanges.get(i); 14856 if (item.pid == app.pid) { 14857 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14858 break; 14859 } 14860 i--; 14861 } 14862 if (i < 0) { 14863 // No existing item in pending changes; need a new one. 14864 final int NA = mAvailProcessChanges.size(); 14865 if (NA > 0) { 14866 item = mAvailProcessChanges.remove(NA-1); 14867 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14868 } else { 14869 item = new ProcessChangeItem(); 14870 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14871 } 14872 item.changes = 0; 14873 item.pid = app.pid; 14874 item.uid = app.info.uid; 14875 if (mPendingProcessChanges.size() == 0) { 14876 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14877 "*** Enqueueing dispatch processes changed!"); 14878 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14879 } 14880 mPendingProcessChanges.add(item); 14881 } 14882 item.changes |= changes; 14883 item.importance = importance; 14884 item.foregroundActivities = foregroundActivities; 14885 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14886 + Integer.toHexString(System.identityHashCode(item)) 14887 + " " + app.toShortString() + ": changes=" + item.changes 14888 + " importance=" + item.importance 14889 + " foreground=" + item.foregroundActivities 14890 + " type=" + app.adjType + " source=" + app.adjSource 14891 + " target=" + app.adjTarget); 14892 } 14893 14894 return app.curRawAdj; 14895 } 14896 14897 /** 14898 * Schedule PSS collection of a process. 14899 */ 14900 void requestPssLocked(ProcessRecord proc, int procState) { 14901 if (mPendingPssProcesses.contains(proc)) { 14902 return; 14903 } 14904 if (mPendingPssProcesses.size() == 0) { 14905 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14906 } 14907 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 14908 proc.pssProcState = procState; 14909 mPendingPssProcesses.add(proc); 14910 } 14911 14912 /** 14913 * Schedule PSS collection of all processes. 14914 */ 14915 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 14916 if (!always) { 14917 if (now < (mLastFullPssTime + 14918 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 14919 return; 14920 } 14921 } 14922 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 14923 mLastFullPssTime = now; 14924 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 14925 mPendingPssProcesses.clear(); 14926 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14927 ProcessRecord app = mLruProcesses.get(i); 14928 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 14929 app.pssProcState = app.setProcState; 14930 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 14931 mSleeping, now); 14932 mPendingPssProcesses.add(app); 14933 } 14934 } 14935 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14936 } 14937 14938 /** 14939 * Ask a given process to GC right now. 14940 */ 14941 final void performAppGcLocked(ProcessRecord app) { 14942 try { 14943 app.lastRequestedGc = SystemClock.uptimeMillis(); 14944 if (app.thread != null) { 14945 if (app.reportLowMemory) { 14946 app.reportLowMemory = false; 14947 app.thread.scheduleLowMemory(); 14948 } else { 14949 app.thread.processInBackground(); 14950 } 14951 } 14952 } catch (Exception e) { 14953 // whatever. 14954 } 14955 } 14956 14957 /** 14958 * Returns true if things are idle enough to perform GCs. 14959 */ 14960 private final boolean canGcNowLocked() { 14961 boolean processingBroadcasts = false; 14962 for (BroadcastQueue q : mBroadcastQueues) { 14963 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 14964 processingBroadcasts = true; 14965 } 14966 } 14967 return !processingBroadcasts 14968 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 14969 } 14970 14971 /** 14972 * Perform GCs on all processes that are waiting for it, but only 14973 * if things are idle. 14974 */ 14975 final void performAppGcsLocked() { 14976 final int N = mProcessesToGc.size(); 14977 if (N <= 0) { 14978 return; 14979 } 14980 if (canGcNowLocked()) { 14981 while (mProcessesToGc.size() > 0) { 14982 ProcessRecord proc = mProcessesToGc.remove(0); 14983 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 14984 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 14985 <= SystemClock.uptimeMillis()) { 14986 // To avoid spamming the system, we will GC processes one 14987 // at a time, waiting a few seconds between each. 14988 performAppGcLocked(proc); 14989 scheduleAppGcsLocked(); 14990 return; 14991 } else { 14992 // It hasn't been long enough since we last GCed this 14993 // process... put it in the list to wait for its time. 14994 addProcessToGcListLocked(proc); 14995 break; 14996 } 14997 } 14998 } 14999 15000 scheduleAppGcsLocked(); 15001 } 15002 } 15003 15004 /** 15005 * If all looks good, perform GCs on all processes waiting for them. 15006 */ 15007 final void performAppGcsIfAppropriateLocked() { 15008 if (canGcNowLocked()) { 15009 performAppGcsLocked(); 15010 return; 15011 } 15012 // Still not idle, wait some more. 15013 scheduleAppGcsLocked(); 15014 } 15015 15016 /** 15017 * Schedule the execution of all pending app GCs. 15018 */ 15019 final void scheduleAppGcsLocked() { 15020 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15021 15022 if (mProcessesToGc.size() > 0) { 15023 // Schedule a GC for the time to the next process. 15024 ProcessRecord proc = mProcessesToGc.get(0); 15025 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15026 15027 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15028 long now = SystemClock.uptimeMillis(); 15029 if (when < (now+GC_TIMEOUT)) { 15030 when = now + GC_TIMEOUT; 15031 } 15032 mHandler.sendMessageAtTime(msg, when); 15033 } 15034 } 15035 15036 /** 15037 * Add a process to the array of processes waiting to be GCed. Keeps the 15038 * list in sorted order by the last GC time. The process can't already be 15039 * on the list. 15040 */ 15041 final void addProcessToGcListLocked(ProcessRecord proc) { 15042 boolean added = false; 15043 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15044 if (mProcessesToGc.get(i).lastRequestedGc < 15045 proc.lastRequestedGc) { 15046 added = true; 15047 mProcessesToGc.add(i+1, proc); 15048 break; 15049 } 15050 } 15051 if (!added) { 15052 mProcessesToGc.add(0, proc); 15053 } 15054 } 15055 15056 /** 15057 * Set up to ask a process to GC itself. This will either do it 15058 * immediately, or put it on the list of processes to gc the next 15059 * time things are idle. 15060 */ 15061 final void scheduleAppGcLocked(ProcessRecord app) { 15062 long now = SystemClock.uptimeMillis(); 15063 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15064 return; 15065 } 15066 if (!mProcessesToGc.contains(app)) { 15067 addProcessToGcListLocked(app); 15068 scheduleAppGcsLocked(); 15069 } 15070 } 15071 15072 final void checkExcessivePowerUsageLocked(boolean doKills) { 15073 updateCpuStatsNow(); 15074 15075 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15076 boolean doWakeKills = doKills; 15077 boolean doCpuKills = doKills; 15078 if (mLastPowerCheckRealtime == 0) { 15079 doWakeKills = false; 15080 } 15081 if (mLastPowerCheckUptime == 0) { 15082 doCpuKills = false; 15083 } 15084 if (stats.isScreenOn()) { 15085 doWakeKills = false; 15086 } 15087 final long curRealtime = SystemClock.elapsedRealtime(); 15088 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15089 final long curUptime = SystemClock.uptimeMillis(); 15090 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15091 mLastPowerCheckRealtime = curRealtime; 15092 mLastPowerCheckUptime = curUptime; 15093 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15094 doWakeKills = false; 15095 } 15096 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15097 doCpuKills = false; 15098 } 15099 int i = mLruProcesses.size(); 15100 while (i > 0) { 15101 i--; 15102 ProcessRecord app = mLruProcesses.get(i); 15103 if (!app.keeping) { 15104 long wtime; 15105 synchronized (stats) { 15106 wtime = stats.getProcessWakeTime(app.info.uid, 15107 app.pid, curRealtime); 15108 } 15109 long wtimeUsed = wtime - app.lastWakeTime; 15110 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15111 if (DEBUG_POWER) { 15112 StringBuilder sb = new StringBuilder(128); 15113 sb.append("Wake for "); 15114 app.toShortString(sb); 15115 sb.append(": over "); 15116 TimeUtils.formatDuration(realtimeSince, sb); 15117 sb.append(" used "); 15118 TimeUtils.formatDuration(wtimeUsed, sb); 15119 sb.append(" ("); 15120 sb.append((wtimeUsed*100)/realtimeSince); 15121 sb.append("%)"); 15122 Slog.i(TAG, sb.toString()); 15123 sb.setLength(0); 15124 sb.append("CPU for "); 15125 app.toShortString(sb); 15126 sb.append(": over "); 15127 TimeUtils.formatDuration(uptimeSince, sb); 15128 sb.append(" used "); 15129 TimeUtils.formatDuration(cputimeUsed, sb); 15130 sb.append(" ("); 15131 sb.append((cputimeUsed*100)/uptimeSince); 15132 sb.append("%)"); 15133 Slog.i(TAG, sb.toString()); 15134 } 15135 // If a process has held a wake lock for more 15136 // than 50% of the time during this period, 15137 // that sounds bad. Kill! 15138 if (doWakeKills && realtimeSince > 0 15139 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15140 synchronized (stats) { 15141 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15142 realtimeSince, wtimeUsed); 15143 } 15144 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15145 + " during " + realtimeSince); 15146 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15147 } else if (doCpuKills && uptimeSince > 0 15148 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15149 synchronized (stats) { 15150 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15151 uptimeSince, cputimeUsed); 15152 } 15153 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15154 + " during " + uptimeSince); 15155 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15156 } else { 15157 app.lastWakeTime = wtime; 15158 app.lastCpuTime = app.curCpuTime; 15159 } 15160 } 15161 } 15162 } 15163 15164 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15165 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15166 boolean success = true; 15167 15168 if (app.curRawAdj != app.setRawAdj) { 15169 if (wasKeeping && !app.keeping) { 15170 // This app is no longer something we want to keep. Note 15171 // its current wake lock time to later know to kill it if 15172 // it is not behaving well. 15173 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15174 synchronized (stats) { 15175 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15176 app.pid, SystemClock.elapsedRealtime()); 15177 } 15178 app.lastCpuTime = app.curCpuTime; 15179 } 15180 15181 app.setRawAdj = app.curRawAdj; 15182 } 15183 15184 if (app.curAdj != app.setAdj) { 15185 ProcessList.setOomAdj(app.pid, app.curAdj); 15186 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15187 TAG, "Set " + app.pid + " " + app.processName + 15188 " adj " + app.curAdj + ": " + app.adjType); 15189 app.setAdj = app.curAdj; 15190 } 15191 15192 if (app.setSchedGroup != app.curSchedGroup) { 15193 app.setSchedGroup = app.curSchedGroup; 15194 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15195 "Setting process group of " + app.processName 15196 + " to " + app.curSchedGroup); 15197 if (app.waitingToKill != null && 15198 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15199 killUnneededProcessLocked(app, app.waitingToKill); 15200 success = false; 15201 } else { 15202 if (true) { 15203 long oldId = Binder.clearCallingIdentity(); 15204 try { 15205 Process.setProcessGroup(app.pid, app.curSchedGroup); 15206 } catch (Exception e) { 15207 Slog.w(TAG, "Failed setting process group of " + app.pid 15208 + " to " + app.curSchedGroup); 15209 e.printStackTrace(); 15210 } finally { 15211 Binder.restoreCallingIdentity(oldId); 15212 } 15213 } else { 15214 if (app.thread != null) { 15215 try { 15216 app.thread.setSchedulingGroup(app.curSchedGroup); 15217 } catch (RemoteException e) { 15218 } 15219 } 15220 } 15221 Process.setSwappiness(app.pid, 15222 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15223 } 15224 } 15225 if (app.repProcState != app.curProcState) { 15226 app.repProcState = app.curProcState; 15227 if (!reportingProcessState && app.thread != null) { 15228 try { 15229 if (false) { 15230 //RuntimeException h = new RuntimeException("here"); 15231 Slog.i(TAG, "Sending new process state " + app.repProcState 15232 + " to " + app /*, h*/); 15233 } 15234 app.thread.setProcessState(app.repProcState); 15235 } catch (RemoteException e) { 15236 } 15237 } 15238 } 15239 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15240 app.setProcState)) { 15241 app.lastStateTime = now; 15242 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15243 mSleeping, now); 15244 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15245 + ProcessList.makeProcStateString(app.setProcState) + " to " 15246 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15247 + (app.nextPssTime-now) + ": " + app); 15248 } else { 15249 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15250 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15251 requestPssLocked(app, app.setProcState); 15252 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15253 mSleeping, now); 15254 } else if (false && DEBUG_PSS) { 15255 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15256 } 15257 } 15258 if (app.setProcState != app.curProcState) { 15259 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15260 "Proc state change of " + app.processName 15261 + " to " + app.curProcState); 15262 app.setProcState = app.curProcState; 15263 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15264 app.notCachedSinceIdle = false; 15265 } 15266 if (!doingAll) { 15267 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15268 } else { 15269 app.procStateChanged = true; 15270 } 15271 } 15272 return success; 15273 } 15274 15275 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15276 if (proc.thread != null && proc.baseProcessTracker != null) { 15277 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15278 } 15279 } 15280 15281 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15282 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15283 if (app.thread == null) { 15284 return false; 15285 } 15286 15287 final boolean wasKeeping = app.keeping; 15288 15289 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15290 15291 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15292 reportingProcessState, now); 15293 } 15294 15295 private final ActivityRecord resumedAppLocked() { 15296 return mStackSupervisor.resumedAppLocked(); 15297 } 15298 15299 final boolean updateOomAdjLocked(ProcessRecord app) { 15300 return updateOomAdjLocked(app, false); 15301 } 15302 15303 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15304 final ActivityRecord TOP_ACT = resumedAppLocked(); 15305 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15306 final boolean wasCached = app.cached; 15307 15308 mAdjSeq++; 15309 15310 // This is the desired cached adjusment we want to tell it to use. 15311 // If our app is currently cached, we know it, and that is it. Otherwise, 15312 // we don't know it yet, and it needs to now be cached we will then 15313 // need to do a complete oom adj. 15314 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15315 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15316 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15317 SystemClock.uptimeMillis()); 15318 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15319 // Changed to/from cached state, so apps after it in the LRU 15320 // list may also be changed. 15321 updateOomAdjLocked(); 15322 } 15323 return success; 15324 } 15325 15326 final void updateOomAdjLocked() { 15327 final ActivityRecord TOP_ACT = resumedAppLocked(); 15328 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15329 final long now = SystemClock.uptimeMillis(); 15330 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15331 final int N = mLruProcesses.size(); 15332 15333 if (false) { 15334 RuntimeException e = new RuntimeException(); 15335 e.fillInStackTrace(); 15336 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15337 } 15338 15339 mAdjSeq++; 15340 mNewNumServiceProcs = 0; 15341 mNewNumAServiceProcs = 0; 15342 15343 final int emptyProcessLimit; 15344 final int cachedProcessLimit; 15345 if (mProcessLimit <= 0) { 15346 emptyProcessLimit = cachedProcessLimit = 0; 15347 } else if (mProcessLimit == 1) { 15348 emptyProcessLimit = 1; 15349 cachedProcessLimit = 0; 15350 } else { 15351 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15352 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15353 } 15354 15355 // Let's determine how many processes we have running vs. 15356 // how many slots we have for background processes; we may want 15357 // to put multiple processes in a slot of there are enough of 15358 // them. 15359 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15360 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15361 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15362 if (numEmptyProcs > cachedProcessLimit) { 15363 // If there are more empty processes than our limit on cached 15364 // processes, then use the cached process limit for the factor. 15365 // This ensures that the really old empty processes get pushed 15366 // down to the bottom, so if we are running low on memory we will 15367 // have a better chance at keeping around more cached processes 15368 // instead of a gazillion empty processes. 15369 numEmptyProcs = cachedProcessLimit; 15370 } 15371 int emptyFactor = numEmptyProcs/numSlots; 15372 if (emptyFactor < 1) emptyFactor = 1; 15373 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15374 if (cachedFactor < 1) cachedFactor = 1; 15375 int stepCached = 0; 15376 int stepEmpty = 0; 15377 int numCached = 0; 15378 int numEmpty = 0; 15379 int numTrimming = 0; 15380 15381 mNumNonCachedProcs = 0; 15382 mNumCachedHiddenProcs = 0; 15383 15384 // First update the OOM adjustment for each of the 15385 // application processes based on their current state. 15386 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15387 int nextCachedAdj = curCachedAdj+1; 15388 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15389 int nextEmptyAdj = curEmptyAdj+2; 15390 for (int i=N-1; i>=0; i--) { 15391 ProcessRecord app = mLruProcesses.get(i); 15392 if (!app.killedByAm && app.thread != null) { 15393 app.procStateChanged = false; 15394 final boolean wasKeeping = app.keeping; 15395 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15396 15397 // If we haven't yet assigned the final cached adj 15398 // to the process, do that now. 15399 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15400 switch (app.curProcState) { 15401 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15402 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15403 // This process is a cached process holding activities... 15404 // assign it the next cached value for that type, and then 15405 // step that cached level. 15406 app.curRawAdj = curCachedAdj; 15407 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15408 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15409 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15410 + ")"); 15411 if (curCachedAdj != nextCachedAdj) { 15412 stepCached++; 15413 if (stepCached >= cachedFactor) { 15414 stepCached = 0; 15415 curCachedAdj = nextCachedAdj; 15416 nextCachedAdj += 2; 15417 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15418 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15419 } 15420 } 15421 } 15422 break; 15423 default: 15424 // For everything else, assign next empty cached process 15425 // level and bump that up. Note that this means that 15426 // long-running services that have dropped down to the 15427 // cached level will be treated as empty (since their process 15428 // state is still as a service), which is what we want. 15429 app.curRawAdj = curEmptyAdj; 15430 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15431 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15432 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15433 + ")"); 15434 if (curEmptyAdj != nextEmptyAdj) { 15435 stepEmpty++; 15436 if (stepEmpty >= emptyFactor) { 15437 stepEmpty = 0; 15438 curEmptyAdj = nextEmptyAdj; 15439 nextEmptyAdj += 2; 15440 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15441 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15442 } 15443 } 15444 } 15445 break; 15446 } 15447 } 15448 15449 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15450 15451 // Count the number of process types. 15452 switch (app.curProcState) { 15453 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15454 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15455 mNumCachedHiddenProcs++; 15456 numCached++; 15457 if (numCached > cachedProcessLimit) { 15458 killUnneededProcessLocked(app, "cached #" + numCached); 15459 } 15460 break; 15461 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15462 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15463 && app.lastActivityTime < oldTime) { 15464 killUnneededProcessLocked(app, "empty for " 15465 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15466 / 1000) + "s"); 15467 } else { 15468 numEmpty++; 15469 if (numEmpty > emptyProcessLimit) { 15470 killUnneededProcessLocked(app, "empty #" + numEmpty); 15471 } 15472 } 15473 break; 15474 default: 15475 mNumNonCachedProcs++; 15476 break; 15477 } 15478 15479 if (app.isolated && app.services.size() <= 0) { 15480 // If this is an isolated process, and there are no 15481 // services running in it, then the process is no longer 15482 // needed. We agressively kill these because we can by 15483 // definition not re-use the same process again, and it is 15484 // good to avoid having whatever code was running in them 15485 // left sitting around after no longer needed. 15486 killUnneededProcessLocked(app, "isolated not needed"); 15487 } 15488 15489 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15490 && !app.killedByAm) { 15491 numTrimming++; 15492 } 15493 } 15494 } 15495 15496 mNumServiceProcs = mNewNumServiceProcs; 15497 15498 // Now determine the memory trimming level of background processes. 15499 // Unfortunately we need to start at the back of the list to do this 15500 // properly. We only do this if the number of background apps we 15501 // are managing to keep around is less than half the maximum we desire; 15502 // if we are keeping a good number around, we'll let them use whatever 15503 // memory they want. 15504 final int numCachedAndEmpty = numCached + numEmpty; 15505 int memFactor; 15506 if (numCached <= ProcessList.TRIM_CACHED_APPS 15507 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15508 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15509 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15510 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15511 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15512 } else { 15513 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15514 } 15515 } else { 15516 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15517 } 15518 // We always allow the memory level to go up (better). We only allow it to go 15519 // down if we are in a state where that is allowed, *and* the total number of processes 15520 // has gone down since last time. 15521 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15522 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15523 + " last=" + mLastNumProcesses); 15524 if (memFactor > mLastMemoryLevel) { 15525 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15526 memFactor = mLastMemoryLevel; 15527 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15528 } 15529 } 15530 mLastMemoryLevel = memFactor; 15531 mLastNumProcesses = mLruProcesses.size(); 15532 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15533 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15534 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15535 if (mLowRamStartTime == 0) { 15536 mLowRamStartTime = now; 15537 } 15538 int step = 0; 15539 int fgTrimLevel; 15540 switch (memFactor) { 15541 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15542 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15543 break; 15544 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15545 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15546 break; 15547 default: 15548 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15549 break; 15550 } 15551 int factor = numTrimming/3; 15552 int minFactor = 2; 15553 if (mHomeProcess != null) minFactor++; 15554 if (mPreviousProcess != null) minFactor++; 15555 if (factor < minFactor) factor = minFactor; 15556 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15557 for (int i=N-1; i>=0; i--) { 15558 ProcessRecord app = mLruProcesses.get(i); 15559 if (allChanged || app.procStateChanged) { 15560 setProcessTrackerState(app, trackerMemFactor, now); 15561 app.procStateChanged = false; 15562 } 15563 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15564 && !app.killedByAm) { 15565 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15566 try { 15567 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15568 "Trimming memory of " + app.processName 15569 + " to " + curLevel); 15570 app.thread.scheduleTrimMemory(curLevel); 15571 } catch (RemoteException e) { 15572 } 15573 if (false) { 15574 // For now we won't do this; our memory trimming seems 15575 // to be good enough at this point that destroying 15576 // activities causes more harm than good. 15577 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15578 && app != mHomeProcess && app != mPreviousProcess) { 15579 // Need to do this on its own message because the stack may not 15580 // be in a consistent state at this point. 15581 // For these apps we will also finish their activities 15582 // to help them free memory. 15583 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15584 } 15585 } 15586 } 15587 app.trimMemoryLevel = curLevel; 15588 step++; 15589 if (step >= factor) { 15590 step = 0; 15591 switch (curLevel) { 15592 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15593 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15594 break; 15595 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15596 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15597 break; 15598 } 15599 } 15600 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15601 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15602 && app.thread != null) { 15603 try { 15604 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15605 "Trimming memory of heavy-weight " + app.processName 15606 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15607 app.thread.scheduleTrimMemory( 15608 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15609 } catch (RemoteException e) { 15610 } 15611 } 15612 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15613 } else { 15614 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15615 || app.systemNoUi) && app.pendingUiClean) { 15616 // If this application is now in the background and it 15617 // had done UI, then give it the special trim level to 15618 // have it free UI resources. 15619 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15620 if (app.trimMemoryLevel < level && app.thread != null) { 15621 try { 15622 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15623 "Trimming memory of bg-ui " + app.processName 15624 + " to " + level); 15625 app.thread.scheduleTrimMemory(level); 15626 } catch (RemoteException e) { 15627 } 15628 } 15629 app.pendingUiClean = false; 15630 } 15631 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15632 try { 15633 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15634 "Trimming memory of fg " + app.processName 15635 + " to " + fgTrimLevel); 15636 app.thread.scheduleTrimMemory(fgTrimLevel); 15637 } catch (RemoteException e) { 15638 } 15639 } 15640 app.trimMemoryLevel = fgTrimLevel; 15641 } 15642 } 15643 } else { 15644 if (mLowRamStartTime != 0) { 15645 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15646 mLowRamStartTime = 0; 15647 } 15648 for (int i=N-1; i>=0; i--) { 15649 ProcessRecord app = mLruProcesses.get(i); 15650 if (allChanged || app.procStateChanged) { 15651 setProcessTrackerState(app, trackerMemFactor, now); 15652 app.procStateChanged = false; 15653 } 15654 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15655 || app.systemNoUi) && app.pendingUiClean) { 15656 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15657 && app.thread != null) { 15658 try { 15659 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15660 "Trimming memory of ui hidden " + app.processName 15661 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15662 app.thread.scheduleTrimMemory( 15663 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15664 } catch (RemoteException e) { 15665 } 15666 } 15667 app.pendingUiClean = false; 15668 } 15669 app.trimMemoryLevel = 0; 15670 } 15671 } 15672 15673 if (mAlwaysFinishActivities) { 15674 // Need to do this on its own message because the stack may not 15675 // be in a consistent state at this point. 15676 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15677 } 15678 15679 if (allChanged) { 15680 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15681 } 15682 15683 if (mProcessStats.shouldWriteNowLocked(now)) { 15684 mHandler.post(new Runnable() { 15685 @Override public void run() { 15686 synchronized (ActivityManagerService.this) { 15687 mProcessStats.writeStateAsyncLocked(); 15688 } 15689 } 15690 }); 15691 } 15692 15693 if (DEBUG_OOM_ADJ) { 15694 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15695 } 15696 } 15697 15698 final void trimApplications() { 15699 synchronized (this) { 15700 int i; 15701 15702 // First remove any unused application processes whose package 15703 // has been removed. 15704 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15705 final ProcessRecord app = mRemovedProcesses.get(i); 15706 if (app.activities.size() == 0 15707 && app.curReceiver == null && app.services.size() == 0) { 15708 Slog.i( 15709 TAG, "Exiting empty application process " 15710 + app.processName + " (" 15711 + (app.thread != null ? app.thread.asBinder() : null) 15712 + ")\n"); 15713 if (app.pid > 0 && app.pid != MY_PID) { 15714 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 15715 app.processName, app.setAdj, "empty"); 15716 app.killedByAm = true; 15717 Process.killProcessQuiet(app.pid); 15718 } else { 15719 try { 15720 app.thread.scheduleExit(); 15721 } catch (Exception e) { 15722 // Ignore exceptions. 15723 } 15724 } 15725 cleanUpApplicationRecordLocked(app, false, true, -1); 15726 mRemovedProcesses.remove(i); 15727 15728 if (app.persistent) { 15729 if (app.persistent) { 15730 addAppLocked(app.info, false, null /* ABI override */); 15731 } 15732 } 15733 } 15734 } 15735 15736 // Now update the oom adj for all processes. 15737 updateOomAdjLocked(); 15738 } 15739 } 15740 15741 /** This method sends the specified signal to each of the persistent apps */ 15742 public void signalPersistentProcesses(int sig) throws RemoteException { 15743 if (sig != Process.SIGNAL_USR1) { 15744 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 15745 } 15746 15747 synchronized (this) { 15748 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 15749 != PackageManager.PERMISSION_GRANTED) { 15750 throw new SecurityException("Requires permission " 15751 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 15752 } 15753 15754 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15755 ProcessRecord r = mLruProcesses.get(i); 15756 if (r.thread != null && r.persistent) { 15757 Process.sendSignal(r.pid, sig); 15758 } 15759 } 15760 } 15761 } 15762 15763 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 15764 if (proc == null || proc == mProfileProc) { 15765 proc = mProfileProc; 15766 path = mProfileFile; 15767 profileType = mProfileType; 15768 clearProfilerLocked(); 15769 } 15770 if (proc == null) { 15771 return; 15772 } 15773 try { 15774 proc.thread.profilerControl(false, path, null, profileType); 15775 } catch (RemoteException e) { 15776 throw new IllegalStateException("Process disappeared"); 15777 } 15778 } 15779 15780 private void clearProfilerLocked() { 15781 if (mProfileFd != null) { 15782 try { 15783 mProfileFd.close(); 15784 } catch (IOException e) { 15785 } 15786 } 15787 mProfileApp = null; 15788 mProfileProc = null; 15789 mProfileFile = null; 15790 mProfileType = 0; 15791 mAutoStopProfiler = false; 15792 } 15793 15794 public boolean profileControl(String process, int userId, boolean start, 15795 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 15796 15797 try { 15798 synchronized (this) { 15799 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15800 // its own permission. 15801 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15802 != PackageManager.PERMISSION_GRANTED) { 15803 throw new SecurityException("Requires permission " 15804 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15805 } 15806 15807 if (start && fd == null) { 15808 throw new IllegalArgumentException("null fd"); 15809 } 15810 15811 ProcessRecord proc = null; 15812 if (process != null) { 15813 proc = findProcessLocked(process, userId, "profileControl"); 15814 } 15815 15816 if (start && (proc == null || proc.thread == null)) { 15817 throw new IllegalArgumentException("Unknown process: " + process); 15818 } 15819 15820 if (start) { 15821 stopProfilerLocked(null, null, 0); 15822 setProfileApp(proc.info, proc.processName, path, fd, false); 15823 mProfileProc = proc; 15824 mProfileType = profileType; 15825 try { 15826 fd = fd.dup(); 15827 } catch (IOException e) { 15828 fd = null; 15829 } 15830 proc.thread.profilerControl(start, path, fd, profileType); 15831 fd = null; 15832 mProfileFd = null; 15833 } else { 15834 stopProfilerLocked(proc, path, profileType); 15835 if (fd != null) { 15836 try { 15837 fd.close(); 15838 } catch (IOException e) { 15839 } 15840 } 15841 } 15842 15843 return true; 15844 } 15845 } catch (RemoteException e) { 15846 throw new IllegalStateException("Process disappeared"); 15847 } finally { 15848 if (fd != null) { 15849 try { 15850 fd.close(); 15851 } catch (IOException e) { 15852 } 15853 } 15854 } 15855 } 15856 15857 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 15858 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15859 userId, true, true, callName, null); 15860 ProcessRecord proc = null; 15861 try { 15862 int pid = Integer.parseInt(process); 15863 synchronized (mPidsSelfLocked) { 15864 proc = mPidsSelfLocked.get(pid); 15865 } 15866 } catch (NumberFormatException e) { 15867 } 15868 15869 if (proc == null) { 15870 ArrayMap<String, SparseArray<ProcessRecord>> all 15871 = mProcessNames.getMap(); 15872 SparseArray<ProcessRecord> procs = all.get(process); 15873 if (procs != null && procs.size() > 0) { 15874 proc = procs.valueAt(0); 15875 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 15876 for (int i=1; i<procs.size(); i++) { 15877 ProcessRecord thisProc = procs.valueAt(i); 15878 if (thisProc.userId == userId) { 15879 proc = thisProc; 15880 break; 15881 } 15882 } 15883 } 15884 } 15885 } 15886 15887 return proc; 15888 } 15889 15890 public boolean dumpHeap(String process, int userId, boolean managed, 15891 String path, ParcelFileDescriptor fd) throws RemoteException { 15892 15893 try { 15894 synchronized (this) { 15895 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15896 // its own permission (same as profileControl). 15897 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15898 != PackageManager.PERMISSION_GRANTED) { 15899 throw new SecurityException("Requires permission " 15900 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15901 } 15902 15903 if (fd == null) { 15904 throw new IllegalArgumentException("null fd"); 15905 } 15906 15907 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 15908 if (proc == null || proc.thread == null) { 15909 throw new IllegalArgumentException("Unknown process: " + process); 15910 } 15911 15912 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 15913 if (!isDebuggable) { 15914 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 15915 throw new SecurityException("Process not debuggable: " + proc); 15916 } 15917 } 15918 15919 proc.thread.dumpHeap(managed, path, fd); 15920 fd = null; 15921 return true; 15922 } 15923 } catch (RemoteException e) { 15924 throw new IllegalStateException("Process disappeared"); 15925 } finally { 15926 if (fd != null) { 15927 try { 15928 fd.close(); 15929 } catch (IOException e) { 15930 } 15931 } 15932 } 15933 } 15934 15935 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 15936 public void monitor() { 15937 synchronized (this) { } 15938 } 15939 15940 void onCoreSettingsChange(Bundle settings) { 15941 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 15942 ProcessRecord processRecord = mLruProcesses.get(i); 15943 try { 15944 if (processRecord.thread != null) { 15945 processRecord.thread.setCoreSettings(settings); 15946 } 15947 } catch (RemoteException re) { 15948 /* ignore */ 15949 } 15950 } 15951 } 15952 15953 // Multi-user methods 15954 15955 @Override 15956 public boolean switchUser(final int userId) { 15957 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 15958 != PackageManager.PERMISSION_GRANTED) { 15959 String msg = "Permission Denial: switchUser() from pid=" 15960 + Binder.getCallingPid() 15961 + ", uid=" + Binder.getCallingUid() 15962 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 15963 Slog.w(TAG, msg); 15964 throw new SecurityException(msg); 15965 } 15966 15967 final long ident = Binder.clearCallingIdentity(); 15968 try { 15969 synchronized (this) { 15970 final int oldUserId = mCurrentUserId; 15971 if (oldUserId == userId) { 15972 return true; 15973 } 15974 15975 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 15976 if (userInfo == null) { 15977 Slog.w(TAG, "No user info for user #" + userId); 15978 return false; 15979 } 15980 15981 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 15982 R.anim.screen_user_enter); 15983 15984 boolean needStart = false; 15985 15986 // If the user we are switching to is not currently started, then 15987 // we need to start it now. 15988 if (mStartedUsers.get(userId) == null) { 15989 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 15990 updateStartedUserArrayLocked(); 15991 needStart = true; 15992 } 15993 15994 mCurrentUserId = userId; 15995 final Integer userIdInt = Integer.valueOf(userId); 15996 mUserLru.remove(userIdInt); 15997 mUserLru.add(userIdInt); 15998 15999 mWindowManager.setCurrentUser(userId); 16000 16001 // Once the internal notion of the active user has switched, we lock the device 16002 // with the option to show the user switcher on the keyguard. 16003 mWindowManager.lockNow(null); 16004 16005 final UserStartedState uss = mStartedUsers.get(userId); 16006 16007 // Make sure user is in the started state. If it is currently 16008 // stopping, we need to knock that off. 16009 if (uss.mState == UserStartedState.STATE_STOPPING) { 16010 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16011 // so we can just fairly silently bring the user back from 16012 // the almost-dead. 16013 uss.mState = UserStartedState.STATE_RUNNING; 16014 updateStartedUserArrayLocked(); 16015 needStart = true; 16016 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16017 // This means ACTION_SHUTDOWN has been sent, so we will 16018 // need to treat this as a new boot of the user. 16019 uss.mState = UserStartedState.STATE_BOOTING; 16020 updateStartedUserArrayLocked(); 16021 needStart = true; 16022 } 16023 16024 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16025 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16026 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16027 oldUserId, userId, uss)); 16028 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16029 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16030 if (needStart) { 16031 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16032 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16033 | Intent.FLAG_RECEIVER_FOREGROUND); 16034 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16035 broadcastIntentLocked(null, null, intent, 16036 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16037 false, false, MY_PID, Process.SYSTEM_UID, userId); 16038 } 16039 16040 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16041 if (userId != 0) { 16042 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16043 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16044 broadcastIntentLocked(null, null, intent, null, 16045 new IIntentReceiver.Stub() { 16046 public void performReceive(Intent intent, int resultCode, 16047 String data, Bundle extras, boolean ordered, 16048 boolean sticky, int sendingUser) { 16049 userInitialized(uss, userId); 16050 } 16051 }, 0, null, null, null, AppOpsManager.OP_NONE, 16052 true, false, MY_PID, Process.SYSTEM_UID, 16053 userId); 16054 uss.initializing = true; 16055 } else { 16056 getUserManagerLocked().makeInitialized(userInfo.id); 16057 } 16058 } 16059 16060 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16061 if (homeInFront) { 16062 startHomeActivityLocked(userId); 16063 } else { 16064 mStackSupervisor.resumeTopActivitiesLocked(); 16065 } 16066 16067 EventLogTags.writeAmSwitchUser(userId); 16068 getUserManagerLocked().userForeground(userId); 16069 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16070 if (needStart) { 16071 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16072 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16073 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16074 broadcastIntentLocked(null, null, intent, 16075 null, new IIntentReceiver.Stub() { 16076 @Override 16077 public void performReceive(Intent intent, int resultCode, String data, 16078 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16079 throws RemoteException { 16080 } 16081 }, 0, null, null, 16082 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16083 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16084 } 16085 } 16086 } finally { 16087 Binder.restoreCallingIdentity(ident); 16088 } 16089 16090 return true; 16091 } 16092 16093 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16094 long ident = Binder.clearCallingIdentity(); 16095 try { 16096 Intent intent; 16097 if (oldUserId >= 0) { 16098 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16099 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16100 | Intent.FLAG_RECEIVER_FOREGROUND); 16101 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16102 broadcastIntentLocked(null, null, intent, 16103 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16104 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16105 } 16106 if (newUserId >= 0) { 16107 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16108 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16109 | Intent.FLAG_RECEIVER_FOREGROUND); 16110 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16111 broadcastIntentLocked(null, null, intent, 16112 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16113 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16114 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16115 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16116 | Intent.FLAG_RECEIVER_FOREGROUND); 16117 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16118 broadcastIntentLocked(null, null, intent, 16119 null, null, 0, null, null, 16120 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16121 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16122 } 16123 } finally { 16124 Binder.restoreCallingIdentity(ident); 16125 } 16126 } 16127 16128 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16129 final int newUserId) { 16130 final int N = mUserSwitchObservers.beginBroadcast(); 16131 if (N > 0) { 16132 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16133 int mCount = 0; 16134 @Override 16135 public void sendResult(Bundle data) throws RemoteException { 16136 synchronized (ActivityManagerService.this) { 16137 if (mCurUserSwitchCallback == this) { 16138 mCount++; 16139 if (mCount == N) { 16140 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16141 } 16142 } 16143 } 16144 } 16145 }; 16146 synchronized (this) { 16147 uss.switching = true; 16148 mCurUserSwitchCallback = callback; 16149 } 16150 for (int i=0; i<N; i++) { 16151 try { 16152 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16153 newUserId, callback); 16154 } catch (RemoteException e) { 16155 } 16156 } 16157 } else { 16158 synchronized (this) { 16159 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16160 } 16161 } 16162 mUserSwitchObservers.finishBroadcast(); 16163 } 16164 16165 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16166 synchronized (this) { 16167 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16168 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16169 } 16170 } 16171 16172 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16173 mCurUserSwitchCallback = null; 16174 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16175 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16176 oldUserId, newUserId, uss)); 16177 } 16178 16179 void userInitialized(UserStartedState uss, int newUserId) { 16180 completeSwitchAndInitalize(uss, newUserId, true, false); 16181 } 16182 16183 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16184 completeSwitchAndInitalize(uss, newUserId, false, true); 16185 } 16186 16187 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16188 boolean clearInitializing, boolean clearSwitching) { 16189 boolean unfrozen = false; 16190 synchronized (this) { 16191 if (clearInitializing) { 16192 uss.initializing = false; 16193 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16194 } 16195 if (clearSwitching) { 16196 uss.switching = false; 16197 } 16198 if (!uss.switching && !uss.initializing) { 16199 mWindowManager.stopFreezingScreen(); 16200 unfrozen = true; 16201 } 16202 } 16203 if (unfrozen) { 16204 final int N = mUserSwitchObservers.beginBroadcast(); 16205 for (int i=0; i<N; i++) { 16206 try { 16207 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16208 } catch (RemoteException e) { 16209 } 16210 } 16211 mUserSwitchObservers.finishBroadcast(); 16212 } 16213 } 16214 16215 void finishUserSwitch(UserStartedState uss) { 16216 synchronized (this) { 16217 if (uss.mState == UserStartedState.STATE_BOOTING 16218 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16219 uss.mState = UserStartedState.STATE_RUNNING; 16220 final int userId = uss.mHandle.getIdentifier(); 16221 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16222 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16223 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16224 broadcastIntentLocked(null, null, intent, 16225 null, null, 0, null, null, 16226 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16227 true, false, MY_PID, Process.SYSTEM_UID, userId); 16228 } 16229 int num = mUserLru.size(); 16230 int i = 0; 16231 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16232 Integer oldUserId = mUserLru.get(i); 16233 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16234 if (oldUss == null) { 16235 // Shouldn't happen, but be sane if it does. 16236 mUserLru.remove(i); 16237 num--; 16238 continue; 16239 } 16240 if (oldUss.mState == UserStartedState.STATE_STOPPING 16241 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16242 // This user is already stopping, doesn't count. 16243 num--; 16244 i++; 16245 continue; 16246 } 16247 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16248 // Owner and current can't be stopped, but count as running. 16249 i++; 16250 continue; 16251 } 16252 // This is a user to be stopped. 16253 stopUserLocked(oldUserId, null); 16254 num--; 16255 i++; 16256 } 16257 } 16258 } 16259 16260 @Override 16261 public int stopUser(final int userId, final IStopUserCallback callback) { 16262 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16263 != PackageManager.PERMISSION_GRANTED) { 16264 String msg = "Permission Denial: switchUser() from pid=" 16265 + Binder.getCallingPid() 16266 + ", uid=" + Binder.getCallingUid() 16267 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16268 Slog.w(TAG, msg); 16269 throw new SecurityException(msg); 16270 } 16271 if (userId <= 0) { 16272 throw new IllegalArgumentException("Can't stop primary user " + userId); 16273 } 16274 synchronized (this) { 16275 return stopUserLocked(userId, callback); 16276 } 16277 } 16278 16279 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16280 if (mCurrentUserId == userId) { 16281 return ActivityManager.USER_OP_IS_CURRENT; 16282 } 16283 16284 final UserStartedState uss = mStartedUsers.get(userId); 16285 if (uss == null) { 16286 // User is not started, nothing to do... but we do need to 16287 // callback if requested. 16288 if (callback != null) { 16289 mHandler.post(new Runnable() { 16290 @Override 16291 public void run() { 16292 try { 16293 callback.userStopped(userId); 16294 } catch (RemoteException e) { 16295 } 16296 } 16297 }); 16298 } 16299 return ActivityManager.USER_OP_SUCCESS; 16300 } 16301 16302 if (callback != null) { 16303 uss.mStopCallbacks.add(callback); 16304 } 16305 16306 if (uss.mState != UserStartedState.STATE_STOPPING 16307 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16308 uss.mState = UserStartedState.STATE_STOPPING; 16309 updateStartedUserArrayLocked(); 16310 16311 long ident = Binder.clearCallingIdentity(); 16312 try { 16313 // We are going to broadcast ACTION_USER_STOPPING and then 16314 // once that is done send a final ACTION_SHUTDOWN and then 16315 // stop the user. 16316 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16317 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16318 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16319 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16320 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16321 // This is the result receiver for the final shutdown broadcast. 16322 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16323 @Override 16324 public void performReceive(Intent intent, int resultCode, String data, 16325 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16326 finishUserStop(uss); 16327 } 16328 }; 16329 // This is the result receiver for the initial stopping broadcast. 16330 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16331 @Override 16332 public void performReceive(Intent intent, int resultCode, String data, 16333 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16334 // On to the next. 16335 synchronized (ActivityManagerService.this) { 16336 if (uss.mState != UserStartedState.STATE_STOPPING) { 16337 // Whoops, we are being started back up. Abort, abort! 16338 return; 16339 } 16340 uss.mState = UserStartedState.STATE_SHUTDOWN; 16341 } 16342 broadcastIntentLocked(null, null, shutdownIntent, 16343 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16344 true, false, MY_PID, Process.SYSTEM_UID, userId); 16345 } 16346 }; 16347 // Kick things off. 16348 broadcastIntentLocked(null, null, stoppingIntent, 16349 null, stoppingReceiver, 0, null, null, 16350 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16351 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16352 } finally { 16353 Binder.restoreCallingIdentity(ident); 16354 } 16355 } 16356 16357 return ActivityManager.USER_OP_SUCCESS; 16358 } 16359 16360 void finishUserStop(UserStartedState uss) { 16361 final int userId = uss.mHandle.getIdentifier(); 16362 boolean stopped; 16363 ArrayList<IStopUserCallback> callbacks; 16364 synchronized (this) { 16365 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16366 if (mStartedUsers.get(userId) != uss) { 16367 stopped = false; 16368 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16369 stopped = false; 16370 } else { 16371 stopped = true; 16372 // User can no longer run. 16373 mStartedUsers.remove(userId); 16374 mUserLru.remove(Integer.valueOf(userId)); 16375 updateStartedUserArrayLocked(); 16376 16377 // Clean up all state and processes associated with the user. 16378 // Kill all the processes for the user. 16379 forceStopUserLocked(userId, "finish user"); 16380 } 16381 } 16382 16383 for (int i=0; i<callbacks.size(); i++) { 16384 try { 16385 if (stopped) callbacks.get(i).userStopped(userId); 16386 else callbacks.get(i).userStopAborted(userId); 16387 } catch (RemoteException e) { 16388 } 16389 } 16390 16391 mStackSupervisor.removeUserLocked(userId); 16392 } 16393 16394 @Override 16395 public UserInfo getCurrentUser() { 16396 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16397 != PackageManager.PERMISSION_GRANTED) && ( 16398 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16399 != PackageManager.PERMISSION_GRANTED)) { 16400 String msg = "Permission Denial: getCurrentUser() from pid=" 16401 + Binder.getCallingPid() 16402 + ", uid=" + Binder.getCallingUid() 16403 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16404 Slog.w(TAG, msg); 16405 throw new SecurityException(msg); 16406 } 16407 synchronized (this) { 16408 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16409 } 16410 } 16411 16412 int getCurrentUserIdLocked() { 16413 return mCurrentUserId; 16414 } 16415 16416 @Override 16417 public boolean isUserRunning(int userId, boolean orStopped) { 16418 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16419 != PackageManager.PERMISSION_GRANTED) { 16420 String msg = "Permission Denial: isUserRunning() from pid=" 16421 + Binder.getCallingPid() 16422 + ", uid=" + Binder.getCallingUid() 16423 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16424 Slog.w(TAG, msg); 16425 throw new SecurityException(msg); 16426 } 16427 synchronized (this) { 16428 return isUserRunningLocked(userId, orStopped); 16429 } 16430 } 16431 16432 boolean isUserRunningLocked(int userId, boolean orStopped) { 16433 UserStartedState state = mStartedUsers.get(userId); 16434 if (state == null) { 16435 return false; 16436 } 16437 if (orStopped) { 16438 return true; 16439 } 16440 return state.mState != UserStartedState.STATE_STOPPING 16441 && state.mState != UserStartedState.STATE_SHUTDOWN; 16442 } 16443 16444 @Override 16445 public int[] getRunningUserIds() { 16446 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16447 != PackageManager.PERMISSION_GRANTED) { 16448 String msg = "Permission Denial: isUserRunning() from pid=" 16449 + Binder.getCallingPid() 16450 + ", uid=" + Binder.getCallingUid() 16451 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16452 Slog.w(TAG, msg); 16453 throw new SecurityException(msg); 16454 } 16455 synchronized (this) { 16456 return mStartedUserArray; 16457 } 16458 } 16459 16460 private void updateStartedUserArrayLocked() { 16461 int num = 0; 16462 for (int i=0; i<mStartedUsers.size(); i++) { 16463 UserStartedState uss = mStartedUsers.valueAt(i); 16464 // This list does not include stopping users. 16465 if (uss.mState != UserStartedState.STATE_STOPPING 16466 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16467 num++; 16468 } 16469 } 16470 mStartedUserArray = new int[num]; 16471 num = 0; 16472 for (int i=0; i<mStartedUsers.size(); i++) { 16473 UserStartedState uss = mStartedUsers.valueAt(i); 16474 if (uss.mState != UserStartedState.STATE_STOPPING 16475 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16476 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16477 num++; 16478 } 16479 } 16480 } 16481 16482 @Override 16483 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16484 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16485 != PackageManager.PERMISSION_GRANTED) { 16486 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16487 + Binder.getCallingPid() 16488 + ", uid=" + Binder.getCallingUid() 16489 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16490 Slog.w(TAG, msg); 16491 throw new SecurityException(msg); 16492 } 16493 16494 mUserSwitchObservers.register(observer); 16495 } 16496 16497 @Override 16498 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16499 mUserSwitchObservers.unregister(observer); 16500 } 16501 16502 private boolean userExists(int userId) { 16503 if (userId == 0) { 16504 return true; 16505 } 16506 UserManagerService ums = getUserManagerLocked(); 16507 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16508 } 16509 16510 int[] getUsersLocked() { 16511 UserManagerService ums = getUserManagerLocked(); 16512 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16513 } 16514 16515 UserManagerService getUserManagerLocked() { 16516 if (mUserManager == null) { 16517 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16518 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16519 } 16520 return mUserManager; 16521 } 16522 16523 private int applyUserId(int uid, int userId) { 16524 return UserHandle.getUid(userId, uid); 16525 } 16526 16527 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16528 if (info == null) return null; 16529 ApplicationInfo newInfo = new ApplicationInfo(info); 16530 newInfo.uid = applyUserId(info.uid, userId); 16531 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16532 + info.packageName; 16533 return newInfo; 16534 } 16535 16536 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16537 if (aInfo == null 16538 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16539 return aInfo; 16540 } 16541 16542 ActivityInfo info = new ActivityInfo(aInfo); 16543 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16544 return info; 16545 } 16546 16547 private final class LocalService extends ActivityManagerInternal { 16548 @Override 16549 public void goingToSleep() { 16550 ActivityManagerService.this.goingToSleep(); 16551 } 16552 16553 @Override 16554 public void wakingUp() { 16555 ActivityManagerService.this.wakingUp(); 16556 } 16557 } 16558} 16559