ActivityManagerService.java revision 13014b5fe5967b3c7e232ffaf81581ed178e6df6
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.util.FastPrintWriter; 46import com.android.internal.util.FastXmlSerializer; 47import com.android.internal.util.MemInfoReader; 48import com.android.internal.util.Preconditions; 49import com.android.server.AppOpsService; 50import com.android.server.AttributeCache; 51import com.android.server.IntentResolver; 52import com.android.server.LocalServices; 53import com.android.server.ServiceThread; 54import com.android.server.SystemService; 55import com.android.server.Watchdog; 56import com.android.server.am.ActivityStack.ActivityState; 57import com.android.server.firewall.IntentFirewall; 58import com.android.server.pm.UserManagerService; 59import com.android.server.wm.AppTransition; 60import com.android.server.wm.WindowManagerService; 61import com.google.android.collect.Lists; 62import com.google.android.collect.Maps; 63 64import dalvik.system.Zygote; 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 = 300*1000; 277 278 // How long to wait after going idle before forcing apps to GC. 279 static final int GC_TIMEOUT = 5*1000; 280 281 // The minimum amount of time between successive GC requests for a process. 282 static final int GC_MIN_INTERVAL = 60*1000; 283 284 // The minimum amount of time between successive PSS requests for a process. 285 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 286 287 // The minimum amount of time between successive PSS requests for a process 288 // when the request is due to the memory state being lowered. 289 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 290 291 // The rate at which we check for apps using excessive power -- 15 mins. 292 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 293 294 // The minimum sample duration we will allow before deciding we have 295 // enough data on wake locks to start killing things. 296 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 297 298 // The minimum sample duration we will allow before deciding we have 299 // enough data on CPU usage to start killing things. 300 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 301 302 // How long we allow a receiver to run before giving up on it. 303 static final int BROADCAST_FG_TIMEOUT = 10*1000; 304 static final int BROADCAST_BG_TIMEOUT = 60*1000; 305 306 // How long we wait until we timeout on key dispatching. 307 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 308 309 // How long we wait until we timeout on key dispatching during instrumentation. 310 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 311 312 // Amount of time we wait for observers to handle a user switch before 313 // giving up on them and unfreezing the screen. 314 static final int USER_SWITCH_TIMEOUT = 2*1000; 315 316 // Maximum number of users we allow to be running at a time. 317 static final int MAX_RUNNING_USERS = 3; 318 319 // How long to wait in getAssistContextExtras for the activity and foreground services 320 // to respond with the result. 321 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 322 323 // Maximum number of persisted Uri grants a package is allowed 324 static final int MAX_PERSISTED_URI_GRANTS = 128; 325 326 static final int MY_PID = Process.myPid(); 327 328 static final String[] EMPTY_STRING_ARRAY = new String[0]; 329 330 // How many bytes to write into the dropbox log before truncating 331 static final int DROPBOX_MAX_SIZE = 256 * 1024; 332 333 /** Run all ActivityStacks through this */ 334 ActivityStackSupervisor mStackSupervisor; 335 336 public IntentFirewall mIntentFirewall; 337 338 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 339 // default actuion automatically. Important for devices without direct input 340 // devices. 341 private boolean mShowDialogs = true; 342 343 /** 344 * Description of a request to start a new activity, which has been held 345 * due to app switches being disabled. 346 */ 347 static class PendingActivityLaunch { 348 final ActivityRecord r; 349 final ActivityRecord sourceRecord; 350 final int startFlags; 351 final ActivityStack stack; 352 353 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 354 int _startFlags, ActivityStack _stack) { 355 r = _r; 356 sourceRecord = _sourceRecord; 357 startFlags = _startFlags; 358 stack = _stack; 359 } 360 } 361 362 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 363 = new ArrayList<PendingActivityLaunch>(); 364 365 BroadcastQueue mFgBroadcastQueue; 366 BroadcastQueue mBgBroadcastQueue; 367 // Convenient for easy iteration over the queues. Foreground is first 368 // so that dispatch of foreground broadcasts gets precedence. 369 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 370 371 BroadcastQueue broadcastQueueForIntent(Intent intent) { 372 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 373 if (DEBUG_BACKGROUND_BROADCAST) { 374 Slog.i(TAG, "Broadcast intent " + intent + " on " 375 + (isFg ? "foreground" : "background") 376 + " queue"); 377 } 378 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 379 } 380 381 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 382 for (BroadcastQueue queue : mBroadcastQueues) { 383 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 384 if (r != null) { 385 return r; 386 } 387 } 388 return null; 389 } 390 391 /** 392 * Activity we have told the window manager to have key focus. 393 */ 394 ActivityRecord mFocusedActivity = null; 395 396 /** 397 * List of intents that were used to start the most recent tasks. 398 */ 399 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 400 401 public class PendingAssistExtras extends Binder implements Runnable { 402 public final ActivityRecord activity; 403 public boolean haveResult = false; 404 public Bundle result = null; 405 public PendingAssistExtras(ActivityRecord _activity) { 406 activity = _activity; 407 } 408 @Override 409 public void run() { 410 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 411 synchronized (this) { 412 haveResult = true; 413 notifyAll(); 414 } 415 } 416 } 417 418 final ArrayList<PendingAssistExtras> mPendingAssistExtras 419 = new ArrayList<PendingAssistExtras>(); 420 421 /** 422 * Process management. 423 */ 424 final ProcessList mProcessList = new ProcessList(); 425 426 /** 427 * All of the applications we currently have running organized by name. 428 * The keys are strings of the application package name (as 429 * returned by the package manager), and the keys are ApplicationRecord 430 * objects. 431 */ 432 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 433 434 /** 435 * Tracking long-term execution of processes to look for abuse and other 436 * bad app behavior. 437 */ 438 final ProcessStatsService mProcessStats; 439 440 /** 441 * The currently running isolated processes. 442 */ 443 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 444 445 /** 446 * Counter for assigning isolated process uids, to avoid frequently reusing the 447 * same ones. 448 */ 449 int mNextIsolatedProcessUid = 0; 450 451 /** 452 * The currently running heavy-weight process, if any. 453 */ 454 ProcessRecord mHeavyWeightProcess = null; 455 456 /** 457 * The last time that various processes have crashed. 458 */ 459 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 460 461 /** 462 * Information about a process that is currently marked as bad. 463 */ 464 static final class BadProcessInfo { 465 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 466 this.time = time; 467 this.shortMsg = shortMsg; 468 this.longMsg = longMsg; 469 this.stack = stack; 470 } 471 472 final long time; 473 final String shortMsg; 474 final String longMsg; 475 final String stack; 476 } 477 478 /** 479 * Set of applications that we consider to be bad, and will reject 480 * incoming broadcasts from (which the user has no control over). 481 * Processes are added to this set when they have crashed twice within 482 * a minimum amount of time; they are removed from it when they are 483 * later restarted (hopefully due to some user action). The value is the 484 * time it was added to the list. 485 */ 486 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 487 488 /** 489 * All of the processes we currently have running organized by pid. 490 * The keys are the pid running the application. 491 * 492 * <p>NOTE: This object is protected by its own lock, NOT the global 493 * activity manager lock! 494 */ 495 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 496 497 /** 498 * All of the processes that have been forced to be foreground. The key 499 * is the pid of the caller who requested it (we hold a death 500 * link on it). 501 */ 502 abstract class ForegroundToken implements IBinder.DeathRecipient { 503 int pid; 504 IBinder token; 505 } 506 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 507 508 /** 509 * List of records for processes that someone had tried to start before the 510 * system was ready. We don't start them at that point, but ensure they 511 * are started by the time booting is complete. 512 */ 513 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 514 515 /** 516 * List of persistent applications that are in the process 517 * of being started. 518 */ 519 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 520 521 /** 522 * Processes that are being forcibly torn down. 523 */ 524 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 525 526 /** 527 * List of running applications, sorted by recent usage. 528 * The first entry in the list is the least recently used. 529 */ 530 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 531 532 /** 533 * Where in mLruProcesses that the processes hosting activities start. 534 */ 535 int mLruProcessActivityStart = 0; 536 537 /** 538 * Where in mLruProcesses that the processes hosting services start. 539 * This is after (lower index) than mLruProcessesActivityStart. 540 */ 541 int mLruProcessServiceStart = 0; 542 543 /** 544 * List of processes that should gc as soon as things are idle. 545 */ 546 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 547 548 /** 549 * Processes we want to collect PSS data from. 550 */ 551 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 552 553 /** 554 * Last time we requested PSS data of all processes. 555 */ 556 long mLastFullPssTime = SystemClock.uptimeMillis(); 557 558 /** 559 * This is the process holding what we currently consider to be 560 * the "home" activity. 561 */ 562 ProcessRecord mHomeProcess; 563 564 /** 565 * This is the process holding the activity the user last visited that 566 * is in a different process from the one they are currently in. 567 */ 568 ProcessRecord mPreviousProcess; 569 570 /** 571 * The time at which the previous process was last visible. 572 */ 573 long mPreviousProcessVisibleTime; 574 575 /** 576 * Which uses have been started, so are allowed to run code. 577 */ 578 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 579 580 /** 581 * LRU list of history of current users. Most recently current is at the end. 582 */ 583 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 584 585 /** 586 * Constant array of the users that are currently started. 587 */ 588 int[] mStartedUserArray = new int[] { 0 }; 589 590 /** 591 * Registered observers of the user switching mechanics. 592 */ 593 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 594 = new RemoteCallbackList<IUserSwitchObserver>(); 595 596 /** 597 * Currently active user switch. 598 */ 599 Object mCurUserSwitchCallback; 600 601 /** 602 * Packages that the user has asked to have run in screen size 603 * compatibility mode instead of filling the screen. 604 */ 605 final CompatModePackages mCompatModePackages; 606 607 /** 608 * Set of IntentSenderRecord objects that are currently active. 609 */ 610 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 611 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 612 613 /** 614 * Fingerprints (hashCode()) of stack traces that we've 615 * already logged DropBox entries for. Guarded by itself. If 616 * something (rogue user app) forces this over 617 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 618 */ 619 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 620 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 621 622 /** 623 * Strict Mode background batched logging state. 624 * 625 * The string buffer is guarded by itself, and its lock is also 626 * used to determine if another batched write is already 627 * in-flight. 628 */ 629 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 630 631 /** 632 * Keeps track of all IIntentReceivers that have been registered for 633 * broadcasts. Hash keys are the receiver IBinder, hash value is 634 * a ReceiverList. 635 */ 636 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 637 new HashMap<IBinder, ReceiverList>(); 638 639 /** 640 * Resolver for broadcast intents to registered receivers. 641 * Holds BroadcastFilter (subclass of IntentFilter). 642 */ 643 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 644 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 645 @Override 646 protected boolean allowFilterResult( 647 BroadcastFilter filter, List<BroadcastFilter> dest) { 648 IBinder target = filter.receiverList.receiver.asBinder(); 649 for (int i=dest.size()-1; i>=0; i--) { 650 if (dest.get(i).receiverList.receiver.asBinder() == target) { 651 return false; 652 } 653 } 654 return true; 655 } 656 657 @Override 658 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 659 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 660 || userId == filter.owningUserId) { 661 return super.newResult(filter, match, userId); 662 } 663 return null; 664 } 665 666 @Override 667 protected BroadcastFilter[] newArray(int size) { 668 return new BroadcastFilter[size]; 669 } 670 671 @Override 672 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 673 return packageName.equals(filter.packageName); 674 } 675 }; 676 677 /** 678 * State of all active sticky broadcasts per user. Keys are the action of the 679 * sticky Intent, values are an ArrayList of all broadcasted intents with 680 * that action (which should usually be one). The SparseArray is keyed 681 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 682 * for stickies that are sent to all users. 683 */ 684 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 685 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 686 687 final ActiveServices mServices; 688 689 /** 690 * Backup/restore process management 691 */ 692 String mBackupAppName = null; 693 BackupRecord mBackupTarget = null; 694 695 /** 696 * List of PendingThumbnailsRecord objects of clients who are still 697 * waiting to receive all of the thumbnails for a task. 698 */ 699 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 700 new ArrayList<PendingThumbnailsRecord>(); 701 702 final ProviderMap mProviderMap; 703 704 /** 705 * List of content providers who have clients waiting for them. The 706 * application is currently being launched and the provider will be 707 * removed from this list once it is published. 708 */ 709 final ArrayList<ContentProviderRecord> mLaunchingProviders 710 = new ArrayList<ContentProviderRecord>(); 711 712 /** 713 * File storing persisted {@link #mGrantedUriPermissions}. 714 */ 715 private final AtomicFile mGrantFile; 716 717 /** XML constants used in {@link #mGrantFile} */ 718 private static final String TAG_URI_GRANTS = "uri-grants"; 719 private static final String TAG_URI_GRANT = "uri-grant"; 720 private static final String ATTR_USER_HANDLE = "userHandle"; 721 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 722 private static final String ATTR_TARGET_PKG = "targetPkg"; 723 private static final String ATTR_URI = "uri"; 724 private static final String ATTR_MODE_FLAGS = "modeFlags"; 725 private static final String ATTR_CREATED_TIME = "createdTime"; 726 727 /** 728 * Global set of specific {@link Uri} permissions that have been granted. 729 * This optimized lookup structure maps from {@link UriPermission#targetUid} 730 * to {@link UriPermission#uri} to {@link UriPermission}. 731 */ 732 @GuardedBy("this") 733 private final SparseArray<ArrayMap<Uri, UriPermission>> 734 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 735 736 CoreSettingsObserver mCoreSettingsObserver; 737 738 /** 739 * Thread-local storage used to carry caller permissions over through 740 * indirect content-provider access. 741 */ 742 private class Identity { 743 public int pid; 744 public int uid; 745 746 Identity(int _pid, int _uid) { 747 pid = _pid; 748 uid = _uid; 749 } 750 } 751 752 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 753 754 /** 755 * All information we have collected about the runtime performance of 756 * any user id that can impact battery performance. 757 */ 758 final BatteryStatsService mBatteryStatsService; 759 760 /** 761 * Information about component usage 762 */ 763 final UsageStatsService mUsageStatsService; 764 765 /** 766 * Information about and control over application operations 767 */ 768 final AppOpsService mAppOpsService; 769 770 /** 771 * Current configuration information. HistoryRecord objects are given 772 * a reference to this object to indicate which configuration they are 773 * currently running in, so this object must be kept immutable. 774 */ 775 Configuration mConfiguration = new Configuration(); 776 777 /** 778 * Current sequencing integer of the configuration, for skipping old 779 * configurations. 780 */ 781 int mConfigurationSeq = 0; 782 783 /** 784 * Hardware-reported OpenGLES version. 785 */ 786 final int GL_ES_VERSION; 787 788 /** 789 * List of initialization arguments to pass to all processes when binding applications to them. 790 * For example, references to the commonly used services. 791 */ 792 HashMap<String, IBinder> mAppBindArgs; 793 794 /** 795 * Temporary to avoid allocations. Protected by main lock. 796 */ 797 final StringBuilder mStringBuilder = new StringBuilder(256); 798 799 /** 800 * Used to control how we initialize the service. 801 */ 802 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 increasing the ANR timeouts in that case. 930 */ 931 boolean mDidDexOpt; 932 933 String mDebugApp = null; 934 boolean mWaitForDebugger = false; 935 boolean mDebugTransient = false; 936 String mOrigDebugApp = null; 937 boolean mOrigWaitForDebugger = false; 938 boolean mAlwaysFinishActivities = false; 939 IActivityController mController = null; 940 String mProfileApp = null; 941 ProcessRecord mProfileProc = null; 942 String mProfileFile; 943 ParcelFileDescriptor mProfileFd; 944 int mProfileType = 0; 945 boolean mAutoStopProfiler = false; 946 String mOpenGlTraceApp = null; 947 948 static class ProcessChangeItem { 949 static final int CHANGE_ACTIVITIES = 1<<0; 950 static final int CHANGE_IMPORTANCE= 1<<1; 951 int changes; 952 int uid; 953 int pid; 954 int importance; 955 boolean foregroundActivities; 956 } 957 958 final RemoteCallbackList<IProcessObserver> mProcessObservers 959 = new RemoteCallbackList<IProcessObserver>(); 960 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 961 962 final ArrayList<ProcessChangeItem> mPendingProcessChanges 963 = new ArrayList<ProcessChangeItem>(); 964 final ArrayList<ProcessChangeItem> mAvailProcessChanges 965 = new ArrayList<ProcessChangeItem>(); 966 967 /** 968 * Runtime CPU use collection thread. This object's lock is used to 969 * protect all related state. 970 */ 971 final Thread mProcessCpuThread; 972 973 /** 974 * Used to collect process stats when showing not responding dialog. 975 * Protected by mProcessCpuThread. 976 */ 977 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 978 MONITOR_THREAD_CPU_USAGE); 979 final AtomicLong mLastCpuTime = new AtomicLong(0); 980 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 981 982 long mLastWriteTime = 0; 983 984 /** 985 * Used to retain an update lock when the foreground activity is in 986 * immersive mode. 987 */ 988 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 989 990 /** 991 * Set to true after the system has finished booting. 992 */ 993 boolean mBooted = false; 994 995 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 996 int mProcessLimitOverride = -1; 997 998 WindowManagerService mWindowManager; 999 1000 final ActivityThread mSystemThread; 1001 1002 int mCurrentUserId = 0; 1003 private UserManagerService mUserManager; 1004 1005 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1006 final ProcessRecord mApp; 1007 final int mPid; 1008 final IApplicationThread mAppThread; 1009 1010 AppDeathRecipient(ProcessRecord app, int pid, 1011 IApplicationThread thread) { 1012 if (localLOGV) Slog.v( 1013 TAG, "New death recipient " + this 1014 + " for thread " + thread.asBinder()); 1015 mApp = app; 1016 mPid = pid; 1017 mAppThread = thread; 1018 } 1019 1020 @Override 1021 public void binderDied() { 1022 if (localLOGV) Slog.v( 1023 TAG, "Death received in " + this 1024 + " for thread " + mAppThread.asBinder()); 1025 synchronized(ActivityManagerService.this) { 1026 appDiedLocked(mApp, mPid, mAppThread); 1027 } 1028 } 1029 } 1030 1031 static final int SHOW_ERROR_MSG = 1; 1032 static final int SHOW_NOT_RESPONDING_MSG = 2; 1033 static final int SHOW_FACTORY_ERROR_MSG = 3; 1034 static final int UPDATE_CONFIGURATION_MSG = 4; 1035 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1036 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1037 static final int SERVICE_TIMEOUT_MSG = 12; 1038 static final int UPDATE_TIME_ZONE = 13; 1039 static final int SHOW_UID_ERROR_MSG = 14; 1040 static final int IM_FEELING_LUCKY_MSG = 15; 1041 static final int PROC_START_TIMEOUT_MSG = 20; 1042 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1043 static final int KILL_APPLICATION_MSG = 22; 1044 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1045 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1046 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1047 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1048 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1049 static final int CLEAR_DNS_CACHE_MSG = 28; 1050 static final int UPDATE_HTTP_PROXY_MSG = 29; 1051 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1052 static final int DISPATCH_PROCESSES_CHANGED = 31; 1053 static final int DISPATCH_PROCESS_DIED = 32; 1054 static final int REPORT_MEM_USAGE_MSG = 33; 1055 static final int REPORT_USER_SWITCH_MSG = 34; 1056 static final int CONTINUE_USER_SWITCH_MSG = 35; 1057 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1058 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1059 static final int PERSIST_URI_GRANTS_MSG = 38; 1060 static final int REQUEST_ALL_PSS_MSG = 39; 1061 1062 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1063 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1064 static final int FIRST_COMPAT_MODE_MSG = 300; 1065 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1066 1067 AlertDialog mUidAlert; 1068 CompatModeDialog mCompatModeDialog; 1069 long mLastMemUsageReportTime = 0; 1070 1071 /** 1072 * Flag whether the current user is a "monkey", i.e. whether 1073 * the UI is driven by a UI automation tool. 1074 */ 1075 private boolean mUserIsMonkey; 1076 1077 final ServiceThread mHandlerThread; 1078 final MainHandler mHandler; 1079 1080 final class MainHandler extends Handler { 1081 public MainHandler(Looper looper) { 1082 super(looper, null, true); 1083 } 1084 1085 @Override 1086 public void handleMessage(Message msg) { 1087 switch (msg.what) { 1088 case SHOW_ERROR_MSG: { 1089 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1090 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1091 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1092 synchronized (ActivityManagerService.this) { 1093 ProcessRecord proc = (ProcessRecord)data.get("app"); 1094 AppErrorResult res = (AppErrorResult) data.get("result"); 1095 if (proc != null && proc.crashDialog != null) { 1096 Slog.e(TAG, "App already has crash dialog: " + proc); 1097 if (res != null) { 1098 res.set(0); 1099 } 1100 return; 1101 } 1102 if (!showBackground && UserHandle.getAppId(proc.uid) 1103 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1104 && proc.pid != MY_PID) { 1105 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1106 if (res != null) { 1107 res.set(0); 1108 } 1109 return; 1110 } 1111 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1112 Dialog d = new AppErrorDialog(mContext, 1113 ActivityManagerService.this, res, proc); 1114 d.show(); 1115 proc.crashDialog = d; 1116 } else { 1117 // The device is asleep, so just pretend that the user 1118 // saw a crash dialog and hit "force quit". 1119 if (res != null) { 1120 res.set(0); 1121 } 1122 } 1123 } 1124 1125 ensureBootCompleted(); 1126 } break; 1127 case SHOW_NOT_RESPONDING_MSG: { 1128 synchronized (ActivityManagerService.this) { 1129 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1130 ProcessRecord proc = (ProcessRecord)data.get("app"); 1131 if (proc != null && proc.anrDialog != null) { 1132 Slog.e(TAG, "App already has anr dialog: " + proc); 1133 return; 1134 } 1135 1136 Intent intent = new Intent("android.intent.action.ANR"); 1137 if (!mProcessesReady) { 1138 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1139 | Intent.FLAG_RECEIVER_FOREGROUND); 1140 } 1141 broadcastIntentLocked(null, null, intent, 1142 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1143 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1144 1145 if (mShowDialogs) { 1146 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1147 mContext, proc, (ActivityRecord)data.get("activity"), 1148 msg.arg1 != 0); 1149 d.show(); 1150 proc.anrDialog = d; 1151 } else { 1152 // Just kill the app if there is no dialog to be shown. 1153 killAppAtUsersRequest(proc, null); 1154 } 1155 } 1156 1157 ensureBootCompleted(); 1158 } break; 1159 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1160 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1161 synchronized (ActivityManagerService.this) { 1162 ProcessRecord proc = (ProcessRecord) data.get("app"); 1163 if (proc == null) { 1164 Slog.e(TAG, "App not found when showing strict mode dialog."); 1165 break; 1166 } 1167 if (proc.crashDialog != null) { 1168 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1169 return; 1170 } 1171 AppErrorResult res = (AppErrorResult) data.get("result"); 1172 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1173 Dialog d = new StrictModeViolationDialog(mContext, 1174 ActivityManagerService.this, res, proc); 1175 d.show(); 1176 proc.crashDialog = d; 1177 } else { 1178 // The device is asleep, so just pretend that the user 1179 // saw a crash dialog and hit "force quit". 1180 res.set(0); 1181 } 1182 } 1183 ensureBootCompleted(); 1184 } break; 1185 case SHOW_FACTORY_ERROR_MSG: { 1186 Dialog d = new FactoryErrorDialog( 1187 mContext, msg.getData().getCharSequence("msg")); 1188 d.show(); 1189 ensureBootCompleted(); 1190 } break; 1191 case UPDATE_CONFIGURATION_MSG: { 1192 final ContentResolver resolver = mContext.getContentResolver(); 1193 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1194 } break; 1195 case GC_BACKGROUND_PROCESSES_MSG: { 1196 synchronized (ActivityManagerService.this) { 1197 performAppGcsIfAppropriateLocked(); 1198 } 1199 } break; 1200 case WAIT_FOR_DEBUGGER_MSG: { 1201 synchronized (ActivityManagerService.this) { 1202 ProcessRecord app = (ProcessRecord)msg.obj; 1203 if (msg.arg1 != 0) { 1204 if (!app.waitedForDebugger) { 1205 Dialog d = new AppWaitingForDebuggerDialog( 1206 ActivityManagerService.this, 1207 mContext, app); 1208 app.waitDialog = d; 1209 app.waitedForDebugger = true; 1210 d.show(); 1211 } 1212 } else { 1213 if (app.waitDialog != null) { 1214 app.waitDialog.dismiss(); 1215 app.waitDialog = null; 1216 } 1217 } 1218 } 1219 } break; 1220 case SERVICE_TIMEOUT_MSG: { 1221 if (mDidDexOpt) { 1222 mDidDexOpt = false; 1223 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1224 nmsg.obj = msg.obj; 1225 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1226 return; 1227 } 1228 mServices.serviceTimeout((ProcessRecord)msg.obj); 1229 } break; 1230 case UPDATE_TIME_ZONE: { 1231 synchronized (ActivityManagerService.this) { 1232 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1233 ProcessRecord r = mLruProcesses.get(i); 1234 if (r.thread != null) { 1235 try { 1236 r.thread.updateTimeZone(); 1237 } catch (RemoteException ex) { 1238 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1239 } 1240 } 1241 } 1242 } 1243 } break; 1244 case CLEAR_DNS_CACHE_MSG: { 1245 synchronized (ActivityManagerService.this) { 1246 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1247 ProcessRecord r = mLruProcesses.get(i); 1248 if (r.thread != null) { 1249 try { 1250 r.thread.clearDnsCache(); 1251 } catch (RemoteException ex) { 1252 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1253 } 1254 } 1255 } 1256 } 1257 } break; 1258 case UPDATE_HTTP_PROXY_MSG: { 1259 ProxyProperties proxy = (ProxyProperties)msg.obj; 1260 String host = ""; 1261 String port = ""; 1262 String exclList = ""; 1263 String pacFileUrl = null; 1264 if (proxy != null) { 1265 host = proxy.getHost(); 1266 port = Integer.toString(proxy.getPort()); 1267 exclList = proxy.getExclusionList(); 1268 pacFileUrl = proxy.getPacFileUrl(); 1269 } 1270 synchronized (ActivityManagerService.this) { 1271 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1272 ProcessRecord r = mLruProcesses.get(i); 1273 if (r.thread != null) { 1274 try { 1275 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1276 } catch (RemoteException ex) { 1277 Slog.w(TAG, "Failed to update http proxy for: " + 1278 r.info.processName); 1279 } 1280 } 1281 } 1282 } 1283 } break; 1284 case SHOW_UID_ERROR_MSG: { 1285 String title = "System UIDs Inconsistent"; 1286 String text = "UIDs on the system are inconsistent, you need to wipe your" 1287 + " data partition or your device will be unstable."; 1288 Log.e(TAG, title + ": " + text); 1289 if (mShowDialogs) { 1290 // XXX This is a temporary dialog, no need to localize. 1291 AlertDialog d = new BaseErrorDialog(mContext); 1292 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1293 d.setCancelable(false); 1294 d.setTitle(title); 1295 d.setMessage(text); 1296 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1297 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1298 mUidAlert = d; 1299 d.show(); 1300 } 1301 } break; 1302 case IM_FEELING_LUCKY_MSG: { 1303 if (mUidAlert != null) { 1304 mUidAlert.dismiss(); 1305 mUidAlert = null; 1306 } 1307 } break; 1308 case PROC_START_TIMEOUT_MSG: { 1309 if (mDidDexOpt) { 1310 mDidDexOpt = false; 1311 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1312 nmsg.obj = msg.obj; 1313 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1314 return; 1315 } 1316 ProcessRecord app = (ProcessRecord)msg.obj; 1317 synchronized (ActivityManagerService.this) { 1318 processStartTimedOutLocked(app); 1319 } 1320 } break; 1321 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1322 synchronized (ActivityManagerService.this) { 1323 doPendingActivityLaunchesLocked(true); 1324 } 1325 } break; 1326 case KILL_APPLICATION_MSG: { 1327 synchronized (ActivityManagerService.this) { 1328 int appid = msg.arg1; 1329 boolean restart = (msg.arg2 == 1); 1330 Bundle bundle = (Bundle)msg.obj; 1331 String pkg = bundle.getString("pkg"); 1332 String reason = bundle.getString("reason"); 1333 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1334 UserHandle.USER_ALL, reason); 1335 } 1336 } break; 1337 case FINALIZE_PENDING_INTENT_MSG: { 1338 ((PendingIntentRecord)msg.obj).completeFinalize(); 1339 } break; 1340 case POST_HEAVY_NOTIFICATION_MSG: { 1341 INotificationManager inm = NotificationManager.getService(); 1342 if (inm == null) { 1343 return; 1344 } 1345 1346 ActivityRecord root = (ActivityRecord)msg.obj; 1347 ProcessRecord process = root.app; 1348 if (process == null) { 1349 return; 1350 } 1351 1352 try { 1353 Context context = mContext.createPackageContext(process.info.packageName, 0); 1354 String text = mContext.getString(R.string.heavy_weight_notification, 1355 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1356 Notification notification = new Notification(); 1357 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1358 notification.when = 0; 1359 notification.flags = Notification.FLAG_ONGOING_EVENT; 1360 notification.tickerText = text; 1361 notification.defaults = 0; // please be quiet 1362 notification.sound = null; 1363 notification.vibrate = null; 1364 notification.setLatestEventInfo(context, text, 1365 mContext.getText(R.string.heavy_weight_notification_detail), 1366 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1367 PendingIntent.FLAG_CANCEL_CURRENT, null, 1368 new UserHandle(root.userId))); 1369 1370 try { 1371 int[] outId = new int[1]; 1372 inm.enqueueNotificationWithTag("android", "android", null, 1373 R.string.heavy_weight_notification, 1374 notification, outId, root.userId); 1375 } catch (RuntimeException e) { 1376 Slog.w(ActivityManagerService.TAG, 1377 "Error showing notification for heavy-weight app", e); 1378 } catch (RemoteException e) { 1379 } 1380 } catch (NameNotFoundException e) { 1381 Slog.w(TAG, "Unable to create context for heavy notification", e); 1382 } 1383 } break; 1384 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1385 INotificationManager inm = NotificationManager.getService(); 1386 if (inm == null) { 1387 return; 1388 } 1389 try { 1390 inm.cancelNotificationWithTag("android", null, 1391 R.string.heavy_weight_notification, msg.arg1); 1392 } catch (RuntimeException e) { 1393 Slog.w(ActivityManagerService.TAG, 1394 "Error canceling notification for service", e); 1395 } catch (RemoteException e) { 1396 } 1397 } break; 1398 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1399 synchronized (ActivityManagerService.this) { 1400 checkExcessivePowerUsageLocked(true); 1401 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1402 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1403 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1404 } 1405 } break; 1406 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1407 synchronized (ActivityManagerService.this) { 1408 ActivityRecord ar = (ActivityRecord)msg.obj; 1409 if (mCompatModeDialog != null) { 1410 if (mCompatModeDialog.mAppInfo.packageName.equals( 1411 ar.info.applicationInfo.packageName)) { 1412 return; 1413 } 1414 mCompatModeDialog.dismiss(); 1415 mCompatModeDialog = null; 1416 } 1417 if (ar != null && false) { 1418 if (mCompatModePackages.getPackageAskCompatModeLocked( 1419 ar.packageName)) { 1420 int mode = mCompatModePackages.computeCompatModeLocked( 1421 ar.info.applicationInfo); 1422 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1423 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1424 mCompatModeDialog = new CompatModeDialog( 1425 ActivityManagerService.this, mContext, 1426 ar.info.applicationInfo); 1427 mCompatModeDialog.show(); 1428 } 1429 } 1430 } 1431 } 1432 break; 1433 } 1434 case DISPATCH_PROCESSES_CHANGED: { 1435 dispatchProcessesChanged(); 1436 break; 1437 } 1438 case DISPATCH_PROCESS_DIED: { 1439 final int pid = msg.arg1; 1440 final int uid = msg.arg2; 1441 dispatchProcessDied(pid, uid); 1442 break; 1443 } 1444 case REPORT_MEM_USAGE_MSG: { 1445 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1446 Thread thread = new Thread() { 1447 @Override public void run() { 1448 final SparseArray<ProcessMemInfo> infoMap 1449 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1450 for (int i=0, N=memInfos.size(); i<N; i++) { 1451 ProcessMemInfo mi = memInfos.get(i); 1452 infoMap.put(mi.pid, mi); 1453 } 1454 updateCpuStatsNow(); 1455 synchronized (mProcessCpuThread) { 1456 final int N = mProcessCpuTracker.countStats(); 1457 for (int i=0; i<N; i++) { 1458 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1459 if (st.vsize > 0) { 1460 long pss = Debug.getPss(st.pid, null); 1461 if (pss > 0) { 1462 if (infoMap.indexOfKey(st.pid) < 0) { 1463 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1464 ProcessList.NATIVE_ADJ, -1, "native", null); 1465 mi.pss = pss; 1466 memInfos.add(mi); 1467 } 1468 } 1469 } 1470 } 1471 } 1472 1473 long totalPss = 0; 1474 for (int i=0, N=memInfos.size(); i<N; i++) { 1475 ProcessMemInfo mi = memInfos.get(i); 1476 if (mi.pss == 0) { 1477 mi.pss = Debug.getPss(mi.pid, null); 1478 } 1479 totalPss += mi.pss; 1480 } 1481 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1482 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1483 if (lhs.oomAdj != rhs.oomAdj) { 1484 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1485 } 1486 if (lhs.pss != rhs.pss) { 1487 return lhs.pss < rhs.pss ? 1 : -1; 1488 } 1489 return 0; 1490 } 1491 }); 1492 1493 StringBuilder tag = new StringBuilder(128); 1494 StringBuilder stack = new StringBuilder(128); 1495 tag.append("Low on memory -- "); 1496 appendMemBucket(tag, totalPss, "total", false); 1497 appendMemBucket(stack, totalPss, "total", true); 1498 1499 StringBuilder logBuilder = new StringBuilder(1024); 1500 logBuilder.append("Low on memory:\n"); 1501 1502 boolean firstLine = true; 1503 int lastOomAdj = Integer.MIN_VALUE; 1504 for (int i=0, N=memInfos.size(); i<N; i++) { 1505 ProcessMemInfo mi = memInfos.get(i); 1506 1507 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1508 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1509 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1510 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1511 if (lastOomAdj != mi.oomAdj) { 1512 lastOomAdj = mi.oomAdj; 1513 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1514 tag.append(" / "); 1515 } 1516 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1517 if (firstLine) { 1518 stack.append(":"); 1519 firstLine = false; 1520 } 1521 stack.append("\n\t at "); 1522 } else { 1523 stack.append("$"); 1524 } 1525 } else { 1526 tag.append(" "); 1527 stack.append("$"); 1528 } 1529 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1530 appendMemBucket(tag, mi.pss, mi.name, false); 1531 } 1532 appendMemBucket(stack, mi.pss, mi.name, true); 1533 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1534 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1535 stack.append("("); 1536 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1537 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1538 stack.append(DUMP_MEM_OOM_LABEL[k]); 1539 stack.append(":"); 1540 stack.append(DUMP_MEM_OOM_ADJ[k]); 1541 } 1542 } 1543 stack.append(")"); 1544 } 1545 } 1546 1547 logBuilder.append(" "); 1548 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1549 logBuilder.append(' '); 1550 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1551 logBuilder.append(' '); 1552 ProcessList.appendRamKb(logBuilder, mi.pss); 1553 logBuilder.append(" kB: "); 1554 logBuilder.append(mi.name); 1555 logBuilder.append(" ("); 1556 logBuilder.append(mi.pid); 1557 logBuilder.append(") "); 1558 logBuilder.append(mi.adjType); 1559 logBuilder.append('\n'); 1560 if (mi.adjReason != null) { 1561 logBuilder.append(" "); 1562 logBuilder.append(mi.adjReason); 1563 logBuilder.append('\n'); 1564 } 1565 } 1566 1567 logBuilder.append(" "); 1568 ProcessList.appendRamKb(logBuilder, totalPss); 1569 logBuilder.append(" kB: TOTAL\n"); 1570 1571 long[] infos = new long[Debug.MEMINFO_COUNT]; 1572 Debug.getMemInfo(infos); 1573 logBuilder.append(" MemInfo: "); 1574 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1575 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1576 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1577 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1578 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1579 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1580 logBuilder.append(" ZRAM: "); 1581 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1582 logBuilder.append(" kB RAM, "); 1583 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1584 logBuilder.append(" kB swap total, "); 1585 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1586 logBuilder.append(" kB swap free\n"); 1587 } 1588 Slog.i(TAG, logBuilder.toString()); 1589 1590 StringBuilder dropBuilder = new StringBuilder(1024); 1591 /* 1592 StringWriter oomSw = new StringWriter(); 1593 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1594 StringWriter catSw = new StringWriter(); 1595 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1596 String[] emptyArgs = new String[] { }; 1597 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1598 oomPw.flush(); 1599 String oomString = oomSw.toString(); 1600 */ 1601 dropBuilder.append(stack); 1602 dropBuilder.append('\n'); 1603 dropBuilder.append('\n'); 1604 dropBuilder.append(logBuilder); 1605 dropBuilder.append('\n'); 1606 /* 1607 dropBuilder.append(oomString); 1608 dropBuilder.append('\n'); 1609 */ 1610 StringWriter catSw = new StringWriter(); 1611 synchronized (ActivityManagerService.this) { 1612 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1613 String[] emptyArgs = new String[] { }; 1614 catPw.println(); 1615 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1616 catPw.println(); 1617 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1618 false, false, null); 1619 catPw.println(); 1620 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1621 catPw.flush(); 1622 } 1623 dropBuilder.append(catSw.toString()); 1624 addErrorToDropBox("lowmem", null, "system_server", null, 1625 null, tag.toString(), dropBuilder.toString(), null, null); 1626 //Slog.i(TAG, "Sent to dropbox:"); 1627 //Slog.i(TAG, dropBuilder.toString()); 1628 synchronized (ActivityManagerService.this) { 1629 long now = SystemClock.uptimeMillis(); 1630 if (mLastMemUsageReportTime < now) { 1631 mLastMemUsageReportTime = now; 1632 } 1633 } 1634 } 1635 }; 1636 thread.start(); 1637 break; 1638 } 1639 case REPORT_USER_SWITCH_MSG: { 1640 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1641 break; 1642 } 1643 case CONTINUE_USER_SWITCH_MSG: { 1644 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1645 break; 1646 } 1647 case USER_SWITCH_TIMEOUT_MSG: { 1648 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1649 break; 1650 } 1651 case IMMERSIVE_MODE_LOCK_MSG: { 1652 final boolean nextState = (msg.arg1 != 0); 1653 if (mUpdateLock.isHeld() != nextState) { 1654 if (DEBUG_IMMERSIVE) { 1655 final ActivityRecord r = (ActivityRecord) msg.obj; 1656 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1657 } 1658 if (nextState) { 1659 mUpdateLock.acquire(); 1660 } else { 1661 mUpdateLock.release(); 1662 } 1663 } 1664 break; 1665 } 1666 case PERSIST_URI_GRANTS_MSG: { 1667 writeGrantedUriPermissions(); 1668 break; 1669 } 1670 case REQUEST_ALL_PSS_MSG: { 1671 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1672 break; 1673 } 1674 } 1675 } 1676 }; 1677 1678 static final int COLLECT_PSS_BG_MSG = 1; 1679 1680 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1681 @Override 1682 public void handleMessage(Message msg) { 1683 switch (msg.what) { 1684 case COLLECT_PSS_BG_MSG: { 1685 int i=0, num=0; 1686 long start = SystemClock.uptimeMillis(); 1687 long[] tmp = new long[1]; 1688 do { 1689 ProcessRecord proc; 1690 int procState; 1691 int pid; 1692 synchronized (ActivityManagerService.this) { 1693 if (i >= mPendingPssProcesses.size()) { 1694 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1695 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1696 mPendingPssProcesses.clear(); 1697 return; 1698 } 1699 proc = mPendingPssProcesses.get(i); 1700 procState = proc.pssProcState; 1701 if (proc.thread != null && procState == proc.setProcState) { 1702 pid = proc.pid; 1703 } else { 1704 proc = null; 1705 pid = 0; 1706 } 1707 i++; 1708 } 1709 if (proc != null) { 1710 long pss = Debug.getPss(pid, tmp); 1711 synchronized (ActivityManagerService.this) { 1712 if (proc.thread != null && proc.setProcState == procState 1713 && proc.pid == pid) { 1714 num++; 1715 proc.lastPssTime = SystemClock.uptimeMillis(); 1716 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1717 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1718 + ": " + pss + " lastPss=" + proc.lastPss 1719 + " state=" + ProcessList.makeProcStateString(procState)); 1720 if (proc.initialIdlePss == 0) { 1721 proc.initialIdlePss = pss; 1722 } 1723 proc.lastPss = pss; 1724 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1725 proc.lastCachedPss = pss; 1726 } 1727 } 1728 } 1729 } 1730 } while (true); 1731 } 1732 } 1733 } 1734 }; 1735 1736 public void setSystemProcess() { 1737 try { 1738 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1739 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1740 ServiceManager.addService("meminfo", new MemBinder(this)); 1741 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1742 ServiceManager.addService("dbinfo", new DbBinder(this)); 1743 if (MONITOR_CPU_USAGE) { 1744 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1745 } 1746 ServiceManager.addService("permission", new PermissionController(this)); 1747 1748 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1749 "android", STOCK_PM_FLAGS); 1750 mSystemThread.installSystemApplicationInfo(info); 1751 1752 synchronized (this) { 1753 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1754 app.persistent = true; 1755 app.pid = MY_PID; 1756 app.maxAdj = ProcessList.SYSTEM_ADJ; 1757 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1758 mProcessNames.put(app.processName, app.uid, app); 1759 synchronized (mPidsSelfLocked) { 1760 mPidsSelfLocked.put(app.pid, app); 1761 } 1762 updateLruProcessLocked(app, false, null); 1763 updateOomAdjLocked(); 1764 } 1765 } catch (PackageManager.NameNotFoundException e) { 1766 throw new RuntimeException( 1767 "Unable to find android system package", e); 1768 } 1769 } 1770 1771 public void setWindowManager(WindowManagerService wm) { 1772 mWindowManager = wm; 1773 mStackSupervisor.setWindowManager(wm); 1774 } 1775 1776 public void startObservingNativeCrashes() { 1777 final NativeCrashListener ncl = new NativeCrashListener(this); 1778 ncl.start(); 1779 } 1780 1781 public IAppOpsService getAppOpsService() { 1782 return mAppOpsService; 1783 } 1784 1785 static class MemBinder extends Binder { 1786 ActivityManagerService mActivityManagerService; 1787 MemBinder(ActivityManagerService activityManagerService) { 1788 mActivityManagerService = activityManagerService; 1789 } 1790 1791 @Override 1792 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1793 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1794 != PackageManager.PERMISSION_GRANTED) { 1795 pw.println("Permission Denial: can't dump meminfo from from pid=" 1796 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1797 + " without permission " + android.Manifest.permission.DUMP); 1798 return; 1799 } 1800 1801 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1802 } 1803 } 1804 1805 static class GraphicsBinder extends Binder { 1806 ActivityManagerService mActivityManagerService; 1807 GraphicsBinder(ActivityManagerService activityManagerService) { 1808 mActivityManagerService = activityManagerService; 1809 } 1810 1811 @Override 1812 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1813 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1814 != PackageManager.PERMISSION_GRANTED) { 1815 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1816 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1817 + " without permission " + android.Manifest.permission.DUMP); 1818 return; 1819 } 1820 1821 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1822 } 1823 } 1824 1825 static class DbBinder extends Binder { 1826 ActivityManagerService mActivityManagerService; 1827 DbBinder(ActivityManagerService activityManagerService) { 1828 mActivityManagerService = activityManagerService; 1829 } 1830 1831 @Override 1832 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1833 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1834 != PackageManager.PERMISSION_GRANTED) { 1835 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1836 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1837 + " without permission " + android.Manifest.permission.DUMP); 1838 return; 1839 } 1840 1841 mActivityManagerService.dumpDbInfo(fd, pw, args); 1842 } 1843 } 1844 1845 static class CpuBinder extends Binder { 1846 ActivityManagerService mActivityManagerService; 1847 CpuBinder(ActivityManagerService activityManagerService) { 1848 mActivityManagerService = activityManagerService; 1849 } 1850 1851 @Override 1852 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1853 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1854 != PackageManager.PERMISSION_GRANTED) { 1855 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1856 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1857 + " without permission " + android.Manifest.permission.DUMP); 1858 return; 1859 } 1860 1861 synchronized (mActivityManagerService.mProcessCpuThread) { 1862 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1863 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1864 SystemClock.uptimeMillis())); 1865 } 1866 } 1867 } 1868 1869 public static final class Lifecycle extends SystemService { 1870 private final ActivityManagerService mService; 1871 1872 public Lifecycle(Context context) { 1873 super(context); 1874 mService = new ActivityManagerService(context); 1875 } 1876 1877 @Override 1878 public void onStart() { 1879 mService.start(); 1880 } 1881 1882 public ActivityManagerService getService() { 1883 return mService; 1884 } 1885 } 1886 1887 // Note: This method is invoked on the main thread but may need to attach various 1888 // handlers to other threads. So take care to be explicit about the looper. 1889 public ActivityManagerService(Context systemContext) { 1890 mContext = systemContext; 1891 mFactoryTest = FactoryTest.getMode(); 1892 mSystemThread = ActivityThread.currentActivityThread(); 1893 1894 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1895 1896 mHandlerThread = new ServiceThread(TAG, 1897 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1898 mHandlerThread.start(); 1899 mHandler = new MainHandler(mHandlerThread.getLooper()); 1900 1901 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1902 "foreground", BROADCAST_FG_TIMEOUT, false); 1903 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1904 "background", BROADCAST_BG_TIMEOUT, true); 1905 mBroadcastQueues[0] = mFgBroadcastQueue; 1906 mBroadcastQueues[1] = mBgBroadcastQueue; 1907 1908 mServices = new ActiveServices(this); 1909 mProviderMap = new ProviderMap(this); 1910 1911 // TODO: Move creation of battery stats service outside of activity manager service. 1912 File dataDir = Environment.getDataDirectory(); 1913 File systemDir = new File(dataDir, "system"); 1914 systemDir.mkdirs(); 1915 mBatteryStatsService = new BatteryStatsService(new File( 1916 systemDir, "batterystats.bin").toString(), mHandler); 1917 mBatteryStatsService.getActiveStatistics().readLocked(); 1918 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1919 mOnBattery = DEBUG_POWER ? true 1920 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1921 mBatteryStatsService.getActiveStatistics().setCallback(this); 1922 1923 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1924 1925 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1926 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1927 1928 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1929 1930 // User 0 is the first and only user that runs at boot. 1931 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1932 mUserLru.add(Integer.valueOf(0)); 1933 updateStartedUserArrayLocked(); 1934 1935 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1936 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1937 1938 mConfiguration.setToDefaults(); 1939 mConfiguration.setLocale(Locale.getDefault()); 1940 1941 mConfigurationSeq = mConfiguration.seq = 1; 1942 mProcessCpuTracker.init(); 1943 1944 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1945 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1946 mStackSupervisor = new ActivityStackSupervisor(this); 1947 1948 mProcessCpuThread = new Thread("CpuTracker") { 1949 @Override 1950 public void run() { 1951 while (true) { 1952 try { 1953 try { 1954 synchronized(this) { 1955 final long now = SystemClock.uptimeMillis(); 1956 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1957 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1958 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1959 // + ", write delay=" + nextWriteDelay); 1960 if (nextWriteDelay < nextCpuDelay) { 1961 nextCpuDelay = nextWriteDelay; 1962 } 1963 if (nextCpuDelay > 0) { 1964 mProcessCpuMutexFree.set(true); 1965 this.wait(nextCpuDelay); 1966 } 1967 } 1968 } catch (InterruptedException e) { 1969 } 1970 updateCpuStatsNow(); 1971 } catch (Exception e) { 1972 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1973 } 1974 } 1975 } 1976 }; 1977 1978 Watchdog.getInstance().addMonitor(this); 1979 Watchdog.getInstance().addThread(mHandler); 1980 } 1981 1982 private void start() { 1983 mProcessCpuThread.start(); 1984 1985 mBatteryStatsService.publish(mContext); 1986 mUsageStatsService.publish(mContext); 1987 mAppOpsService.publish(mContext); 1988 1989 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 1990 } 1991 1992 @Override 1993 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1994 throws RemoteException { 1995 if (code == SYSPROPS_TRANSACTION) { 1996 // We need to tell all apps about the system property change. 1997 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1998 synchronized(this) { 1999 final int NP = mProcessNames.getMap().size(); 2000 for (int ip=0; ip<NP; ip++) { 2001 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2002 final int NA = apps.size(); 2003 for (int ia=0; ia<NA; ia++) { 2004 ProcessRecord app = apps.valueAt(ia); 2005 if (app.thread != null) { 2006 procs.add(app.thread.asBinder()); 2007 } 2008 } 2009 } 2010 } 2011 2012 int N = procs.size(); 2013 for (int i=0; i<N; i++) { 2014 Parcel data2 = Parcel.obtain(); 2015 try { 2016 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2017 } catch (RemoteException e) { 2018 } 2019 data2.recycle(); 2020 } 2021 } 2022 try { 2023 return super.onTransact(code, data, reply, flags); 2024 } catch (RuntimeException e) { 2025 // The activity manager only throws security exceptions, so let's 2026 // log all others. 2027 if (!(e instanceof SecurityException)) { 2028 Slog.wtf(TAG, "Activity Manager Crash", e); 2029 } 2030 throw e; 2031 } 2032 } 2033 2034 void updateCpuStats() { 2035 final long now = SystemClock.uptimeMillis(); 2036 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2037 return; 2038 } 2039 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2040 synchronized (mProcessCpuThread) { 2041 mProcessCpuThread.notify(); 2042 } 2043 } 2044 } 2045 2046 void updateCpuStatsNow() { 2047 synchronized (mProcessCpuThread) { 2048 mProcessCpuMutexFree.set(false); 2049 final long now = SystemClock.uptimeMillis(); 2050 boolean haveNewCpuStats = false; 2051 2052 if (MONITOR_CPU_USAGE && 2053 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2054 mLastCpuTime.set(now); 2055 haveNewCpuStats = true; 2056 mProcessCpuTracker.update(); 2057 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2058 //Slog.i(TAG, "Total CPU usage: " 2059 // + mProcessCpu.getTotalCpuPercent() + "%"); 2060 2061 // Slog the cpu usage if the property is set. 2062 if ("true".equals(SystemProperties.get("events.cpu"))) { 2063 int user = mProcessCpuTracker.getLastUserTime(); 2064 int system = mProcessCpuTracker.getLastSystemTime(); 2065 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2066 int irq = mProcessCpuTracker.getLastIrqTime(); 2067 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2068 int idle = mProcessCpuTracker.getLastIdleTime(); 2069 2070 int total = user + system + iowait + irq + softIrq + idle; 2071 if (total == 0) total = 1; 2072 2073 EventLog.writeEvent(EventLogTags.CPU, 2074 ((user+system+iowait+irq+softIrq) * 100) / total, 2075 (user * 100) / total, 2076 (system * 100) / total, 2077 (iowait * 100) / total, 2078 (irq * 100) / total, 2079 (softIrq * 100) / total); 2080 } 2081 } 2082 2083 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2084 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2085 synchronized(bstats) { 2086 synchronized(mPidsSelfLocked) { 2087 if (haveNewCpuStats) { 2088 if (mOnBattery) { 2089 int perc = bstats.startAddingCpuLocked(); 2090 int totalUTime = 0; 2091 int totalSTime = 0; 2092 final int N = mProcessCpuTracker.countStats(); 2093 for (int i=0; i<N; i++) { 2094 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2095 if (!st.working) { 2096 continue; 2097 } 2098 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2099 int otherUTime = (st.rel_utime*perc)/100; 2100 int otherSTime = (st.rel_stime*perc)/100; 2101 totalUTime += otherUTime; 2102 totalSTime += otherSTime; 2103 if (pr != null) { 2104 BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked( 2105 st.name, st.pid); 2106 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2107 st.rel_stime-otherSTime); 2108 ps.addSpeedStepTimes(cpuSpeedTimes); 2109 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2110 } else if (st.uid >= Process.FIRST_APPLICATION_UID) { 2111 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2112 if (ps == null) { 2113 st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid, 2114 "(Unknown)"); 2115 } 2116 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2117 st.rel_stime-otherSTime); 2118 ps.addSpeedStepTimes(cpuSpeedTimes); 2119 } else { 2120 BatteryStatsImpl.Uid.Proc ps = 2121 bstats.getProcessStatsLocked(st.name, st.pid); 2122 if (ps != null) { 2123 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2124 st.rel_stime-otherSTime); 2125 ps.addSpeedStepTimes(cpuSpeedTimes); 2126 } 2127 } 2128 } 2129 bstats.finishAddingCpuLocked(perc, totalUTime, 2130 totalSTime, cpuSpeedTimes); 2131 } 2132 } 2133 } 2134 2135 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2136 mLastWriteTime = now; 2137 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2138 } 2139 } 2140 } 2141 } 2142 2143 @Override 2144 public void batteryNeedsCpuUpdate() { 2145 updateCpuStatsNow(); 2146 } 2147 2148 @Override 2149 public void batteryPowerChanged(boolean onBattery) { 2150 // When plugging in, update the CPU stats first before changing 2151 // the plug state. 2152 updateCpuStatsNow(); 2153 synchronized (this) { 2154 synchronized(mPidsSelfLocked) { 2155 mOnBattery = DEBUG_POWER ? true : onBattery; 2156 } 2157 } 2158 } 2159 2160 /** 2161 * Initialize the application bind args. These are passed to each 2162 * process when the bindApplication() IPC is sent to the process. They're 2163 * lazily setup to make sure the services are running when they're asked for. 2164 */ 2165 private HashMap<String, IBinder> getCommonServicesLocked() { 2166 if (mAppBindArgs == null) { 2167 mAppBindArgs = new HashMap<String, IBinder>(); 2168 2169 // Setup the application init args 2170 mAppBindArgs.put("package", ServiceManager.getService("package")); 2171 mAppBindArgs.put("window", ServiceManager.getService("window")); 2172 mAppBindArgs.put(Context.ALARM_SERVICE, 2173 ServiceManager.getService(Context.ALARM_SERVICE)); 2174 } 2175 return mAppBindArgs; 2176 } 2177 2178 final void setFocusedActivityLocked(ActivityRecord r) { 2179 if (mFocusedActivity != r) { 2180 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2181 mFocusedActivity = r; 2182 mStackSupervisor.setFocusedStack(r); 2183 if (r != null) { 2184 mWindowManager.setFocusedApp(r.appToken, true); 2185 } 2186 applyUpdateLockStateLocked(r); 2187 } 2188 } 2189 2190 @Override 2191 public void setFocusedStack(int stackId) { 2192 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2193 synchronized (ActivityManagerService.this) { 2194 ActivityStack stack = mStackSupervisor.getStack(stackId); 2195 if (stack != null) { 2196 ActivityRecord r = stack.topRunningActivityLocked(null); 2197 if (r != null) { 2198 setFocusedActivityLocked(r); 2199 } 2200 } 2201 } 2202 } 2203 2204 @Override 2205 public void notifyActivityDrawn(IBinder token) { 2206 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2207 synchronized (this) { 2208 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2209 if (r != null) { 2210 r.task.stack.notifyActivityDrawnLocked(r); 2211 } 2212 } 2213 } 2214 2215 final void applyUpdateLockStateLocked(ActivityRecord r) { 2216 // Modifications to the UpdateLock state are done on our handler, outside 2217 // the activity manager's locks. The new state is determined based on the 2218 // state *now* of the relevant activity record. The object is passed to 2219 // the handler solely for logging detail, not to be consulted/modified. 2220 final boolean nextState = r != null && r.immersive; 2221 mHandler.sendMessage( 2222 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2223 } 2224 2225 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2226 Message msg = Message.obtain(); 2227 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2228 msg.obj = r.task.askedCompatMode ? null : r; 2229 mHandler.sendMessage(msg); 2230 } 2231 2232 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2233 String what, Object obj, ProcessRecord srcApp) { 2234 app.lastActivityTime = now; 2235 2236 if (app.activities.size() > 0) { 2237 // Don't want to touch dependent processes that are hosting activities. 2238 return index; 2239 } 2240 2241 int lrui = mLruProcesses.lastIndexOf(app); 2242 if (lrui < 0) { 2243 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2244 + what + " " + obj + " from " + srcApp); 2245 return index; 2246 } 2247 2248 if (lrui >= index) { 2249 // Don't want to cause this to move dependent processes *back* in the 2250 // list as if they were less frequently used. 2251 return index; 2252 } 2253 2254 if (lrui >= mLruProcessActivityStart) { 2255 // Don't want to touch dependent processes that are hosting activities. 2256 return index; 2257 } 2258 2259 mLruProcesses.remove(lrui); 2260 if (index > 0) { 2261 index--; 2262 } 2263 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2264 + " in LRU list: " + app); 2265 mLruProcesses.add(index, app); 2266 return index; 2267 } 2268 2269 final void removeLruProcessLocked(ProcessRecord app) { 2270 int lrui = mLruProcesses.lastIndexOf(app); 2271 if (lrui >= 0) { 2272 if (lrui <= mLruProcessActivityStart) { 2273 mLruProcessActivityStart--; 2274 } 2275 if (lrui <= mLruProcessServiceStart) { 2276 mLruProcessServiceStart--; 2277 } 2278 mLruProcesses.remove(lrui); 2279 } 2280 } 2281 2282 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2283 ProcessRecord client) { 2284 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities; 2285 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2286 if (!activityChange && hasActivity) { 2287 // The process has activties, so we are only going to allow activity-based 2288 // adjustments move it. It should be kept in the front of the list with other 2289 // processes that have activities, and we don't want those to change their 2290 // order except due to activity operations. 2291 return; 2292 } 2293 2294 mLruSeq++; 2295 final long now = SystemClock.uptimeMillis(); 2296 app.lastActivityTime = now; 2297 2298 // First a quick reject: if the app is already at the position we will 2299 // put it, then there is nothing to do. 2300 if (hasActivity) { 2301 final int N = mLruProcesses.size(); 2302 if (N > 0 && mLruProcesses.get(N-1) == app) { 2303 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2304 return; 2305 } 2306 } else { 2307 if (mLruProcessServiceStart > 0 2308 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2309 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2310 return; 2311 } 2312 } 2313 2314 int lrui = mLruProcesses.lastIndexOf(app); 2315 2316 if (app.persistent && lrui >= 0) { 2317 // We don't care about the position of persistent processes, as long as 2318 // they are in the list. 2319 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2320 return; 2321 } 2322 2323 /* In progress: compute new position first, so we can avoid doing work 2324 if the process is not actually going to move. Not yet working. 2325 int addIndex; 2326 int nextIndex; 2327 boolean inActivity = false, inService = false; 2328 if (hasActivity) { 2329 // Process has activities, put it at the very tipsy-top. 2330 addIndex = mLruProcesses.size(); 2331 nextIndex = mLruProcessServiceStart; 2332 inActivity = true; 2333 } else if (hasService) { 2334 // Process has services, put it at the top of the service list. 2335 addIndex = mLruProcessActivityStart; 2336 nextIndex = mLruProcessServiceStart; 2337 inActivity = true; 2338 inService = true; 2339 } else { 2340 // Process not otherwise of interest, it goes to the top of the non-service area. 2341 addIndex = mLruProcessServiceStart; 2342 if (client != null) { 2343 int clientIndex = mLruProcesses.lastIndexOf(client); 2344 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2345 + app); 2346 if (clientIndex >= 0 && addIndex > clientIndex) { 2347 addIndex = clientIndex; 2348 } 2349 } 2350 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2351 } 2352 2353 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2354 + mLruProcessActivityStart + "): " + app); 2355 */ 2356 2357 if (lrui >= 0) { 2358 if (lrui < mLruProcessActivityStart) { 2359 mLruProcessActivityStart--; 2360 } 2361 if (lrui < mLruProcessServiceStart) { 2362 mLruProcessServiceStart--; 2363 } 2364 /* 2365 if (addIndex > lrui) { 2366 addIndex--; 2367 } 2368 if (nextIndex > lrui) { 2369 nextIndex--; 2370 } 2371 */ 2372 mLruProcesses.remove(lrui); 2373 } 2374 2375 /* 2376 mLruProcesses.add(addIndex, app); 2377 if (inActivity) { 2378 mLruProcessActivityStart++; 2379 } 2380 if (inService) { 2381 mLruProcessActivityStart++; 2382 } 2383 */ 2384 2385 int nextIndex; 2386 if (hasActivity) { 2387 final int N = mLruProcesses.size(); 2388 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2389 // Process doesn't have activities, but has clients with 2390 // activities... move it up, but one below the top (the top 2391 // should always have a real activity). 2392 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2393 mLruProcesses.add(N-1, app); 2394 // To keep it from spamming the LRU list (by making a bunch of clients), 2395 // we will push down any other entries owned by the app. 2396 final int uid = app.info.uid; 2397 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2398 ProcessRecord subProc = mLruProcesses.get(i); 2399 if (subProc.info.uid == uid) { 2400 // We want to push this one down the list. If the process after 2401 // it is for the same uid, however, don't do so, because we don't 2402 // want them internally to be re-ordered. 2403 if (mLruProcesses.get(i-1).info.uid != uid) { 2404 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2405 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2406 ProcessRecord tmp = mLruProcesses.get(i); 2407 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2408 mLruProcesses.set(i-1, tmp); 2409 i--; 2410 } 2411 } else { 2412 // A gap, we can stop here. 2413 break; 2414 } 2415 } 2416 } else { 2417 // Process has activities, put it at the very tipsy-top. 2418 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2419 mLruProcesses.add(app); 2420 } 2421 nextIndex = mLruProcessServiceStart; 2422 } else if (hasService) { 2423 // Process has services, put it at the top of the service list. 2424 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2425 mLruProcesses.add(mLruProcessActivityStart, app); 2426 nextIndex = mLruProcessServiceStart; 2427 mLruProcessActivityStart++; 2428 } else { 2429 // Process not otherwise of interest, it goes to the top of the non-service area. 2430 int index = mLruProcessServiceStart; 2431 if (client != null) { 2432 // If there is a client, don't allow the process to be moved up higher 2433 // in the list than that client. 2434 int clientIndex = mLruProcesses.lastIndexOf(client); 2435 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2436 + " when updating " + app); 2437 if (clientIndex <= lrui) { 2438 // Don't allow the client index restriction to push it down farther in the 2439 // list than it already is. 2440 clientIndex = lrui; 2441 } 2442 if (clientIndex >= 0 && index > clientIndex) { 2443 index = clientIndex; 2444 } 2445 } 2446 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2447 mLruProcesses.add(index, app); 2448 nextIndex = index-1; 2449 mLruProcessActivityStart++; 2450 mLruProcessServiceStart++; 2451 } 2452 2453 // If the app is currently using a content provider or service, 2454 // bump those processes as well. 2455 for (int j=app.connections.size()-1; j>=0; j--) { 2456 ConnectionRecord cr = app.connections.valueAt(j); 2457 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2458 && cr.binding.service.app != null 2459 && cr.binding.service.app.lruSeq != mLruSeq 2460 && !cr.binding.service.app.persistent) { 2461 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2462 "service connection", cr, app); 2463 } 2464 } 2465 for (int j=app.conProviders.size()-1; j>=0; j--) { 2466 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2467 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2468 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2469 "provider reference", cpr, app); 2470 } 2471 } 2472 } 2473 2474 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2475 if (uid == Process.SYSTEM_UID) { 2476 // The system gets to run in any process. If there are multiple 2477 // processes with the same uid, just pick the first (this 2478 // should never happen). 2479 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2480 if (procs == null) return null; 2481 final int N = procs.size(); 2482 for (int i = 0; i < N; i++) { 2483 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2484 } 2485 } 2486 ProcessRecord proc = mProcessNames.get(processName, uid); 2487 if (false && proc != null && !keepIfLarge 2488 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2489 && proc.lastCachedPss >= 4000) { 2490 // Turn this condition on to cause killing to happen regularly, for testing. 2491 if (proc.baseProcessTracker != null) { 2492 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2493 } 2494 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2495 + "k from cached"); 2496 } else if (proc != null && !keepIfLarge 2497 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2498 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2499 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2500 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2501 if (proc.baseProcessTracker != null) { 2502 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2503 } 2504 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2505 + "k from cached"); 2506 } 2507 } 2508 return proc; 2509 } 2510 2511 void ensurePackageDexOpt(String packageName) { 2512 IPackageManager pm = AppGlobals.getPackageManager(); 2513 try { 2514 if (pm.performDexOpt(packageName)) { 2515 mDidDexOpt = true; 2516 } 2517 } catch (RemoteException e) { 2518 } 2519 } 2520 2521 boolean isNextTransitionForward() { 2522 int transit = mWindowManager.getPendingAppTransition(); 2523 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2524 || transit == AppTransition.TRANSIT_TASK_OPEN 2525 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2526 } 2527 2528 final ProcessRecord startProcessLocked(String processName, 2529 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2530 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2531 boolean isolated, boolean keepIfLarge) { 2532 ProcessRecord app; 2533 if (!isolated) { 2534 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2535 } else { 2536 // If this is an isolated process, it can't re-use an existing process. 2537 app = null; 2538 } 2539 // We don't have to do anything more if: 2540 // (1) There is an existing application record; and 2541 // (2) The caller doesn't think it is dead, OR there is no thread 2542 // object attached to it so we know it couldn't have crashed; and 2543 // (3) There is a pid assigned to it, so it is either starting or 2544 // already running. 2545 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2546 + " app=" + app + " knownToBeDead=" + knownToBeDead 2547 + " thread=" + (app != null ? app.thread : null) 2548 + " pid=" + (app != null ? app.pid : -1)); 2549 if (app != null && app.pid > 0) { 2550 if (!knownToBeDead || app.thread == null) { 2551 // We already have the app running, or are waiting for it to 2552 // come up (we have a pid but not yet its thread), so keep it. 2553 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2554 // If this is a new package in the process, add the package to the list 2555 app.addPackage(info.packageName, mProcessStats); 2556 return app; 2557 } 2558 2559 // An application record is attached to a previous process, 2560 // clean it up now. 2561 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2562 handleAppDiedLocked(app, true, true); 2563 } 2564 2565 String hostingNameStr = hostingName != null 2566 ? hostingName.flattenToShortString() : null; 2567 2568 if (!isolated) { 2569 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2570 // If we are in the background, then check to see if this process 2571 // is bad. If so, we will just silently fail. 2572 if (mBadProcesses.get(info.processName, info.uid) != null) { 2573 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2574 + "/" + info.processName); 2575 return null; 2576 } 2577 } else { 2578 // When the user is explicitly starting a process, then clear its 2579 // crash count so that we won't make it bad until they see at 2580 // least one crash dialog again, and make the process good again 2581 // if it had been bad. 2582 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2583 + "/" + info.processName); 2584 mProcessCrashTimes.remove(info.processName, info.uid); 2585 if (mBadProcesses.get(info.processName, info.uid) != null) { 2586 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2587 UserHandle.getUserId(info.uid), info.uid, 2588 info.processName); 2589 mBadProcesses.remove(info.processName, info.uid); 2590 if (app != null) { 2591 app.bad = false; 2592 } 2593 } 2594 } 2595 } 2596 2597 if (app == null) { 2598 app = newProcessRecordLocked(info, processName, isolated); 2599 if (app == null) { 2600 Slog.w(TAG, "Failed making new process record for " 2601 + processName + "/" + info.uid + " isolated=" + isolated); 2602 return null; 2603 } 2604 mProcessNames.put(processName, app.uid, app); 2605 if (isolated) { 2606 mIsolatedProcesses.put(app.uid, app); 2607 } 2608 } else { 2609 // If this is a new package in the process, add the package to the list 2610 app.addPackage(info.packageName, mProcessStats); 2611 } 2612 2613 // If the system is not ready yet, then hold off on starting this 2614 // process until it is. 2615 if (!mProcessesReady 2616 && !isAllowedWhileBooting(info) 2617 && !allowWhileBooting) { 2618 if (!mProcessesOnHold.contains(app)) { 2619 mProcessesOnHold.add(app); 2620 } 2621 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2622 return app; 2623 } 2624 2625 startProcessLocked(app, hostingType, hostingNameStr); 2626 return (app.pid != 0) ? app : null; 2627 } 2628 2629 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2630 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2631 } 2632 2633 private final void startProcessLocked(ProcessRecord app, 2634 String hostingType, String hostingNameStr) { 2635 if (app.pid > 0 && app.pid != MY_PID) { 2636 synchronized (mPidsSelfLocked) { 2637 mPidsSelfLocked.remove(app.pid); 2638 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2639 } 2640 app.setPid(0); 2641 } 2642 2643 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2644 "startProcessLocked removing on hold: " + app); 2645 mProcessesOnHold.remove(app); 2646 2647 updateCpuStats(); 2648 2649 try { 2650 int uid = app.uid; 2651 2652 int[] gids = null; 2653 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2654 if (!app.isolated) { 2655 int[] permGids = null; 2656 try { 2657 final PackageManager pm = mContext.getPackageManager(); 2658 permGids = pm.getPackageGids(app.info.packageName); 2659 2660 if (Environment.isExternalStorageEmulated()) { 2661 if (pm.checkPermission( 2662 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2663 app.info.packageName) == PERMISSION_GRANTED) { 2664 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2665 } else { 2666 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2667 } 2668 } 2669 } catch (PackageManager.NameNotFoundException e) { 2670 Slog.w(TAG, "Unable to retrieve gids", e); 2671 } 2672 2673 /* 2674 * Add shared application GID so applications can share some 2675 * resources like shared libraries 2676 */ 2677 if (permGids == null) { 2678 gids = new int[1]; 2679 } else { 2680 gids = new int[permGids.length + 1]; 2681 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2682 } 2683 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2684 } 2685 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2686 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2687 && mTopComponent != null 2688 && app.processName.equals(mTopComponent.getPackageName())) { 2689 uid = 0; 2690 } 2691 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2692 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2693 uid = 0; 2694 } 2695 } 2696 int debugFlags = 0; 2697 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2698 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2699 // Also turn on CheckJNI for debuggable apps. It's quite 2700 // awkward to turn on otherwise. 2701 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2702 } 2703 // Run the app in safe mode if its manifest requests so or the 2704 // system is booted in safe mode. 2705 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2706 Zygote.systemInSafeMode == true) { 2707 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2708 } 2709 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2710 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2711 } 2712 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2713 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2714 } 2715 if ("1".equals(SystemProperties.get("debug.assert"))) { 2716 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2717 } 2718 2719 // Start the process. It will either succeed and return a result containing 2720 // the PID of the new process, or else throw a RuntimeException. 2721 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2722 app.processName, uid, uid, gids, debugFlags, mountExternal, 2723 app.info.targetSdkVersion, app.info.seinfo, null); 2724 2725 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2726 synchronized (bs) { 2727 if (bs.isOnBattery()) { 2728 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2729 } 2730 } 2731 2732 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2733 UserHandle.getUserId(uid), startResult.pid, uid, 2734 app.processName, hostingType, 2735 hostingNameStr != null ? hostingNameStr : ""); 2736 2737 if (app.persistent) { 2738 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2739 } 2740 2741 StringBuilder buf = mStringBuilder; 2742 buf.setLength(0); 2743 buf.append("Start proc "); 2744 buf.append(app.processName); 2745 buf.append(" for "); 2746 buf.append(hostingType); 2747 if (hostingNameStr != null) { 2748 buf.append(" "); 2749 buf.append(hostingNameStr); 2750 } 2751 buf.append(": pid="); 2752 buf.append(startResult.pid); 2753 buf.append(" uid="); 2754 buf.append(uid); 2755 buf.append(" gids={"); 2756 if (gids != null) { 2757 for (int gi=0; gi<gids.length; gi++) { 2758 if (gi != 0) buf.append(", "); 2759 buf.append(gids[gi]); 2760 2761 } 2762 } 2763 buf.append("}"); 2764 Slog.i(TAG, buf.toString()); 2765 app.setPid(startResult.pid); 2766 app.usingWrapper = startResult.usingWrapper; 2767 app.removed = false; 2768 synchronized (mPidsSelfLocked) { 2769 this.mPidsSelfLocked.put(startResult.pid, app); 2770 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2771 msg.obj = app; 2772 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2773 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2774 } 2775 } catch (RuntimeException e) { 2776 // XXX do better error recovery. 2777 app.setPid(0); 2778 Slog.e(TAG, "Failure starting process " + app.processName, e); 2779 } 2780 } 2781 2782 void updateUsageStats(ActivityRecord component, boolean resumed) { 2783 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2784 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2785 if (resumed) { 2786 mUsageStatsService.noteResumeComponent(component.realActivity); 2787 synchronized (stats) { 2788 stats.noteActivityResumedLocked(component.app.uid); 2789 } 2790 } else { 2791 mUsageStatsService.notePauseComponent(component.realActivity); 2792 synchronized (stats) { 2793 stats.noteActivityPausedLocked(component.app.uid); 2794 } 2795 } 2796 } 2797 2798 Intent getHomeIntent() { 2799 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2800 intent.setComponent(mTopComponent); 2801 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2802 intent.addCategory(Intent.CATEGORY_HOME); 2803 } 2804 return intent; 2805 } 2806 2807 boolean startHomeActivityLocked(int userId) { 2808 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2809 && mTopAction == null) { 2810 // We are running in factory test mode, but unable to find 2811 // the factory test app, so just sit around displaying the 2812 // error message and don't try to start anything. 2813 return false; 2814 } 2815 Intent intent = getHomeIntent(); 2816 ActivityInfo aInfo = 2817 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2818 if (aInfo != null) { 2819 intent.setComponent(new ComponentName( 2820 aInfo.applicationInfo.packageName, aInfo.name)); 2821 // Don't do this if the home app is currently being 2822 // instrumented. 2823 aInfo = new ActivityInfo(aInfo); 2824 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2825 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2826 aInfo.applicationInfo.uid, true); 2827 if (app == null || app.instrumentationClass == null) { 2828 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2829 mStackSupervisor.startHomeActivity(intent, aInfo); 2830 } 2831 } 2832 2833 return true; 2834 } 2835 2836 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2837 ActivityInfo ai = null; 2838 ComponentName comp = intent.getComponent(); 2839 try { 2840 if (comp != null) { 2841 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2842 } else { 2843 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2844 intent, 2845 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2846 flags, userId); 2847 2848 if (info != null) { 2849 ai = info.activityInfo; 2850 } 2851 } 2852 } catch (RemoteException e) { 2853 // ignore 2854 } 2855 2856 return ai; 2857 } 2858 2859 /** 2860 * Starts the "new version setup screen" if appropriate. 2861 */ 2862 void startSetupActivityLocked() { 2863 // Only do this once per boot. 2864 if (mCheckedForSetup) { 2865 return; 2866 } 2867 2868 // We will show this screen if the current one is a different 2869 // version than the last one shown, and we are not running in 2870 // low-level factory test mode. 2871 final ContentResolver resolver = mContext.getContentResolver(); 2872 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2873 Settings.Global.getInt(resolver, 2874 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2875 mCheckedForSetup = true; 2876 2877 // See if we should be showing the platform update setup UI. 2878 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2879 List<ResolveInfo> ris = mContext.getPackageManager() 2880 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2881 2882 // We don't allow third party apps to replace this. 2883 ResolveInfo ri = null; 2884 for (int i=0; ris != null && i<ris.size(); i++) { 2885 if ((ris.get(i).activityInfo.applicationInfo.flags 2886 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2887 ri = ris.get(i); 2888 break; 2889 } 2890 } 2891 2892 if (ri != null) { 2893 String vers = ri.activityInfo.metaData != null 2894 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2895 : null; 2896 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2897 vers = ri.activityInfo.applicationInfo.metaData.getString( 2898 Intent.METADATA_SETUP_VERSION); 2899 } 2900 String lastVers = Settings.Secure.getString( 2901 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2902 if (vers != null && !vers.equals(lastVers)) { 2903 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2904 intent.setComponent(new ComponentName( 2905 ri.activityInfo.packageName, ri.activityInfo.name)); 2906 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2907 null, null, 0, 0, 0, null, 0, null, false, null, null); 2908 } 2909 } 2910 } 2911 } 2912 2913 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2914 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2915 } 2916 2917 void enforceNotIsolatedCaller(String caller) { 2918 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2919 throw new SecurityException("Isolated process not allowed to call " + caller); 2920 } 2921 } 2922 2923 @Override 2924 public int getFrontActivityScreenCompatMode() { 2925 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2926 synchronized (this) { 2927 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2928 } 2929 } 2930 2931 @Override 2932 public void setFrontActivityScreenCompatMode(int mode) { 2933 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2934 "setFrontActivityScreenCompatMode"); 2935 synchronized (this) { 2936 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2937 } 2938 } 2939 2940 @Override 2941 public int getPackageScreenCompatMode(String packageName) { 2942 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2943 synchronized (this) { 2944 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2945 } 2946 } 2947 2948 @Override 2949 public void setPackageScreenCompatMode(String packageName, int mode) { 2950 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2951 "setPackageScreenCompatMode"); 2952 synchronized (this) { 2953 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2954 } 2955 } 2956 2957 @Override 2958 public boolean getPackageAskScreenCompat(String packageName) { 2959 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2960 synchronized (this) { 2961 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2962 } 2963 } 2964 2965 @Override 2966 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2967 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2968 "setPackageAskScreenCompat"); 2969 synchronized (this) { 2970 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2971 } 2972 } 2973 2974 private void dispatchProcessesChanged() { 2975 int N; 2976 synchronized (this) { 2977 N = mPendingProcessChanges.size(); 2978 if (mActiveProcessChanges.length < N) { 2979 mActiveProcessChanges = new ProcessChangeItem[N]; 2980 } 2981 mPendingProcessChanges.toArray(mActiveProcessChanges); 2982 mAvailProcessChanges.addAll(mPendingProcessChanges); 2983 mPendingProcessChanges.clear(); 2984 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2985 } 2986 2987 int i = mProcessObservers.beginBroadcast(); 2988 while (i > 0) { 2989 i--; 2990 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2991 if (observer != null) { 2992 try { 2993 for (int j=0; j<N; j++) { 2994 ProcessChangeItem item = mActiveProcessChanges[j]; 2995 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2996 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2997 + item.pid + " uid=" + item.uid + ": " 2998 + item.foregroundActivities); 2999 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3000 item.foregroundActivities); 3001 } 3002 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3003 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3004 + item.pid + " uid=" + item.uid + ": " + item.importance); 3005 observer.onImportanceChanged(item.pid, item.uid, 3006 item.importance); 3007 } 3008 } 3009 } catch (RemoteException e) { 3010 } 3011 } 3012 } 3013 mProcessObservers.finishBroadcast(); 3014 } 3015 3016 private void dispatchProcessDied(int pid, int uid) { 3017 int i = mProcessObservers.beginBroadcast(); 3018 while (i > 0) { 3019 i--; 3020 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3021 if (observer != null) { 3022 try { 3023 observer.onProcessDied(pid, uid); 3024 } catch (RemoteException e) { 3025 } 3026 } 3027 } 3028 mProcessObservers.finishBroadcast(); 3029 } 3030 3031 final void doPendingActivityLaunchesLocked(boolean doResume) { 3032 final int N = mPendingActivityLaunches.size(); 3033 if (N <= 0) { 3034 return; 3035 } 3036 for (int i=0; i<N; i++) { 3037 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3038 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3039 doResume && i == (N-1), null); 3040 } 3041 mPendingActivityLaunches.clear(); 3042 } 3043 3044 @Override 3045 public final int startActivity(IApplicationThread caller, String callingPackage, 3046 Intent intent, String resolvedType, IBinder resultTo, 3047 String resultWho, int requestCode, int startFlags, 3048 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3049 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3050 resultWho, requestCode, 3051 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3052 } 3053 3054 @Override 3055 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3056 Intent intent, String resolvedType, IBinder resultTo, 3057 String resultWho, int requestCode, int startFlags, 3058 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3059 enforceNotIsolatedCaller("startActivity"); 3060 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3061 false, true, "startActivity", null); 3062 // TODO: Switch to user app stacks here. 3063 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3064 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3065 null, null, options, userId, null); 3066 } 3067 3068 @Override 3069 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3070 Intent intent, String resolvedType, IBinder resultTo, 3071 String resultWho, int requestCode, int startFlags, String profileFile, 3072 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3073 enforceNotIsolatedCaller("startActivityAndWait"); 3074 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3075 false, true, "startActivityAndWait", null); 3076 WaitResult res = new WaitResult(); 3077 // TODO: Switch to user app stacks here. 3078 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3079 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3080 res, null, options, UserHandle.getCallingUserId(), null); 3081 return res; 3082 } 3083 3084 @Override 3085 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3086 Intent intent, String resolvedType, IBinder resultTo, 3087 String resultWho, int requestCode, int startFlags, Configuration config, 3088 Bundle options, int userId) { 3089 enforceNotIsolatedCaller("startActivityWithConfig"); 3090 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3091 false, true, "startActivityWithConfig", null); 3092 // TODO: Switch to user app stacks here. 3093 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3094 resolvedType, resultTo, resultWho, requestCode, startFlags, 3095 null, null, null, config, options, userId, null); 3096 return ret; 3097 } 3098 3099 @Override 3100 public int startActivityIntentSender(IApplicationThread caller, 3101 IntentSender intent, Intent fillInIntent, String resolvedType, 3102 IBinder resultTo, String resultWho, int requestCode, 3103 int flagsMask, int flagsValues, Bundle options) { 3104 enforceNotIsolatedCaller("startActivityIntentSender"); 3105 // Refuse possible leaked file descriptors 3106 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3107 throw new IllegalArgumentException("File descriptors passed in Intent"); 3108 } 3109 3110 IIntentSender sender = intent.getTarget(); 3111 if (!(sender instanceof PendingIntentRecord)) { 3112 throw new IllegalArgumentException("Bad PendingIntent object"); 3113 } 3114 3115 PendingIntentRecord pir = (PendingIntentRecord)sender; 3116 3117 synchronized (this) { 3118 // If this is coming from the currently resumed activity, it is 3119 // effectively saying that app switches are allowed at this point. 3120 final ActivityStack stack = getFocusedStack(); 3121 if (stack.mResumedActivity != null && 3122 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3123 mAppSwitchesAllowedTime = 0; 3124 } 3125 } 3126 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3127 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3128 return ret; 3129 } 3130 3131 @Override 3132 public boolean startNextMatchingActivity(IBinder callingActivity, 3133 Intent intent, Bundle options) { 3134 // Refuse possible leaked file descriptors 3135 if (intent != null && intent.hasFileDescriptors() == true) { 3136 throw new IllegalArgumentException("File descriptors passed in Intent"); 3137 } 3138 3139 synchronized (this) { 3140 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3141 if (r == null) { 3142 ActivityOptions.abort(options); 3143 return false; 3144 } 3145 if (r.app == null || r.app.thread == null) { 3146 // The caller is not running... d'oh! 3147 ActivityOptions.abort(options); 3148 return false; 3149 } 3150 intent = new Intent(intent); 3151 // The caller is not allowed to change the data. 3152 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3153 // And we are resetting to find the next component... 3154 intent.setComponent(null); 3155 3156 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3157 3158 ActivityInfo aInfo = null; 3159 try { 3160 List<ResolveInfo> resolves = 3161 AppGlobals.getPackageManager().queryIntentActivities( 3162 intent, r.resolvedType, 3163 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3164 UserHandle.getCallingUserId()); 3165 3166 // Look for the original activity in the list... 3167 final int N = resolves != null ? resolves.size() : 0; 3168 for (int i=0; i<N; i++) { 3169 ResolveInfo rInfo = resolves.get(i); 3170 if (rInfo.activityInfo.packageName.equals(r.packageName) 3171 && rInfo.activityInfo.name.equals(r.info.name)) { 3172 // We found the current one... the next matching is 3173 // after it. 3174 i++; 3175 if (i<N) { 3176 aInfo = resolves.get(i).activityInfo; 3177 } 3178 if (debug) { 3179 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3180 + "/" + r.info.name); 3181 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3182 + "/" + aInfo.name); 3183 } 3184 break; 3185 } 3186 } 3187 } catch (RemoteException e) { 3188 } 3189 3190 if (aInfo == null) { 3191 // Nobody who is next! 3192 ActivityOptions.abort(options); 3193 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3194 return false; 3195 } 3196 3197 intent.setComponent(new ComponentName( 3198 aInfo.applicationInfo.packageName, aInfo.name)); 3199 intent.setFlags(intent.getFlags()&~( 3200 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3201 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3202 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3203 Intent.FLAG_ACTIVITY_NEW_TASK)); 3204 3205 // Okay now we need to start the new activity, replacing the 3206 // currently running activity. This is a little tricky because 3207 // we want to start the new one as if the current one is finished, 3208 // but not finish the current one first so that there is no flicker. 3209 // And thus... 3210 final boolean wasFinishing = r.finishing; 3211 r.finishing = true; 3212 3213 // Propagate reply information over to the new activity. 3214 final ActivityRecord resultTo = r.resultTo; 3215 final String resultWho = r.resultWho; 3216 final int requestCode = r.requestCode; 3217 r.resultTo = null; 3218 if (resultTo != null) { 3219 resultTo.removeResultsLocked(r, resultWho, requestCode); 3220 } 3221 3222 final long origId = Binder.clearCallingIdentity(); 3223 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3224 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3225 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3226 options, false, null, null); 3227 Binder.restoreCallingIdentity(origId); 3228 3229 r.finishing = wasFinishing; 3230 if (res != ActivityManager.START_SUCCESS) { 3231 return false; 3232 } 3233 return true; 3234 } 3235 } 3236 3237 final int startActivityInPackage(int uid, String callingPackage, 3238 Intent intent, String resolvedType, IBinder resultTo, 3239 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3240 IActivityContainer container) { 3241 3242 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3243 false, true, "startActivityInPackage", null); 3244 3245 // TODO: Switch to user app stacks here. 3246 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3247 resultTo, resultWho, requestCode, startFlags, 3248 null, null, null, null, options, userId, container); 3249 return ret; 3250 } 3251 3252 @Override 3253 public final int startActivities(IApplicationThread caller, String callingPackage, 3254 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3255 int userId) { 3256 enforceNotIsolatedCaller("startActivities"); 3257 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3258 false, true, "startActivity", null); 3259 // TODO: Switch to user app stacks here. 3260 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3261 resolvedTypes, resultTo, options, userId); 3262 return ret; 3263 } 3264 3265 final int startActivitiesInPackage(int uid, String callingPackage, 3266 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3267 Bundle options, int userId) { 3268 3269 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3270 false, true, "startActivityInPackage", null); 3271 // TODO: Switch to user app stacks here. 3272 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3273 resultTo, options, userId); 3274 return ret; 3275 } 3276 3277 final void addRecentTaskLocked(TaskRecord task) { 3278 int N = mRecentTasks.size(); 3279 // Quick case: check if the top-most recent task is the same. 3280 if (N > 0 && mRecentTasks.get(0) == task) { 3281 return; 3282 } 3283 // Remove any existing entries that are the same kind of task. 3284 for (int i=0; i<N; i++) { 3285 TaskRecord tr = mRecentTasks.get(i); 3286 if (task.userId == tr.userId 3287 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 3288 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 3289 tr.disposeThumbnail(); 3290 mRecentTasks.remove(i); 3291 i--; 3292 N--; 3293 if (task.intent == null) { 3294 // If the new recent task we are adding is not fully 3295 // specified, then replace it with the existing recent task. 3296 task = tr; 3297 } 3298 } 3299 } 3300 if (N >= MAX_RECENT_TASKS) { 3301 mRecentTasks.remove(N-1).disposeThumbnail(); 3302 } 3303 mRecentTasks.add(0, task); 3304 } 3305 3306 @Override 3307 public void reportActivityFullyDrawn(IBinder token) { 3308 synchronized (this) { 3309 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3310 if (r == null) { 3311 return; 3312 } 3313 r.reportFullyDrawnLocked(); 3314 } 3315 } 3316 3317 @Override 3318 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3319 synchronized (this) { 3320 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3321 if (r == null) { 3322 return; 3323 } 3324 final long origId = Binder.clearCallingIdentity(); 3325 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3326 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3327 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3328 if (config != null) { 3329 r.frozenBeforeDestroy = true; 3330 if (!updateConfigurationLocked(config, r, false, false)) { 3331 mStackSupervisor.resumeTopActivitiesLocked(); 3332 } 3333 } 3334 Binder.restoreCallingIdentity(origId); 3335 } 3336 } 3337 3338 @Override 3339 public int getRequestedOrientation(IBinder token) { 3340 synchronized (this) { 3341 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3342 if (r == null) { 3343 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3344 } 3345 return mWindowManager.getAppOrientation(r.appToken); 3346 } 3347 } 3348 3349 /** 3350 * This is the internal entry point for handling Activity.finish(). 3351 * 3352 * @param token The Binder token referencing the Activity we want to finish. 3353 * @param resultCode Result code, if any, from this Activity. 3354 * @param resultData Result data (Intent), if any, from this Activity. 3355 * 3356 * @return Returns true if the activity successfully finished, or false if it is still running. 3357 */ 3358 @Override 3359 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3360 // Refuse possible leaked file descriptors 3361 if (resultData != null && resultData.hasFileDescriptors() == true) { 3362 throw new IllegalArgumentException("File descriptors passed in Intent"); 3363 } 3364 3365 synchronized(this) { 3366 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3367 if (r == null) { 3368 return true; 3369 } 3370 if (mController != null) { 3371 // Find the first activity that is not finishing. 3372 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3373 if (next != null) { 3374 // ask watcher if this is allowed 3375 boolean resumeOK = true; 3376 try { 3377 resumeOK = mController.activityResuming(next.packageName); 3378 } catch (RemoteException e) { 3379 mController = null; 3380 Watchdog.getInstance().setActivityController(null); 3381 } 3382 3383 if (!resumeOK) { 3384 return false; 3385 } 3386 } 3387 } 3388 final long origId = Binder.clearCallingIdentity(); 3389 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3390 resultData, "app-request", true); 3391 Binder.restoreCallingIdentity(origId); 3392 return res; 3393 } 3394 } 3395 3396 @Override 3397 public final void finishHeavyWeightApp() { 3398 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3399 != PackageManager.PERMISSION_GRANTED) { 3400 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3401 + Binder.getCallingPid() 3402 + ", uid=" + Binder.getCallingUid() 3403 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3404 Slog.w(TAG, msg); 3405 throw new SecurityException(msg); 3406 } 3407 3408 synchronized(this) { 3409 if (mHeavyWeightProcess == null) { 3410 return; 3411 } 3412 3413 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3414 mHeavyWeightProcess.activities); 3415 for (int i=0; i<activities.size(); i++) { 3416 ActivityRecord r = activities.get(i); 3417 if (!r.finishing) { 3418 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3419 null, "finish-heavy", true); 3420 } 3421 } 3422 3423 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3424 mHeavyWeightProcess.userId, 0)); 3425 mHeavyWeightProcess = null; 3426 } 3427 } 3428 3429 @Override 3430 public void crashApplication(int uid, int initialPid, String packageName, 3431 String message) { 3432 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3433 != PackageManager.PERMISSION_GRANTED) { 3434 String msg = "Permission Denial: crashApplication() from pid=" 3435 + Binder.getCallingPid() 3436 + ", uid=" + Binder.getCallingUid() 3437 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3438 Slog.w(TAG, msg); 3439 throw new SecurityException(msg); 3440 } 3441 3442 synchronized(this) { 3443 ProcessRecord proc = null; 3444 3445 // Figure out which process to kill. We don't trust that initialPid 3446 // still has any relation to current pids, so must scan through the 3447 // list. 3448 synchronized (mPidsSelfLocked) { 3449 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3450 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3451 if (p.uid != uid) { 3452 continue; 3453 } 3454 if (p.pid == initialPid) { 3455 proc = p; 3456 break; 3457 } 3458 if (p.pkgList.containsKey(packageName)) { 3459 proc = p; 3460 } 3461 } 3462 } 3463 3464 if (proc == null) { 3465 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3466 + " initialPid=" + initialPid 3467 + " packageName=" + packageName); 3468 return; 3469 } 3470 3471 if (proc.thread != null) { 3472 if (proc.pid == Process.myPid()) { 3473 Log.w(TAG, "crashApplication: trying to crash self!"); 3474 return; 3475 } 3476 long ident = Binder.clearCallingIdentity(); 3477 try { 3478 proc.thread.scheduleCrash(message); 3479 } catch (RemoteException e) { 3480 } 3481 Binder.restoreCallingIdentity(ident); 3482 } 3483 } 3484 } 3485 3486 @Override 3487 public final void finishSubActivity(IBinder token, String resultWho, 3488 int requestCode) { 3489 synchronized(this) { 3490 final long origId = Binder.clearCallingIdentity(); 3491 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3492 if (r != null) { 3493 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3494 } 3495 Binder.restoreCallingIdentity(origId); 3496 } 3497 } 3498 3499 @Override 3500 public boolean finishActivityAffinity(IBinder token) { 3501 synchronized(this) { 3502 final long origId = Binder.clearCallingIdentity(); 3503 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3504 boolean res = false; 3505 if (r != null) { 3506 res = r.task.stack.finishActivityAffinityLocked(r); 3507 } 3508 Binder.restoreCallingIdentity(origId); 3509 return res; 3510 } 3511 } 3512 3513 @Override 3514 public boolean willActivityBeVisible(IBinder token) { 3515 synchronized(this) { 3516 ActivityStack stack = ActivityRecord.getStackLocked(token); 3517 if (stack != null) { 3518 return stack.willActivityBeVisibleLocked(token); 3519 } 3520 return false; 3521 } 3522 } 3523 3524 @Override 3525 public void overridePendingTransition(IBinder token, String packageName, 3526 int enterAnim, int exitAnim) { 3527 synchronized(this) { 3528 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3529 if (self == null) { 3530 return; 3531 } 3532 3533 final long origId = Binder.clearCallingIdentity(); 3534 3535 if (self.state == ActivityState.RESUMED 3536 || self.state == ActivityState.PAUSING) { 3537 mWindowManager.overridePendingAppTransition(packageName, 3538 enterAnim, exitAnim, null); 3539 } 3540 3541 Binder.restoreCallingIdentity(origId); 3542 } 3543 } 3544 3545 /** 3546 * Main function for removing an existing process from the activity manager 3547 * as a result of that process going away. Clears out all connections 3548 * to the process. 3549 */ 3550 private final void handleAppDiedLocked(ProcessRecord app, 3551 boolean restarting, boolean allowRestart) { 3552 int pid = app.pid; 3553 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3554 if (!restarting) { 3555 removeLruProcessLocked(app); 3556 if (pid > 0) { 3557 ProcessList.remove(pid); 3558 } 3559 } 3560 3561 if (mProfileProc == app) { 3562 clearProfilerLocked(); 3563 } 3564 3565 // Remove this application's activities from active lists. 3566 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3567 3568 app.activities.clear(); 3569 3570 if (app.instrumentationClass != null) { 3571 Slog.w(TAG, "Crash of app " + app.processName 3572 + " running instrumentation " + app.instrumentationClass); 3573 Bundle info = new Bundle(); 3574 info.putString("shortMsg", "Process crashed."); 3575 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3576 } 3577 3578 if (!restarting) { 3579 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3580 // If there was nothing to resume, and we are not already 3581 // restarting this process, but there is a visible activity that 3582 // is hosted by the process... then make sure all visible 3583 // activities are running, taking care of restarting this 3584 // process. 3585 if (hasVisibleActivities) { 3586 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3587 } 3588 } 3589 } 3590 } 3591 3592 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3593 IBinder threadBinder = thread.asBinder(); 3594 // Find the application record. 3595 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3596 ProcessRecord rec = mLruProcesses.get(i); 3597 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3598 return i; 3599 } 3600 } 3601 return -1; 3602 } 3603 3604 final ProcessRecord getRecordForAppLocked( 3605 IApplicationThread thread) { 3606 if (thread == null) { 3607 return null; 3608 } 3609 3610 int appIndex = getLRURecordIndexForAppLocked(thread); 3611 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3612 } 3613 3614 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3615 // If there are no longer any background processes running, 3616 // and the app that died was not running instrumentation, 3617 // then tell everyone we are now low on memory. 3618 boolean haveBg = false; 3619 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3620 ProcessRecord rec = mLruProcesses.get(i); 3621 if (rec.thread != null 3622 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3623 haveBg = true; 3624 break; 3625 } 3626 } 3627 3628 if (!haveBg) { 3629 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3630 if (doReport) { 3631 long now = SystemClock.uptimeMillis(); 3632 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3633 doReport = false; 3634 } else { 3635 mLastMemUsageReportTime = now; 3636 } 3637 } 3638 final ArrayList<ProcessMemInfo> memInfos 3639 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3640 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3641 long now = SystemClock.uptimeMillis(); 3642 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3643 ProcessRecord rec = mLruProcesses.get(i); 3644 if (rec == dyingProc || rec.thread == null) { 3645 continue; 3646 } 3647 if (doReport) { 3648 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3649 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3650 } 3651 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3652 // The low memory report is overriding any current 3653 // state for a GC request. Make sure to do 3654 // heavy/important/visible/foreground processes first. 3655 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3656 rec.lastRequestedGc = 0; 3657 } else { 3658 rec.lastRequestedGc = rec.lastLowMemory; 3659 } 3660 rec.reportLowMemory = true; 3661 rec.lastLowMemory = now; 3662 mProcessesToGc.remove(rec); 3663 addProcessToGcListLocked(rec); 3664 } 3665 } 3666 if (doReport) { 3667 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3668 mHandler.sendMessage(msg); 3669 } 3670 scheduleAppGcsLocked(); 3671 } 3672 } 3673 3674 final void appDiedLocked(ProcessRecord app, int pid, 3675 IApplicationThread thread) { 3676 3677 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3678 synchronized (stats) { 3679 stats.noteProcessDiedLocked(app.info.uid, pid); 3680 } 3681 3682 // Clean up already done if the process has been re-started. 3683 if (app.pid == pid && app.thread != null && 3684 app.thread.asBinder() == thread.asBinder()) { 3685 boolean doLowMem = app.instrumentationClass == null; 3686 boolean doOomAdj = doLowMem; 3687 if (!app.killedByAm) { 3688 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3689 + ") has died."); 3690 mAllowLowerMemLevel = true; 3691 } else { 3692 // Note that we always want to do oom adj to update our state with the 3693 // new number of procs. 3694 mAllowLowerMemLevel = false; 3695 doLowMem = false; 3696 } 3697 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3698 if (DEBUG_CLEANUP) Slog.v( 3699 TAG, "Dying app: " + app + ", pid: " + pid 3700 + ", thread: " + thread.asBinder()); 3701 handleAppDiedLocked(app, false, true); 3702 3703 if (doOomAdj) { 3704 updateOomAdjLocked(); 3705 } 3706 if (doLowMem) { 3707 doLowMemReportIfNeededLocked(app); 3708 } 3709 } else if (app.pid != pid) { 3710 // A new process has already been started. 3711 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3712 + ") has died and restarted (pid " + app.pid + ")."); 3713 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3714 } else if (DEBUG_PROCESSES) { 3715 Slog.d(TAG, "Received spurious death notification for thread " 3716 + thread.asBinder()); 3717 } 3718 } 3719 3720 /** 3721 * If a stack trace dump file is configured, dump process stack traces. 3722 * @param clearTraces causes the dump file to be erased prior to the new 3723 * traces being written, if true; when false, the new traces will be 3724 * appended to any existing file content. 3725 * @param firstPids of dalvik VM processes to dump stack traces for first 3726 * @param lastPids of dalvik VM processes to dump stack traces for last 3727 * @param nativeProcs optional list of native process names to dump stack crawls 3728 * @return file containing stack traces, or null if no dump file is configured 3729 */ 3730 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3731 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3732 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3733 if (tracesPath == null || tracesPath.length() == 0) { 3734 return null; 3735 } 3736 3737 File tracesFile = new File(tracesPath); 3738 try { 3739 File tracesDir = tracesFile.getParentFile(); 3740 if (!tracesDir.exists()) { 3741 tracesFile.mkdirs(); 3742 if (!SELinux.restorecon(tracesDir)) { 3743 return null; 3744 } 3745 } 3746 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3747 3748 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3749 tracesFile.createNewFile(); 3750 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3751 } catch (IOException e) { 3752 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3753 return null; 3754 } 3755 3756 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3757 return tracesFile; 3758 } 3759 3760 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3761 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3762 // Use a FileObserver to detect when traces finish writing. 3763 // The order of traces is considered important to maintain for legibility. 3764 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3765 @Override 3766 public synchronized void onEvent(int event, String path) { notify(); } 3767 }; 3768 3769 try { 3770 observer.startWatching(); 3771 3772 // First collect all of the stacks of the most important pids. 3773 if (firstPids != null) { 3774 try { 3775 int num = firstPids.size(); 3776 for (int i = 0; i < num; i++) { 3777 synchronized (observer) { 3778 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3779 observer.wait(200); // Wait for write-close, give up after 200msec 3780 } 3781 } 3782 } catch (InterruptedException e) { 3783 Log.wtf(TAG, e); 3784 } 3785 } 3786 3787 // Next collect the stacks of the native pids 3788 if (nativeProcs != null) { 3789 int[] pids = Process.getPidsForCommands(nativeProcs); 3790 if (pids != null) { 3791 for (int pid : pids) { 3792 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3793 } 3794 } 3795 } 3796 3797 // Lastly, measure CPU usage. 3798 if (processCpuTracker != null) { 3799 processCpuTracker.init(); 3800 System.gc(); 3801 processCpuTracker.update(); 3802 try { 3803 synchronized (processCpuTracker) { 3804 processCpuTracker.wait(500); // measure over 1/2 second. 3805 } 3806 } catch (InterruptedException e) { 3807 } 3808 processCpuTracker.update(); 3809 3810 // We'll take the stack crawls of just the top apps using CPU. 3811 final int N = processCpuTracker.countWorkingStats(); 3812 int numProcs = 0; 3813 for (int i=0; i<N && numProcs<5; i++) { 3814 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3815 if (lastPids.indexOfKey(stats.pid) >= 0) { 3816 numProcs++; 3817 try { 3818 synchronized (observer) { 3819 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3820 observer.wait(200); // Wait for write-close, give up after 200msec 3821 } 3822 } catch (InterruptedException e) { 3823 Log.wtf(TAG, e); 3824 } 3825 3826 } 3827 } 3828 } 3829 } finally { 3830 observer.stopWatching(); 3831 } 3832 } 3833 3834 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3835 if (true || IS_USER_BUILD) { 3836 return; 3837 } 3838 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3839 if (tracesPath == null || tracesPath.length() == 0) { 3840 return; 3841 } 3842 3843 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3844 StrictMode.allowThreadDiskWrites(); 3845 try { 3846 final File tracesFile = new File(tracesPath); 3847 final File tracesDir = tracesFile.getParentFile(); 3848 final File tracesTmp = new File(tracesDir, "__tmp__"); 3849 try { 3850 if (!tracesDir.exists()) { 3851 tracesFile.mkdirs(); 3852 if (!SELinux.restorecon(tracesDir.getPath())) { 3853 return; 3854 } 3855 } 3856 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3857 3858 if (tracesFile.exists()) { 3859 tracesTmp.delete(); 3860 tracesFile.renameTo(tracesTmp); 3861 } 3862 StringBuilder sb = new StringBuilder(); 3863 Time tobj = new Time(); 3864 tobj.set(System.currentTimeMillis()); 3865 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3866 sb.append(": "); 3867 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3868 sb.append(" since "); 3869 sb.append(msg); 3870 FileOutputStream fos = new FileOutputStream(tracesFile); 3871 fos.write(sb.toString().getBytes()); 3872 if (app == null) { 3873 fos.write("\n*** No application process!".getBytes()); 3874 } 3875 fos.close(); 3876 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3877 } catch (IOException e) { 3878 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3879 return; 3880 } 3881 3882 if (app != null) { 3883 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3884 firstPids.add(app.pid); 3885 dumpStackTraces(tracesPath, firstPids, null, null, null); 3886 } 3887 3888 File lastTracesFile = null; 3889 File curTracesFile = null; 3890 for (int i=9; i>=0; i--) { 3891 String name = String.format(Locale.US, "slow%02d.txt", i); 3892 curTracesFile = new File(tracesDir, name); 3893 if (curTracesFile.exists()) { 3894 if (lastTracesFile != null) { 3895 curTracesFile.renameTo(lastTracesFile); 3896 } else { 3897 curTracesFile.delete(); 3898 } 3899 } 3900 lastTracesFile = curTracesFile; 3901 } 3902 tracesFile.renameTo(curTracesFile); 3903 if (tracesTmp.exists()) { 3904 tracesTmp.renameTo(tracesFile); 3905 } 3906 } finally { 3907 StrictMode.setThreadPolicy(oldPolicy); 3908 } 3909 } 3910 3911 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3912 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3913 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3914 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3915 3916 if (mController != null) { 3917 try { 3918 // 0 == continue, -1 = kill process immediately 3919 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3920 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3921 } catch (RemoteException e) { 3922 mController = null; 3923 Watchdog.getInstance().setActivityController(null); 3924 } 3925 } 3926 3927 long anrTime = SystemClock.uptimeMillis(); 3928 if (MONITOR_CPU_USAGE) { 3929 updateCpuStatsNow(); 3930 } 3931 3932 synchronized (this) { 3933 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3934 if (mShuttingDown) { 3935 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3936 return; 3937 } else if (app.notResponding) { 3938 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3939 return; 3940 } else if (app.crashing) { 3941 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3942 return; 3943 } 3944 3945 // In case we come through here for the same app before completing 3946 // this one, mark as anring now so we will bail out. 3947 app.notResponding = true; 3948 3949 // Log the ANR to the event log. 3950 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3951 app.processName, app.info.flags, annotation); 3952 3953 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3954 firstPids.add(app.pid); 3955 3956 int parentPid = app.pid; 3957 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3958 if (parentPid != app.pid) firstPids.add(parentPid); 3959 3960 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3961 3962 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3963 ProcessRecord r = mLruProcesses.get(i); 3964 if (r != null && r.thread != null) { 3965 int pid = r.pid; 3966 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3967 if (r.persistent) { 3968 firstPids.add(pid); 3969 } else { 3970 lastPids.put(pid, Boolean.TRUE); 3971 } 3972 } 3973 } 3974 } 3975 } 3976 3977 // Log the ANR to the main log. 3978 StringBuilder info = new StringBuilder(); 3979 info.setLength(0); 3980 info.append("ANR in ").append(app.processName); 3981 if (activity != null && activity.shortComponentName != null) { 3982 info.append(" (").append(activity.shortComponentName).append(")"); 3983 } 3984 info.append("\n"); 3985 info.append("PID: ").append(app.pid).append("\n"); 3986 if (annotation != null) { 3987 info.append("Reason: ").append(annotation).append("\n"); 3988 } 3989 if (parent != null && parent != activity) { 3990 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3991 } 3992 3993 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 3994 3995 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 3996 NATIVE_STACKS_OF_INTEREST); 3997 3998 String cpuInfo = null; 3999 if (MONITOR_CPU_USAGE) { 4000 updateCpuStatsNow(); 4001 synchronized (mProcessCpuThread) { 4002 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4003 } 4004 info.append(processCpuTracker.printCurrentLoad()); 4005 info.append(cpuInfo); 4006 } 4007 4008 info.append(processCpuTracker.printCurrentState(anrTime)); 4009 4010 Slog.e(TAG, info.toString()); 4011 if (tracesFile == null) { 4012 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4013 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4014 } 4015 4016 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4017 cpuInfo, tracesFile, null); 4018 4019 if (mController != null) { 4020 try { 4021 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4022 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4023 if (res != 0) { 4024 if (res < 0 && app.pid != MY_PID) { 4025 Process.killProcess(app.pid); 4026 } else { 4027 synchronized (this) { 4028 mServices.scheduleServiceTimeoutLocked(app); 4029 } 4030 } 4031 return; 4032 } 4033 } catch (RemoteException e) { 4034 mController = null; 4035 Watchdog.getInstance().setActivityController(null); 4036 } 4037 } 4038 4039 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4040 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4041 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4042 4043 synchronized (this) { 4044 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4045 killUnneededProcessLocked(app, "background ANR"); 4046 return; 4047 } 4048 4049 // Set the app's notResponding state, and look up the errorReportReceiver 4050 makeAppNotRespondingLocked(app, 4051 activity != null ? activity.shortComponentName : null, 4052 annotation != null ? "ANR " + annotation : "ANR", 4053 info.toString()); 4054 4055 // Bring up the infamous App Not Responding dialog 4056 Message msg = Message.obtain(); 4057 HashMap<String, Object> map = new HashMap<String, Object>(); 4058 msg.what = SHOW_NOT_RESPONDING_MSG; 4059 msg.obj = map; 4060 msg.arg1 = aboveSystem ? 1 : 0; 4061 map.put("app", app); 4062 if (activity != null) { 4063 map.put("activity", activity); 4064 } 4065 4066 mHandler.sendMessage(msg); 4067 } 4068 } 4069 4070 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4071 if (!mLaunchWarningShown) { 4072 mLaunchWarningShown = true; 4073 mHandler.post(new Runnable() { 4074 @Override 4075 public void run() { 4076 synchronized (ActivityManagerService.this) { 4077 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4078 d.show(); 4079 mHandler.postDelayed(new Runnable() { 4080 @Override 4081 public void run() { 4082 synchronized (ActivityManagerService.this) { 4083 d.dismiss(); 4084 mLaunchWarningShown = false; 4085 } 4086 } 4087 }, 4000); 4088 } 4089 } 4090 }); 4091 } 4092 } 4093 4094 @Override 4095 public boolean clearApplicationUserData(final String packageName, 4096 final IPackageDataObserver observer, int userId) { 4097 enforceNotIsolatedCaller("clearApplicationUserData"); 4098 int uid = Binder.getCallingUid(); 4099 int pid = Binder.getCallingPid(); 4100 userId = handleIncomingUser(pid, uid, 4101 userId, false, true, "clearApplicationUserData", null); 4102 long callingId = Binder.clearCallingIdentity(); 4103 try { 4104 IPackageManager pm = AppGlobals.getPackageManager(); 4105 int pkgUid = -1; 4106 synchronized(this) { 4107 try { 4108 pkgUid = pm.getPackageUid(packageName, userId); 4109 } catch (RemoteException e) { 4110 } 4111 if (pkgUid == -1) { 4112 Slog.w(TAG, "Invalid packageName: " + packageName); 4113 if (observer != null) { 4114 try { 4115 observer.onRemoveCompleted(packageName, false); 4116 } catch (RemoteException e) { 4117 Slog.i(TAG, "Observer no longer exists."); 4118 } 4119 } 4120 return false; 4121 } 4122 if (uid == pkgUid || checkComponentPermission( 4123 android.Manifest.permission.CLEAR_APP_USER_DATA, 4124 pid, uid, -1, true) 4125 == PackageManager.PERMISSION_GRANTED) { 4126 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4127 } else { 4128 throw new SecurityException("PID " + pid + " does not have permission " 4129 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4130 + " of package " + packageName); 4131 } 4132 } 4133 4134 try { 4135 // Clear application user data 4136 pm.clearApplicationUserData(packageName, observer, userId); 4137 4138 // Remove all permissions granted from/to this package 4139 removeUriPermissionsForPackageLocked(packageName, userId, true); 4140 4141 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4142 Uri.fromParts("package", packageName, null)); 4143 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4144 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4145 null, null, 0, null, null, null, false, false, userId); 4146 } catch (RemoteException e) { 4147 } 4148 } finally { 4149 Binder.restoreCallingIdentity(callingId); 4150 } 4151 return true; 4152 } 4153 4154 @Override 4155 public void killBackgroundProcesses(final String packageName, int userId) { 4156 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4157 != PackageManager.PERMISSION_GRANTED && 4158 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4159 != PackageManager.PERMISSION_GRANTED) { 4160 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4161 + Binder.getCallingPid() 4162 + ", uid=" + Binder.getCallingUid() 4163 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4164 Slog.w(TAG, msg); 4165 throw new SecurityException(msg); 4166 } 4167 4168 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4169 userId, true, true, "killBackgroundProcesses", null); 4170 long callingId = Binder.clearCallingIdentity(); 4171 try { 4172 IPackageManager pm = AppGlobals.getPackageManager(); 4173 synchronized(this) { 4174 int appId = -1; 4175 try { 4176 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4177 } catch (RemoteException e) { 4178 } 4179 if (appId == -1) { 4180 Slog.w(TAG, "Invalid packageName: " + packageName); 4181 return; 4182 } 4183 killPackageProcessesLocked(packageName, appId, userId, 4184 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4185 } 4186 } finally { 4187 Binder.restoreCallingIdentity(callingId); 4188 } 4189 } 4190 4191 @Override 4192 public void killAllBackgroundProcesses() { 4193 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4194 != PackageManager.PERMISSION_GRANTED) { 4195 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4196 + Binder.getCallingPid() 4197 + ", uid=" + Binder.getCallingUid() 4198 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4199 Slog.w(TAG, msg); 4200 throw new SecurityException(msg); 4201 } 4202 4203 long callingId = Binder.clearCallingIdentity(); 4204 try { 4205 synchronized(this) { 4206 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4207 final int NP = mProcessNames.getMap().size(); 4208 for (int ip=0; ip<NP; ip++) { 4209 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4210 final int NA = apps.size(); 4211 for (int ia=0; ia<NA; ia++) { 4212 ProcessRecord app = apps.valueAt(ia); 4213 if (app.persistent) { 4214 // we don't kill persistent processes 4215 continue; 4216 } 4217 if (app.removed) { 4218 procs.add(app); 4219 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4220 app.removed = true; 4221 procs.add(app); 4222 } 4223 } 4224 } 4225 4226 int N = procs.size(); 4227 for (int i=0; i<N; i++) { 4228 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4229 } 4230 mAllowLowerMemLevel = true; 4231 updateOomAdjLocked(); 4232 doLowMemReportIfNeededLocked(null); 4233 } 4234 } finally { 4235 Binder.restoreCallingIdentity(callingId); 4236 } 4237 } 4238 4239 @Override 4240 public void forceStopPackage(final String packageName, int userId) { 4241 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4242 != PackageManager.PERMISSION_GRANTED) { 4243 String msg = "Permission Denial: forceStopPackage() from pid=" 4244 + Binder.getCallingPid() 4245 + ", uid=" + Binder.getCallingUid() 4246 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4247 Slog.w(TAG, msg); 4248 throw new SecurityException(msg); 4249 } 4250 final int callingPid = Binder.getCallingPid(); 4251 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4252 userId, true, true, "forceStopPackage", null); 4253 long callingId = Binder.clearCallingIdentity(); 4254 try { 4255 IPackageManager pm = AppGlobals.getPackageManager(); 4256 synchronized(this) { 4257 int[] users = userId == UserHandle.USER_ALL 4258 ? getUsersLocked() : new int[] { userId }; 4259 for (int user : users) { 4260 int pkgUid = -1; 4261 try { 4262 pkgUid = pm.getPackageUid(packageName, user); 4263 } catch (RemoteException e) { 4264 } 4265 if (pkgUid == -1) { 4266 Slog.w(TAG, "Invalid packageName: " + packageName); 4267 continue; 4268 } 4269 try { 4270 pm.setPackageStoppedState(packageName, true, user); 4271 } catch (RemoteException e) { 4272 } catch (IllegalArgumentException e) { 4273 Slog.w(TAG, "Failed trying to unstop package " 4274 + packageName + ": " + e); 4275 } 4276 if (isUserRunningLocked(user, false)) { 4277 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4278 } 4279 } 4280 } 4281 } finally { 4282 Binder.restoreCallingIdentity(callingId); 4283 } 4284 } 4285 4286 /* 4287 * The pkg name and app id have to be specified. 4288 */ 4289 @Override 4290 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4291 if (pkg == null) { 4292 return; 4293 } 4294 // Make sure the uid is valid. 4295 if (appid < 0) { 4296 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4297 return; 4298 } 4299 int callerUid = Binder.getCallingUid(); 4300 // Only the system server can kill an application 4301 if (callerUid == Process.SYSTEM_UID) { 4302 // Post an aysnc message to kill the application 4303 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4304 msg.arg1 = appid; 4305 msg.arg2 = 0; 4306 Bundle bundle = new Bundle(); 4307 bundle.putString("pkg", pkg); 4308 bundle.putString("reason", reason); 4309 msg.obj = bundle; 4310 mHandler.sendMessage(msg); 4311 } else { 4312 throw new SecurityException(callerUid + " cannot kill pkg: " + 4313 pkg); 4314 } 4315 } 4316 4317 @Override 4318 public void closeSystemDialogs(String reason) { 4319 enforceNotIsolatedCaller("closeSystemDialogs"); 4320 4321 final int pid = Binder.getCallingPid(); 4322 final int uid = Binder.getCallingUid(); 4323 final long origId = Binder.clearCallingIdentity(); 4324 try { 4325 synchronized (this) { 4326 // Only allow this from foreground processes, so that background 4327 // applications can't abuse it to prevent system UI from being shown. 4328 if (uid >= Process.FIRST_APPLICATION_UID) { 4329 ProcessRecord proc; 4330 synchronized (mPidsSelfLocked) { 4331 proc = mPidsSelfLocked.get(pid); 4332 } 4333 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4334 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4335 + " from background process " + proc); 4336 return; 4337 } 4338 } 4339 closeSystemDialogsLocked(reason); 4340 } 4341 } finally { 4342 Binder.restoreCallingIdentity(origId); 4343 } 4344 } 4345 4346 void closeSystemDialogsLocked(String reason) { 4347 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4348 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4349 | Intent.FLAG_RECEIVER_FOREGROUND); 4350 if (reason != null) { 4351 intent.putExtra("reason", reason); 4352 } 4353 mWindowManager.closeSystemDialogs(reason); 4354 4355 mStackSupervisor.closeSystemDialogsLocked(); 4356 4357 broadcastIntentLocked(null, null, intent, null, 4358 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4359 Process.SYSTEM_UID, UserHandle.USER_ALL); 4360 } 4361 4362 @Override 4363 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4364 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4365 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4366 for (int i=pids.length-1; i>=0; i--) { 4367 ProcessRecord proc; 4368 int oomAdj; 4369 synchronized (this) { 4370 synchronized (mPidsSelfLocked) { 4371 proc = mPidsSelfLocked.get(pids[i]); 4372 oomAdj = proc != null ? proc.setAdj : 0; 4373 } 4374 } 4375 infos[i] = new Debug.MemoryInfo(); 4376 Debug.getMemoryInfo(pids[i], infos[i]); 4377 if (proc != null) { 4378 synchronized (this) { 4379 if (proc.thread != null && proc.setAdj == oomAdj) { 4380 // Record this for posterity if the process has been stable. 4381 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4382 infos[i].getTotalUss(), false, proc.pkgList); 4383 } 4384 } 4385 } 4386 } 4387 return infos; 4388 } 4389 4390 @Override 4391 public long[] getProcessPss(int[] pids) { 4392 enforceNotIsolatedCaller("getProcessPss"); 4393 long[] pss = new long[pids.length]; 4394 for (int i=pids.length-1; i>=0; i--) { 4395 ProcessRecord proc; 4396 int oomAdj; 4397 synchronized (this) { 4398 synchronized (mPidsSelfLocked) { 4399 proc = mPidsSelfLocked.get(pids[i]); 4400 oomAdj = proc != null ? proc.setAdj : 0; 4401 } 4402 } 4403 long[] tmpUss = new long[1]; 4404 pss[i] = Debug.getPss(pids[i], tmpUss); 4405 if (proc != null) { 4406 synchronized (this) { 4407 if (proc.thread != null && proc.setAdj == oomAdj) { 4408 // Record this for posterity if the process has been stable. 4409 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4410 } 4411 } 4412 } 4413 } 4414 return pss; 4415 } 4416 4417 @Override 4418 public void killApplicationProcess(String processName, int uid) { 4419 if (processName == null) { 4420 return; 4421 } 4422 4423 int callerUid = Binder.getCallingUid(); 4424 // Only the system server can kill an application 4425 if (callerUid == Process.SYSTEM_UID) { 4426 synchronized (this) { 4427 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4428 if (app != null && app.thread != null) { 4429 try { 4430 app.thread.scheduleSuicide(); 4431 } catch (RemoteException e) { 4432 // If the other end already died, then our work here is done. 4433 } 4434 } else { 4435 Slog.w(TAG, "Process/uid not found attempting kill of " 4436 + processName + " / " + uid); 4437 } 4438 } 4439 } else { 4440 throw new SecurityException(callerUid + " cannot kill app process: " + 4441 processName); 4442 } 4443 } 4444 4445 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4446 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4447 false, true, false, UserHandle.getUserId(uid), reason); 4448 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4449 Uri.fromParts("package", packageName, null)); 4450 if (!mProcessesReady) { 4451 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4452 | Intent.FLAG_RECEIVER_FOREGROUND); 4453 } 4454 intent.putExtra(Intent.EXTRA_UID, uid); 4455 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4456 broadcastIntentLocked(null, null, intent, 4457 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4458 false, false, 4459 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4460 } 4461 4462 private void forceStopUserLocked(int userId, String reason) { 4463 forceStopPackageLocked(null, -1, false, false, true, false, userId, reason); 4464 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4465 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4466 | Intent.FLAG_RECEIVER_FOREGROUND); 4467 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4468 broadcastIntentLocked(null, null, intent, 4469 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4470 false, false, 4471 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4472 } 4473 4474 private final boolean killPackageProcessesLocked(String packageName, int appId, 4475 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4476 boolean doit, boolean evenPersistent, String reason) { 4477 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4478 4479 // Remove all processes this package may have touched: all with the 4480 // same UID (except for the system or root user), and all whose name 4481 // matches the package name. 4482 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4483 final int NP = mProcessNames.getMap().size(); 4484 for (int ip=0; ip<NP; ip++) { 4485 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4486 final int NA = apps.size(); 4487 for (int ia=0; ia<NA; ia++) { 4488 ProcessRecord app = apps.valueAt(ia); 4489 if (app.persistent && !evenPersistent) { 4490 // we don't kill persistent processes 4491 continue; 4492 } 4493 if (app.removed) { 4494 if (doit) { 4495 procs.add(app); 4496 } 4497 continue; 4498 } 4499 4500 // Skip process if it doesn't meet our oom adj requirement. 4501 if (app.setAdj < minOomAdj) { 4502 continue; 4503 } 4504 4505 // If no package is specified, we call all processes under the 4506 // give user id. 4507 if (packageName == null) { 4508 if (app.userId != userId) { 4509 continue; 4510 } 4511 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4512 continue; 4513 } 4514 // Package has been specified, we want to hit all processes 4515 // that match it. We need to qualify this by the processes 4516 // that are running under the specified app and user ID. 4517 } else { 4518 if (UserHandle.getAppId(app.uid) != appId) { 4519 continue; 4520 } 4521 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4522 continue; 4523 } 4524 if (!app.pkgList.containsKey(packageName)) { 4525 continue; 4526 } 4527 } 4528 4529 // Process has passed all conditions, kill it! 4530 if (!doit) { 4531 return true; 4532 } 4533 app.removed = true; 4534 procs.add(app); 4535 } 4536 } 4537 4538 int N = procs.size(); 4539 for (int i=0; i<N; i++) { 4540 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4541 } 4542 updateOomAdjLocked(); 4543 return N > 0; 4544 } 4545 4546 private final boolean forceStopPackageLocked(String name, int appId, 4547 boolean callerWillRestart, boolean purgeCache, boolean doit, 4548 boolean evenPersistent, int userId, String reason) { 4549 int i; 4550 int N; 4551 4552 if (userId == UserHandle.USER_ALL && name == null) { 4553 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4554 } 4555 4556 if (appId < 0 && name != null) { 4557 try { 4558 appId = UserHandle.getAppId( 4559 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4560 } catch (RemoteException e) { 4561 } 4562 } 4563 4564 if (doit) { 4565 if (name != null) { 4566 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4567 + " user=" + userId + ": " + reason); 4568 } else { 4569 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4570 } 4571 4572 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4573 for (int ip=pmap.size()-1; ip>=0; ip--) { 4574 SparseArray<Long> ba = pmap.valueAt(ip); 4575 for (i=ba.size()-1; i>=0; i--) { 4576 boolean remove = false; 4577 final int entUid = ba.keyAt(i); 4578 if (name != null) { 4579 if (userId == UserHandle.USER_ALL) { 4580 if (UserHandle.getAppId(entUid) == appId) { 4581 remove = true; 4582 } 4583 } else { 4584 if (entUid == UserHandle.getUid(userId, appId)) { 4585 remove = true; 4586 } 4587 } 4588 } else if (UserHandle.getUserId(entUid) == userId) { 4589 remove = true; 4590 } 4591 if (remove) { 4592 ba.removeAt(i); 4593 } 4594 } 4595 if (ba.size() == 0) { 4596 pmap.removeAt(ip); 4597 } 4598 } 4599 } 4600 4601 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4602 -100, callerWillRestart, true, doit, evenPersistent, 4603 name == null ? ("stop user " + userId) : ("stop " + name)); 4604 4605 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4606 if (!doit) { 4607 return true; 4608 } 4609 didSomething = true; 4610 } 4611 4612 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4613 if (!doit) { 4614 return true; 4615 } 4616 didSomething = true; 4617 } 4618 4619 if (name == null) { 4620 // Remove all sticky broadcasts from this user. 4621 mStickyBroadcasts.remove(userId); 4622 } 4623 4624 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4625 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4626 userId, providers)) { 4627 if (!doit) { 4628 return true; 4629 } 4630 didSomething = true; 4631 } 4632 N = providers.size(); 4633 for (i=0; i<N; i++) { 4634 removeDyingProviderLocked(null, providers.get(i), true); 4635 } 4636 4637 // Remove transient permissions granted from/to this package/user 4638 removeUriPermissionsForPackageLocked(name, userId, false); 4639 4640 if (name == null) { 4641 // Remove pending intents. For now we only do this when force 4642 // stopping users, because we have some problems when doing this 4643 // for packages -- app widgets are not currently cleaned up for 4644 // such packages, so they can be left with bad pending intents. 4645 if (mIntentSenderRecords.size() > 0) { 4646 Iterator<WeakReference<PendingIntentRecord>> it 4647 = mIntentSenderRecords.values().iterator(); 4648 while (it.hasNext()) { 4649 WeakReference<PendingIntentRecord> wpir = it.next(); 4650 if (wpir == null) { 4651 it.remove(); 4652 continue; 4653 } 4654 PendingIntentRecord pir = wpir.get(); 4655 if (pir == null) { 4656 it.remove(); 4657 continue; 4658 } 4659 if (name == null) { 4660 // Stopping user, remove all objects for the user. 4661 if (pir.key.userId != userId) { 4662 // Not the same user, skip it. 4663 continue; 4664 } 4665 } else { 4666 if (UserHandle.getAppId(pir.uid) != appId) { 4667 // Different app id, skip it. 4668 continue; 4669 } 4670 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4671 // Different user, skip it. 4672 continue; 4673 } 4674 if (!pir.key.packageName.equals(name)) { 4675 // Different package, skip it. 4676 continue; 4677 } 4678 } 4679 if (!doit) { 4680 return true; 4681 } 4682 didSomething = true; 4683 it.remove(); 4684 pir.canceled = true; 4685 if (pir.key.activity != null) { 4686 pir.key.activity.pendingResults.remove(pir.ref); 4687 } 4688 } 4689 } 4690 } 4691 4692 if (doit) { 4693 if (purgeCache && name != null) { 4694 AttributeCache ac = AttributeCache.instance(); 4695 if (ac != null) { 4696 ac.removePackage(name); 4697 } 4698 } 4699 if (mBooted) { 4700 mStackSupervisor.resumeTopActivitiesLocked(); 4701 mStackSupervisor.scheduleIdleLocked(); 4702 } 4703 } 4704 4705 return didSomething; 4706 } 4707 4708 private final boolean removeProcessLocked(ProcessRecord app, 4709 boolean callerWillRestart, boolean allowRestart, String reason) { 4710 final String name = app.processName; 4711 final int uid = app.uid; 4712 if (DEBUG_PROCESSES) Slog.d( 4713 TAG, "Force removing proc " + app.toShortString() + " (" + name 4714 + "/" + uid + ")"); 4715 4716 mProcessNames.remove(name, uid); 4717 mIsolatedProcesses.remove(app.uid); 4718 if (mHeavyWeightProcess == app) { 4719 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4720 mHeavyWeightProcess.userId, 0)); 4721 mHeavyWeightProcess = null; 4722 } 4723 boolean needRestart = false; 4724 if (app.pid > 0 && app.pid != MY_PID) { 4725 int pid = app.pid; 4726 synchronized (mPidsSelfLocked) { 4727 mPidsSelfLocked.remove(pid); 4728 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4729 } 4730 killUnneededProcessLocked(app, reason); 4731 handleAppDiedLocked(app, true, allowRestart); 4732 removeLruProcessLocked(app); 4733 4734 if (app.persistent && !app.isolated) { 4735 if (!callerWillRestart) { 4736 addAppLocked(app.info, false); 4737 } else { 4738 needRestart = true; 4739 } 4740 } 4741 } else { 4742 mRemovedProcesses.add(app); 4743 } 4744 4745 return needRestart; 4746 } 4747 4748 private final void processStartTimedOutLocked(ProcessRecord app) { 4749 final int pid = app.pid; 4750 boolean gone = false; 4751 synchronized (mPidsSelfLocked) { 4752 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4753 if (knownApp != null && knownApp.thread == null) { 4754 mPidsSelfLocked.remove(pid); 4755 gone = true; 4756 } 4757 } 4758 4759 if (gone) { 4760 Slog.w(TAG, "Process " + app + " failed to attach"); 4761 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4762 pid, app.uid, app.processName); 4763 mProcessNames.remove(app.processName, app.uid); 4764 mIsolatedProcesses.remove(app.uid); 4765 if (mHeavyWeightProcess == app) { 4766 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4767 mHeavyWeightProcess.userId, 0)); 4768 mHeavyWeightProcess = null; 4769 } 4770 // Take care of any launching providers waiting for this process. 4771 checkAppInLaunchingProvidersLocked(app, true); 4772 // Take care of any services that are waiting for the process. 4773 mServices.processStartTimedOutLocked(app); 4774 killUnneededProcessLocked(app, "start timeout"); 4775 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4776 Slog.w(TAG, "Unattached app died before backup, skipping"); 4777 try { 4778 IBackupManager bm = IBackupManager.Stub.asInterface( 4779 ServiceManager.getService(Context.BACKUP_SERVICE)); 4780 bm.agentDisconnected(app.info.packageName); 4781 } catch (RemoteException e) { 4782 // Can't happen; the backup manager is local 4783 } 4784 } 4785 if (isPendingBroadcastProcessLocked(pid)) { 4786 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4787 skipPendingBroadcastLocked(pid); 4788 } 4789 } else { 4790 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4791 } 4792 } 4793 4794 private final boolean attachApplicationLocked(IApplicationThread thread, 4795 int pid) { 4796 4797 // Find the application record that is being attached... either via 4798 // the pid if we are running in multiple processes, or just pull the 4799 // next app record if we are emulating process with anonymous threads. 4800 ProcessRecord app; 4801 if (pid != MY_PID && pid >= 0) { 4802 synchronized (mPidsSelfLocked) { 4803 app = mPidsSelfLocked.get(pid); 4804 } 4805 } else { 4806 app = null; 4807 } 4808 4809 if (app == null) { 4810 Slog.w(TAG, "No pending application record for pid " + pid 4811 + " (IApplicationThread " + thread + "); dropping process"); 4812 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4813 if (pid > 0 && pid != MY_PID) { 4814 Process.killProcessQuiet(pid); 4815 } else { 4816 try { 4817 thread.scheduleExit(); 4818 } catch (Exception e) { 4819 // Ignore exceptions. 4820 } 4821 } 4822 return false; 4823 } 4824 4825 // If this application record is still attached to a previous 4826 // process, clean it up now. 4827 if (app.thread != null) { 4828 handleAppDiedLocked(app, true, true); 4829 } 4830 4831 // Tell the process all about itself. 4832 4833 if (localLOGV) Slog.v( 4834 TAG, "Binding process pid " + pid + " to record " + app); 4835 4836 final String processName = app.processName; 4837 try { 4838 AppDeathRecipient adr = new AppDeathRecipient( 4839 app, pid, thread); 4840 thread.asBinder().linkToDeath(adr, 0); 4841 app.deathRecipient = adr; 4842 } catch (RemoteException e) { 4843 app.resetPackageList(mProcessStats); 4844 startProcessLocked(app, "link fail", processName); 4845 return false; 4846 } 4847 4848 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4849 4850 app.makeActive(thread, mProcessStats); 4851 app.curAdj = app.setAdj = -100; 4852 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4853 app.forcingToForeground = null; 4854 app.foregroundServices = false; 4855 app.hasShownUi = false; 4856 app.debugging = false; 4857 app.cached = false; 4858 4859 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4860 4861 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4862 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4863 4864 if (!normalMode) { 4865 Slog.i(TAG, "Launching preboot mode app: " + app); 4866 } 4867 4868 if (localLOGV) Slog.v( 4869 TAG, "New app record " + app 4870 + " thread=" + thread.asBinder() + " pid=" + pid); 4871 try { 4872 int testMode = IApplicationThread.DEBUG_OFF; 4873 if (mDebugApp != null && mDebugApp.equals(processName)) { 4874 testMode = mWaitForDebugger 4875 ? IApplicationThread.DEBUG_WAIT 4876 : IApplicationThread.DEBUG_ON; 4877 app.debugging = true; 4878 if (mDebugTransient) { 4879 mDebugApp = mOrigDebugApp; 4880 mWaitForDebugger = mOrigWaitForDebugger; 4881 } 4882 } 4883 String profileFile = app.instrumentationProfileFile; 4884 ParcelFileDescriptor profileFd = null; 4885 boolean profileAutoStop = false; 4886 if (mProfileApp != null && mProfileApp.equals(processName)) { 4887 mProfileProc = app; 4888 profileFile = mProfileFile; 4889 profileFd = mProfileFd; 4890 profileAutoStop = mAutoStopProfiler; 4891 } 4892 boolean enableOpenGlTrace = false; 4893 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4894 enableOpenGlTrace = true; 4895 mOpenGlTraceApp = null; 4896 } 4897 4898 // If the app is being launched for restore or full backup, set it up specially 4899 boolean isRestrictedBackupMode = false; 4900 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4901 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4902 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4903 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4904 } 4905 4906 ensurePackageDexOpt(app.instrumentationInfo != null 4907 ? app.instrumentationInfo.packageName 4908 : app.info.packageName); 4909 if (app.instrumentationClass != null) { 4910 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4911 } 4912 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4913 + processName + " with config " + mConfiguration); 4914 ApplicationInfo appInfo = app.instrumentationInfo != null 4915 ? app.instrumentationInfo : app.info; 4916 app.compat = compatibilityInfoForPackageLocked(appInfo); 4917 if (profileFd != null) { 4918 profileFd = profileFd.dup(); 4919 } 4920 thread.bindApplication(processName, appInfo, providers, 4921 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4922 app.instrumentationArguments, app.instrumentationWatcher, 4923 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4924 isRestrictedBackupMode || !normalMode, app.persistent, 4925 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4926 mCoreSettingsObserver.getCoreSettingsLocked()); 4927 updateLruProcessLocked(app, false, null); 4928 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4929 } catch (Exception e) { 4930 // todo: Yikes! What should we do? For now we will try to 4931 // start another process, but that could easily get us in 4932 // an infinite loop of restarting processes... 4933 Slog.w(TAG, "Exception thrown during bind!", e); 4934 4935 app.resetPackageList(mProcessStats); 4936 app.unlinkDeathRecipient(); 4937 startProcessLocked(app, "bind fail", processName); 4938 return false; 4939 } 4940 4941 // Remove this record from the list of starting applications. 4942 mPersistentStartingProcesses.remove(app); 4943 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4944 "Attach application locked removing on hold: " + app); 4945 mProcessesOnHold.remove(app); 4946 4947 boolean badApp = false; 4948 boolean didSomething = false; 4949 4950 // See if the top visible activity is waiting to run in this process... 4951 if (normalMode) { 4952 try { 4953 if (mStackSupervisor.attachApplicationLocked(app)) { 4954 didSomething = true; 4955 } 4956 } catch (Exception e) { 4957 badApp = true; 4958 } 4959 } 4960 4961 // Find any services that should be running in this process... 4962 if (!badApp) { 4963 try { 4964 didSomething |= mServices.attachApplicationLocked(app, processName); 4965 } catch (Exception e) { 4966 badApp = true; 4967 } 4968 } 4969 4970 // Check if a next-broadcast receiver is in this process... 4971 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4972 try { 4973 didSomething |= sendPendingBroadcastsLocked(app); 4974 } catch (Exception e) { 4975 // If the app died trying to launch the receiver we declare it 'bad' 4976 badApp = true; 4977 } 4978 } 4979 4980 // Check whether the next backup agent is in this process... 4981 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4982 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4983 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4984 try { 4985 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4986 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4987 mBackupTarget.backupMode); 4988 } catch (Exception e) { 4989 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4990 e.printStackTrace(); 4991 } 4992 } 4993 4994 if (badApp) { 4995 // todo: Also need to kill application to deal with all 4996 // kinds of exceptions. 4997 handleAppDiedLocked(app, false, true); 4998 return false; 4999 } 5000 5001 if (!didSomething) { 5002 updateOomAdjLocked(); 5003 } 5004 5005 return true; 5006 } 5007 5008 @Override 5009 public final void attachApplication(IApplicationThread thread) { 5010 synchronized (this) { 5011 int callingPid = Binder.getCallingPid(); 5012 final long origId = Binder.clearCallingIdentity(); 5013 attachApplicationLocked(thread, callingPid); 5014 Binder.restoreCallingIdentity(origId); 5015 } 5016 } 5017 5018 @Override 5019 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5020 final long origId = Binder.clearCallingIdentity(); 5021 synchronized (this) { 5022 ActivityStack stack = ActivityRecord.getStackLocked(token); 5023 if (stack != null) { 5024 ActivityRecord r = 5025 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5026 if (stopProfiling) { 5027 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5028 try { 5029 mProfileFd.close(); 5030 } catch (IOException e) { 5031 } 5032 clearProfilerLocked(); 5033 } 5034 } 5035 } 5036 } 5037 Binder.restoreCallingIdentity(origId); 5038 } 5039 5040 void enableScreenAfterBoot() { 5041 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5042 SystemClock.uptimeMillis()); 5043 mWindowManager.enableScreenAfterBoot(); 5044 5045 synchronized (this) { 5046 updateEventDispatchingLocked(); 5047 } 5048 } 5049 5050 @Override 5051 public void showBootMessage(final CharSequence msg, final boolean always) { 5052 enforceNotIsolatedCaller("showBootMessage"); 5053 mWindowManager.showBootMessage(msg, always); 5054 } 5055 5056 @Override 5057 public void dismissKeyguardOnNextActivity() { 5058 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5059 final long token = Binder.clearCallingIdentity(); 5060 try { 5061 synchronized (this) { 5062 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5063 if (mLockScreenShown) { 5064 mLockScreenShown = false; 5065 comeOutOfSleepIfNeededLocked(); 5066 } 5067 mStackSupervisor.setDismissKeyguard(true); 5068 } 5069 } finally { 5070 Binder.restoreCallingIdentity(token); 5071 } 5072 } 5073 5074 final void finishBooting() { 5075 IntentFilter pkgFilter = new IntentFilter(); 5076 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5077 pkgFilter.addDataScheme("package"); 5078 mContext.registerReceiver(new BroadcastReceiver() { 5079 @Override 5080 public void onReceive(Context context, Intent intent) { 5081 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5082 if (pkgs != null) { 5083 for (String pkg : pkgs) { 5084 synchronized (ActivityManagerService.this) { 5085 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0, 5086 "finished booting")) { 5087 setResultCode(Activity.RESULT_OK); 5088 return; 5089 } 5090 } 5091 } 5092 } 5093 } 5094 }, pkgFilter); 5095 5096 synchronized (this) { 5097 // Ensure that any processes we had put on hold are now started 5098 // up. 5099 final int NP = mProcessesOnHold.size(); 5100 if (NP > 0) { 5101 ArrayList<ProcessRecord> procs = 5102 new ArrayList<ProcessRecord>(mProcessesOnHold); 5103 for (int ip=0; ip<NP; ip++) { 5104 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5105 + procs.get(ip)); 5106 startProcessLocked(procs.get(ip), "on-hold", null); 5107 } 5108 } 5109 5110 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5111 // Start looking for apps that are abusing wake locks. 5112 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5113 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5114 // Tell anyone interested that we are done booting! 5115 SystemProperties.set("sys.boot_completed", "1"); 5116 SystemProperties.set("dev.bootcomplete", "1"); 5117 for (int i=0; i<mStartedUsers.size(); i++) { 5118 UserStartedState uss = mStartedUsers.valueAt(i); 5119 if (uss.mState == UserStartedState.STATE_BOOTING) { 5120 uss.mState = UserStartedState.STATE_RUNNING; 5121 final int userId = mStartedUsers.keyAt(i); 5122 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5123 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5124 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5125 broadcastIntentLocked(null, null, intent, null, 5126 new IIntentReceiver.Stub() { 5127 @Override 5128 public void performReceive(Intent intent, int resultCode, 5129 String data, Bundle extras, boolean ordered, 5130 boolean sticky, int sendingUser) { 5131 synchronized (ActivityManagerService.this) { 5132 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5133 true, false); 5134 } 5135 } 5136 }, 5137 0, null, null, 5138 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5139 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5140 userId); 5141 } 5142 } 5143 } 5144 } 5145 } 5146 5147 final void ensureBootCompleted() { 5148 boolean booting; 5149 boolean enableScreen; 5150 synchronized (this) { 5151 booting = mBooting; 5152 mBooting = false; 5153 enableScreen = !mBooted; 5154 mBooted = true; 5155 } 5156 5157 if (booting) { 5158 finishBooting(); 5159 } 5160 5161 if (enableScreen) { 5162 enableScreenAfterBoot(); 5163 } 5164 } 5165 5166 @Override 5167 public final void activityResumed(IBinder token) { 5168 final long origId = Binder.clearCallingIdentity(); 5169 synchronized(this) { 5170 ActivityStack stack = ActivityRecord.getStackLocked(token); 5171 if (stack != null) { 5172 ActivityRecord.activityResumedLocked(token); 5173 } 5174 } 5175 Binder.restoreCallingIdentity(origId); 5176 } 5177 5178 @Override 5179 public final void activityPaused(IBinder token) { 5180 final long origId = Binder.clearCallingIdentity(); 5181 synchronized(this) { 5182 ActivityStack stack = ActivityRecord.getStackLocked(token); 5183 if (stack != null) { 5184 stack.activityPausedLocked(token, false); 5185 } 5186 } 5187 Binder.restoreCallingIdentity(origId); 5188 } 5189 5190 @Override 5191 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5192 CharSequence description) { 5193 if (localLOGV) Slog.v( 5194 TAG, "Activity stopped: token=" + token); 5195 5196 // Refuse possible leaked file descriptors 5197 if (icicle != null && icicle.hasFileDescriptors()) { 5198 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5199 } 5200 5201 ActivityRecord r = null; 5202 5203 final long origId = Binder.clearCallingIdentity(); 5204 5205 synchronized (this) { 5206 r = ActivityRecord.isInStackLocked(token); 5207 if (r != null) { 5208 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5209 } 5210 } 5211 5212 if (r != null) { 5213 sendPendingThumbnail(r, null, null, null, false); 5214 } 5215 5216 trimApplications(); 5217 5218 Binder.restoreCallingIdentity(origId); 5219 } 5220 5221 @Override 5222 public final void activityDestroyed(IBinder token) { 5223 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5224 synchronized (this) { 5225 ActivityStack stack = ActivityRecord.getStackLocked(token); 5226 if (stack != null) { 5227 stack.activityDestroyedLocked(token); 5228 } 5229 } 5230 } 5231 5232 @Override 5233 public String getCallingPackage(IBinder token) { 5234 synchronized (this) { 5235 ActivityRecord r = getCallingRecordLocked(token); 5236 return r != null ? r.info.packageName : null; 5237 } 5238 } 5239 5240 @Override 5241 public ComponentName getCallingActivity(IBinder token) { 5242 synchronized (this) { 5243 ActivityRecord r = getCallingRecordLocked(token); 5244 return r != null ? r.intent.getComponent() : null; 5245 } 5246 } 5247 5248 private ActivityRecord getCallingRecordLocked(IBinder token) { 5249 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5250 if (r == null) { 5251 return null; 5252 } 5253 return r.resultTo; 5254 } 5255 5256 @Override 5257 public ComponentName getActivityClassForToken(IBinder token) { 5258 synchronized(this) { 5259 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5260 if (r == null) { 5261 return null; 5262 } 5263 return r.intent.getComponent(); 5264 } 5265 } 5266 5267 @Override 5268 public String getPackageForToken(IBinder token) { 5269 synchronized(this) { 5270 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5271 if (r == null) { 5272 return null; 5273 } 5274 return r.packageName; 5275 } 5276 } 5277 5278 @Override 5279 public IIntentSender getIntentSender(int type, 5280 String packageName, IBinder token, String resultWho, 5281 int requestCode, Intent[] intents, String[] resolvedTypes, 5282 int flags, Bundle options, int userId) { 5283 enforceNotIsolatedCaller("getIntentSender"); 5284 // Refuse possible leaked file descriptors 5285 if (intents != null) { 5286 if (intents.length < 1) { 5287 throw new IllegalArgumentException("Intents array length must be >= 1"); 5288 } 5289 for (int i=0; i<intents.length; i++) { 5290 Intent intent = intents[i]; 5291 if (intent != null) { 5292 if (intent.hasFileDescriptors()) { 5293 throw new IllegalArgumentException("File descriptors passed in Intent"); 5294 } 5295 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5296 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5297 throw new IllegalArgumentException( 5298 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5299 } 5300 intents[i] = new Intent(intent); 5301 } 5302 } 5303 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5304 throw new IllegalArgumentException( 5305 "Intent array length does not match resolvedTypes length"); 5306 } 5307 } 5308 if (options != null) { 5309 if (options.hasFileDescriptors()) { 5310 throw new IllegalArgumentException("File descriptors passed in options"); 5311 } 5312 } 5313 5314 synchronized(this) { 5315 int callingUid = Binder.getCallingUid(); 5316 int origUserId = userId; 5317 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5318 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5319 "getIntentSender", null); 5320 if (origUserId == UserHandle.USER_CURRENT) { 5321 // We don't want to evaluate this until the pending intent is 5322 // actually executed. However, we do want to always do the 5323 // security checking for it above. 5324 userId = UserHandle.USER_CURRENT; 5325 } 5326 try { 5327 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5328 int uid = AppGlobals.getPackageManager() 5329 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5330 if (!UserHandle.isSameApp(callingUid, uid)) { 5331 String msg = "Permission Denial: getIntentSender() from pid=" 5332 + Binder.getCallingPid() 5333 + ", uid=" + Binder.getCallingUid() 5334 + ", (need uid=" + uid + ")" 5335 + " is not allowed to send as package " + packageName; 5336 Slog.w(TAG, msg); 5337 throw new SecurityException(msg); 5338 } 5339 } 5340 5341 return getIntentSenderLocked(type, packageName, callingUid, userId, 5342 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5343 5344 } catch (RemoteException e) { 5345 throw new SecurityException(e); 5346 } 5347 } 5348 } 5349 5350 IIntentSender getIntentSenderLocked(int type, String packageName, 5351 int callingUid, int userId, IBinder token, String resultWho, 5352 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5353 Bundle options) { 5354 if (DEBUG_MU) 5355 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5356 ActivityRecord activity = null; 5357 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5358 activity = ActivityRecord.isInStackLocked(token); 5359 if (activity == null) { 5360 return null; 5361 } 5362 if (activity.finishing) { 5363 return null; 5364 } 5365 } 5366 5367 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5368 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5369 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5370 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5371 |PendingIntent.FLAG_UPDATE_CURRENT); 5372 5373 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5374 type, packageName, activity, resultWho, 5375 requestCode, intents, resolvedTypes, flags, options, userId); 5376 WeakReference<PendingIntentRecord> ref; 5377 ref = mIntentSenderRecords.get(key); 5378 PendingIntentRecord rec = ref != null ? ref.get() : null; 5379 if (rec != null) { 5380 if (!cancelCurrent) { 5381 if (updateCurrent) { 5382 if (rec.key.requestIntent != null) { 5383 rec.key.requestIntent.replaceExtras(intents != null ? 5384 intents[intents.length - 1] : null); 5385 } 5386 if (intents != null) { 5387 intents[intents.length-1] = rec.key.requestIntent; 5388 rec.key.allIntents = intents; 5389 rec.key.allResolvedTypes = resolvedTypes; 5390 } else { 5391 rec.key.allIntents = null; 5392 rec.key.allResolvedTypes = null; 5393 } 5394 } 5395 return rec; 5396 } 5397 rec.canceled = true; 5398 mIntentSenderRecords.remove(key); 5399 } 5400 if (noCreate) { 5401 return rec; 5402 } 5403 rec = new PendingIntentRecord(this, key, callingUid); 5404 mIntentSenderRecords.put(key, rec.ref); 5405 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5406 if (activity.pendingResults == null) { 5407 activity.pendingResults 5408 = new HashSet<WeakReference<PendingIntentRecord>>(); 5409 } 5410 activity.pendingResults.add(rec.ref); 5411 } 5412 return rec; 5413 } 5414 5415 @Override 5416 public void cancelIntentSender(IIntentSender sender) { 5417 if (!(sender instanceof PendingIntentRecord)) { 5418 return; 5419 } 5420 synchronized(this) { 5421 PendingIntentRecord rec = (PendingIntentRecord)sender; 5422 try { 5423 int uid = AppGlobals.getPackageManager() 5424 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5425 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5426 String msg = "Permission Denial: cancelIntentSender() from pid=" 5427 + Binder.getCallingPid() 5428 + ", uid=" + Binder.getCallingUid() 5429 + " is not allowed to cancel packges " 5430 + rec.key.packageName; 5431 Slog.w(TAG, msg); 5432 throw new SecurityException(msg); 5433 } 5434 } catch (RemoteException e) { 5435 throw new SecurityException(e); 5436 } 5437 cancelIntentSenderLocked(rec, true); 5438 } 5439 } 5440 5441 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5442 rec.canceled = true; 5443 mIntentSenderRecords.remove(rec.key); 5444 if (cleanActivity && rec.key.activity != null) { 5445 rec.key.activity.pendingResults.remove(rec.ref); 5446 } 5447 } 5448 5449 @Override 5450 public String getPackageForIntentSender(IIntentSender pendingResult) { 5451 if (!(pendingResult instanceof PendingIntentRecord)) { 5452 return null; 5453 } 5454 try { 5455 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5456 return res.key.packageName; 5457 } catch (ClassCastException e) { 5458 } 5459 return null; 5460 } 5461 5462 @Override 5463 public int getUidForIntentSender(IIntentSender sender) { 5464 if (sender instanceof PendingIntentRecord) { 5465 try { 5466 PendingIntentRecord res = (PendingIntentRecord)sender; 5467 return res.uid; 5468 } catch (ClassCastException e) { 5469 } 5470 } 5471 return -1; 5472 } 5473 5474 @Override 5475 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5476 if (!(pendingResult instanceof PendingIntentRecord)) { 5477 return false; 5478 } 5479 try { 5480 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5481 if (res.key.allIntents == null) { 5482 return false; 5483 } 5484 for (int i=0; i<res.key.allIntents.length; i++) { 5485 Intent intent = res.key.allIntents[i]; 5486 if (intent.getPackage() != null && intent.getComponent() != null) { 5487 return false; 5488 } 5489 } 5490 return true; 5491 } catch (ClassCastException e) { 5492 } 5493 return false; 5494 } 5495 5496 @Override 5497 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5498 if (!(pendingResult instanceof PendingIntentRecord)) { 5499 return false; 5500 } 5501 try { 5502 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5503 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5504 return true; 5505 } 5506 return false; 5507 } catch (ClassCastException e) { 5508 } 5509 return false; 5510 } 5511 5512 @Override 5513 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5514 if (!(pendingResult instanceof PendingIntentRecord)) { 5515 return null; 5516 } 5517 try { 5518 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5519 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5520 } catch (ClassCastException e) { 5521 } 5522 return null; 5523 } 5524 5525 @Override 5526 public void setProcessLimit(int max) { 5527 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5528 "setProcessLimit()"); 5529 synchronized (this) { 5530 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5531 mProcessLimitOverride = max; 5532 } 5533 trimApplications(); 5534 } 5535 5536 @Override 5537 public int getProcessLimit() { 5538 synchronized (this) { 5539 return mProcessLimitOverride; 5540 } 5541 } 5542 5543 void foregroundTokenDied(ForegroundToken token) { 5544 synchronized (ActivityManagerService.this) { 5545 synchronized (mPidsSelfLocked) { 5546 ForegroundToken cur 5547 = mForegroundProcesses.get(token.pid); 5548 if (cur != token) { 5549 return; 5550 } 5551 mForegroundProcesses.remove(token.pid); 5552 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5553 if (pr == null) { 5554 return; 5555 } 5556 pr.forcingToForeground = null; 5557 pr.foregroundServices = false; 5558 } 5559 updateOomAdjLocked(); 5560 } 5561 } 5562 5563 @Override 5564 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5565 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5566 "setProcessForeground()"); 5567 synchronized(this) { 5568 boolean changed = false; 5569 5570 synchronized (mPidsSelfLocked) { 5571 ProcessRecord pr = mPidsSelfLocked.get(pid); 5572 if (pr == null && isForeground) { 5573 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5574 return; 5575 } 5576 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5577 if (oldToken != null) { 5578 oldToken.token.unlinkToDeath(oldToken, 0); 5579 mForegroundProcesses.remove(pid); 5580 if (pr != null) { 5581 pr.forcingToForeground = null; 5582 } 5583 changed = true; 5584 } 5585 if (isForeground && token != null) { 5586 ForegroundToken newToken = new ForegroundToken() { 5587 @Override 5588 public void binderDied() { 5589 foregroundTokenDied(this); 5590 } 5591 }; 5592 newToken.pid = pid; 5593 newToken.token = token; 5594 try { 5595 token.linkToDeath(newToken, 0); 5596 mForegroundProcesses.put(pid, newToken); 5597 pr.forcingToForeground = token; 5598 changed = true; 5599 } catch (RemoteException e) { 5600 // If the process died while doing this, we will later 5601 // do the cleanup with the process death link. 5602 } 5603 } 5604 } 5605 5606 if (changed) { 5607 updateOomAdjLocked(); 5608 } 5609 } 5610 } 5611 5612 // ========================================================= 5613 // PERMISSIONS 5614 // ========================================================= 5615 5616 static class PermissionController extends IPermissionController.Stub { 5617 ActivityManagerService mActivityManagerService; 5618 PermissionController(ActivityManagerService activityManagerService) { 5619 mActivityManagerService = activityManagerService; 5620 } 5621 5622 @Override 5623 public boolean checkPermission(String permission, int pid, int uid) { 5624 return mActivityManagerService.checkPermission(permission, pid, 5625 uid) == PackageManager.PERMISSION_GRANTED; 5626 } 5627 } 5628 5629 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5630 @Override 5631 public int checkComponentPermission(String permission, int pid, int uid, 5632 int owningUid, boolean exported) { 5633 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5634 owningUid, exported); 5635 } 5636 5637 @Override 5638 public Object getAMSLock() { 5639 return ActivityManagerService.this; 5640 } 5641 } 5642 5643 /** 5644 * This can be called with or without the global lock held. 5645 */ 5646 int checkComponentPermission(String permission, int pid, int uid, 5647 int owningUid, boolean exported) { 5648 // We might be performing an operation on behalf of an indirect binder 5649 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5650 // client identity accordingly before proceeding. 5651 Identity tlsIdentity = sCallerIdentity.get(); 5652 if (tlsIdentity != null) { 5653 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5654 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5655 uid = tlsIdentity.uid; 5656 pid = tlsIdentity.pid; 5657 } 5658 5659 if (pid == MY_PID) { 5660 return PackageManager.PERMISSION_GRANTED; 5661 } 5662 5663 return ActivityManager.checkComponentPermission(permission, uid, 5664 owningUid, exported); 5665 } 5666 5667 /** 5668 * As the only public entry point for permissions checking, this method 5669 * can enforce the semantic that requesting a check on a null global 5670 * permission is automatically denied. (Internally a null permission 5671 * string is used when calling {@link #checkComponentPermission} in cases 5672 * when only uid-based security is needed.) 5673 * 5674 * This can be called with or without the global lock held. 5675 */ 5676 @Override 5677 public int checkPermission(String permission, int pid, int uid) { 5678 if (permission == null) { 5679 return PackageManager.PERMISSION_DENIED; 5680 } 5681 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5682 } 5683 5684 /** 5685 * Binder IPC calls go through the public entry point. 5686 * This can be called with or without the global lock held. 5687 */ 5688 int checkCallingPermission(String permission) { 5689 return checkPermission(permission, 5690 Binder.getCallingPid(), 5691 UserHandle.getAppId(Binder.getCallingUid())); 5692 } 5693 5694 /** 5695 * This can be called with or without the global lock held. 5696 */ 5697 void enforceCallingPermission(String permission, String func) { 5698 if (checkCallingPermission(permission) 5699 == PackageManager.PERMISSION_GRANTED) { 5700 return; 5701 } 5702 5703 String msg = "Permission Denial: " + func + " from pid=" 5704 + Binder.getCallingPid() 5705 + ", uid=" + Binder.getCallingUid() 5706 + " requires " + permission; 5707 Slog.w(TAG, msg); 5708 throw new SecurityException(msg); 5709 } 5710 5711 /** 5712 * Determine if UID is holding permissions required to access {@link Uri} in 5713 * the given {@link ProviderInfo}. Final permission checking is always done 5714 * in {@link ContentProvider}. 5715 */ 5716 private final boolean checkHoldingPermissionsLocked( 5717 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5718 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5719 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5720 5721 if (pi.applicationInfo.uid == uid) { 5722 return true; 5723 } else if (!pi.exported) { 5724 return false; 5725 } 5726 5727 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5728 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5729 try { 5730 // check if target holds top-level <provider> permissions 5731 if (!readMet && pi.readPermission != null 5732 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5733 readMet = true; 5734 } 5735 if (!writeMet && pi.writePermission != null 5736 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5737 writeMet = true; 5738 } 5739 5740 // track if unprotected read/write is allowed; any denied 5741 // <path-permission> below removes this ability 5742 boolean allowDefaultRead = pi.readPermission == null; 5743 boolean allowDefaultWrite = pi.writePermission == null; 5744 5745 // check if target holds any <path-permission> that match uri 5746 final PathPermission[] pps = pi.pathPermissions; 5747 if (pps != null) { 5748 final String path = uri.getPath(); 5749 int i = pps.length; 5750 while (i > 0 && (!readMet || !writeMet)) { 5751 i--; 5752 PathPermission pp = pps[i]; 5753 if (pp.match(path)) { 5754 if (!readMet) { 5755 final String pprperm = pp.getReadPermission(); 5756 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5757 + pprperm + " for " + pp.getPath() 5758 + ": match=" + pp.match(path) 5759 + " check=" + pm.checkUidPermission(pprperm, uid)); 5760 if (pprperm != null) { 5761 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5762 readMet = true; 5763 } else { 5764 allowDefaultRead = false; 5765 } 5766 } 5767 } 5768 if (!writeMet) { 5769 final String ppwperm = pp.getWritePermission(); 5770 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5771 + ppwperm + " for " + pp.getPath() 5772 + ": match=" + pp.match(path) 5773 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5774 if (ppwperm != null) { 5775 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5776 writeMet = true; 5777 } else { 5778 allowDefaultWrite = false; 5779 } 5780 } 5781 } 5782 } 5783 } 5784 } 5785 5786 // grant unprotected <provider> read/write, if not blocked by 5787 // <path-permission> above 5788 if (allowDefaultRead) readMet = true; 5789 if (allowDefaultWrite) writeMet = true; 5790 5791 } catch (RemoteException e) { 5792 return false; 5793 } 5794 5795 return readMet && writeMet; 5796 } 5797 5798 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5799 ProviderInfo pi = null; 5800 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5801 if (cpr != null) { 5802 pi = cpr.info; 5803 } else { 5804 try { 5805 pi = AppGlobals.getPackageManager().resolveContentProvider( 5806 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5807 } catch (RemoteException ex) { 5808 } 5809 } 5810 return pi; 5811 } 5812 5813 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5814 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5815 if (targetUris != null) { 5816 return targetUris.get(uri); 5817 } else { 5818 return null; 5819 } 5820 } 5821 5822 private UriPermission findOrCreateUriPermissionLocked( 5823 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5824 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5825 if (targetUris == null) { 5826 targetUris = Maps.newArrayMap(); 5827 mGrantedUriPermissions.put(targetUid, targetUris); 5828 } 5829 5830 UriPermission perm = targetUris.get(uri); 5831 if (perm == null) { 5832 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5833 targetUris.put(uri, perm); 5834 } 5835 5836 return perm; 5837 } 5838 5839 private final boolean checkUriPermissionLocked( 5840 Uri uri, int uid, int modeFlags, int minStrength) { 5841 // Root gets to do everything. 5842 if (uid == 0) { 5843 return true; 5844 } 5845 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5846 if (perms == null) return false; 5847 UriPermission perm = perms.get(uri); 5848 if (perm == null) return false; 5849 return perm.getStrength(modeFlags) >= minStrength; 5850 } 5851 5852 @Override 5853 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5854 enforceNotIsolatedCaller("checkUriPermission"); 5855 5856 // Another redirected-binder-call permissions check as in 5857 // {@link checkComponentPermission}. 5858 Identity tlsIdentity = sCallerIdentity.get(); 5859 if (tlsIdentity != null) { 5860 uid = tlsIdentity.uid; 5861 pid = tlsIdentity.pid; 5862 } 5863 5864 // Our own process gets to do everything. 5865 if (pid == MY_PID) { 5866 return PackageManager.PERMISSION_GRANTED; 5867 } 5868 synchronized(this) { 5869 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5870 ? PackageManager.PERMISSION_GRANTED 5871 : PackageManager.PERMISSION_DENIED; 5872 } 5873 } 5874 5875 /** 5876 * Check if the targetPkg can be granted permission to access uri by 5877 * the callingUid using the given modeFlags. Throws a security exception 5878 * if callingUid is not allowed to do this. Returns the uid of the target 5879 * if the URI permission grant should be performed; returns -1 if it is not 5880 * needed (for example targetPkg already has permission to access the URI). 5881 * If you already know the uid of the target, you can supply it in 5882 * lastTargetUid else set that to -1. 5883 */ 5884 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5885 Uri uri, int modeFlags, int lastTargetUid) { 5886 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5887 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5888 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5889 if (modeFlags == 0) { 5890 return -1; 5891 } 5892 5893 if (targetPkg != null) { 5894 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5895 "Checking grant " + targetPkg + " permission to " + uri); 5896 } 5897 5898 final IPackageManager pm = AppGlobals.getPackageManager(); 5899 5900 // If this is not a content: uri, we can't do anything with it. 5901 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5902 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5903 "Can't grant URI permission for non-content URI: " + uri); 5904 return -1; 5905 } 5906 5907 final String authority = uri.getAuthority(); 5908 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 5909 if (pi == null) { 5910 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5911 return -1; 5912 } 5913 5914 int targetUid = lastTargetUid; 5915 if (targetUid < 0 && targetPkg != null) { 5916 try { 5917 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5918 if (targetUid < 0) { 5919 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5920 "Can't grant URI permission no uid for: " + targetPkg); 5921 return -1; 5922 } 5923 } catch (RemoteException ex) { 5924 return -1; 5925 } 5926 } 5927 5928 if (targetUid >= 0) { 5929 // First... does the target actually need this permission? 5930 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5931 // No need to grant the target this permission. 5932 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5933 "Target " + targetPkg + " already has full permission to " + uri); 5934 return -1; 5935 } 5936 } else { 5937 // First... there is no target package, so can anyone access it? 5938 boolean allowed = pi.exported; 5939 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5940 if (pi.readPermission != null) { 5941 allowed = false; 5942 } 5943 } 5944 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5945 if (pi.writePermission != null) { 5946 allowed = false; 5947 } 5948 } 5949 if (allowed) { 5950 return -1; 5951 } 5952 } 5953 5954 // Second... is the provider allowing granting of URI permissions? 5955 if (!pi.grantUriPermissions) { 5956 throw new SecurityException("Provider " + pi.packageName 5957 + "/" + pi.name 5958 + " does not allow granting of Uri permissions (uri " 5959 + uri + ")"); 5960 } 5961 if (pi.uriPermissionPatterns != null) { 5962 final int N = pi.uriPermissionPatterns.length; 5963 boolean allowed = false; 5964 for (int i=0; i<N; i++) { 5965 if (pi.uriPermissionPatterns[i] != null 5966 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5967 allowed = true; 5968 break; 5969 } 5970 } 5971 if (!allowed) { 5972 throw new SecurityException("Provider " + pi.packageName 5973 + "/" + pi.name 5974 + " does not allow granting of permission to path of Uri " 5975 + uri); 5976 } 5977 } 5978 5979 // Third... does the caller itself have permission to access 5980 // this uri? 5981 if (callingUid != Process.myUid()) { 5982 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5983 // Require they hold a strong enough Uri permission 5984 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 5985 : UriPermission.STRENGTH_OWNED; 5986 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 5987 throw new SecurityException("Uid " + callingUid 5988 + " does not have permission to uri " + uri); 5989 } 5990 } 5991 } 5992 5993 return targetUid; 5994 } 5995 5996 @Override 5997 public int checkGrantUriPermission(int callingUid, String targetPkg, 5998 Uri uri, int modeFlags) { 5999 enforceNotIsolatedCaller("checkGrantUriPermission"); 6000 synchronized(this) { 6001 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6002 } 6003 } 6004 6005 void grantUriPermissionUncheckedLocked( 6006 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6007 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6008 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6009 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6010 if (modeFlags == 0) { 6011 return; 6012 } 6013 6014 // So here we are: the caller has the assumed permission 6015 // to the uri, and the target doesn't. Let's now give this to 6016 // the target. 6017 6018 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6019 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6020 6021 final String authority = uri.getAuthority(); 6022 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6023 if (pi == null) { 6024 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6025 return; 6026 } 6027 6028 final UriPermission perm = findOrCreateUriPermissionLocked( 6029 pi.packageName, targetPkg, targetUid, uri); 6030 perm.grantModes(modeFlags, persistable, owner); 6031 } 6032 6033 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6034 int modeFlags, UriPermissionOwner owner) { 6035 if (targetPkg == null) { 6036 throw new NullPointerException("targetPkg"); 6037 } 6038 6039 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6040 if (targetUid < 0) { 6041 return; 6042 } 6043 6044 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6045 } 6046 6047 static class NeededUriGrants extends ArrayList<Uri> { 6048 final String targetPkg; 6049 final int targetUid; 6050 final int flags; 6051 6052 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6053 this.targetPkg = targetPkg; 6054 this.targetUid = targetUid; 6055 this.flags = flags; 6056 } 6057 } 6058 6059 /** 6060 * Like checkGrantUriPermissionLocked, but takes an Intent. 6061 */ 6062 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6063 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6064 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6065 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6066 + " clip=" + (intent != null ? intent.getClipData() : null) 6067 + " from " + intent + "; flags=0x" 6068 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6069 6070 if (targetPkg == null) { 6071 throw new NullPointerException("targetPkg"); 6072 } 6073 6074 if (intent == null) { 6075 return null; 6076 } 6077 Uri data = intent.getData(); 6078 ClipData clip = intent.getClipData(); 6079 if (data == null && clip == null) { 6080 return null; 6081 } 6082 6083 if (data != null) { 6084 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6085 mode, needed != null ? needed.targetUid : -1); 6086 if (targetUid > 0) { 6087 if (needed == null) { 6088 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6089 } 6090 needed.add(data); 6091 } 6092 } 6093 if (clip != null) { 6094 for (int i=0; i<clip.getItemCount(); i++) { 6095 Uri uri = clip.getItemAt(i).getUri(); 6096 if (uri != null) { 6097 int targetUid = -1; 6098 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6099 mode, needed != null ? needed.targetUid : -1); 6100 if (targetUid > 0) { 6101 if (needed == null) { 6102 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6103 } 6104 needed.add(uri); 6105 } 6106 } else { 6107 Intent clipIntent = clip.getItemAt(i).getIntent(); 6108 if (clipIntent != null) { 6109 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6110 callingUid, targetPkg, clipIntent, mode, needed); 6111 if (newNeeded != null) { 6112 needed = newNeeded; 6113 } 6114 } 6115 } 6116 } 6117 } 6118 6119 return needed; 6120 } 6121 6122 /** 6123 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6124 */ 6125 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6126 UriPermissionOwner owner) { 6127 if (needed != null) { 6128 for (int i=0; i<needed.size(); i++) { 6129 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6130 needed.get(i), needed.flags, owner); 6131 } 6132 } 6133 } 6134 6135 void grantUriPermissionFromIntentLocked(int callingUid, 6136 String targetPkg, Intent intent, UriPermissionOwner owner) { 6137 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6138 intent, intent != null ? intent.getFlags() : 0, null); 6139 if (needed == null) { 6140 return; 6141 } 6142 6143 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6144 } 6145 6146 @Override 6147 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6148 Uri uri, int modeFlags) { 6149 enforceNotIsolatedCaller("grantUriPermission"); 6150 synchronized(this) { 6151 final ProcessRecord r = getRecordForAppLocked(caller); 6152 if (r == null) { 6153 throw new SecurityException("Unable to find app for caller " 6154 + caller 6155 + " when granting permission to uri " + uri); 6156 } 6157 if (targetPkg == null) { 6158 throw new IllegalArgumentException("null target"); 6159 } 6160 if (uri == null) { 6161 throw new IllegalArgumentException("null uri"); 6162 } 6163 6164 // Persistable only supported through Intents 6165 Preconditions.checkFlagsArgument(modeFlags, 6166 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6167 6168 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6169 null); 6170 } 6171 } 6172 6173 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6174 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6175 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6176 ArrayMap<Uri, UriPermission> perms 6177 = mGrantedUriPermissions.get(perm.targetUid); 6178 if (perms != null) { 6179 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6180 "Removing " + perm.targetUid + " permission to " + perm.uri); 6181 perms.remove(perm.uri); 6182 if (perms.size() == 0) { 6183 mGrantedUriPermissions.remove(perm.targetUid); 6184 } 6185 } 6186 } 6187 } 6188 6189 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6190 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6191 6192 final IPackageManager pm = AppGlobals.getPackageManager(); 6193 final String authority = uri.getAuthority(); 6194 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6195 if (pi == null) { 6196 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6197 return; 6198 } 6199 6200 // Does the caller have this permission on the URI? 6201 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6202 // Right now, if you are not the original owner of the permission, 6203 // you are not allowed to revoke it. 6204 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6205 throw new SecurityException("Uid " + callingUid 6206 + " does not have permission to uri " + uri); 6207 //} 6208 } 6209 6210 boolean persistChanged = false; 6211 6212 // Go through all of the permissions and remove any that match. 6213 final List<String> SEGMENTS = uri.getPathSegments(); 6214 if (SEGMENTS != null) { 6215 final int NS = SEGMENTS.size(); 6216 int N = mGrantedUriPermissions.size(); 6217 for (int i=0; i<N; i++) { 6218 ArrayMap<Uri, UriPermission> perms 6219 = mGrantedUriPermissions.valueAt(i); 6220 Iterator<UriPermission> it = perms.values().iterator(); 6221 toploop: 6222 while (it.hasNext()) { 6223 UriPermission perm = it.next(); 6224 Uri targetUri = perm.uri; 6225 if (!authority.equals(targetUri.getAuthority())) { 6226 continue; 6227 } 6228 List<String> targetSegments = targetUri.getPathSegments(); 6229 if (targetSegments == null) { 6230 continue; 6231 } 6232 if (targetSegments.size() < NS) { 6233 continue; 6234 } 6235 for (int j=0; j<NS; j++) { 6236 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6237 continue toploop; 6238 } 6239 } 6240 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6241 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6242 persistChanged |= perm.clearModes(modeFlags, true); 6243 if (perm.modeFlags == 0) { 6244 it.remove(); 6245 } 6246 } 6247 if (perms.size() == 0) { 6248 mGrantedUriPermissions.remove( 6249 mGrantedUriPermissions.keyAt(i)); 6250 N--; 6251 i--; 6252 } 6253 } 6254 } 6255 6256 if (persistChanged) { 6257 schedulePersistUriGrants(); 6258 } 6259 } 6260 6261 @Override 6262 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6263 int modeFlags) { 6264 enforceNotIsolatedCaller("revokeUriPermission"); 6265 synchronized(this) { 6266 final ProcessRecord r = getRecordForAppLocked(caller); 6267 if (r == null) { 6268 throw new SecurityException("Unable to find app for caller " 6269 + caller 6270 + " when revoking permission to uri " + uri); 6271 } 6272 if (uri == null) { 6273 Slog.w(TAG, "revokeUriPermission: null uri"); 6274 return; 6275 } 6276 6277 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6278 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6279 if (modeFlags == 0) { 6280 return; 6281 } 6282 6283 final IPackageManager pm = AppGlobals.getPackageManager(); 6284 final String authority = uri.getAuthority(); 6285 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6286 if (pi == null) { 6287 Slog.w(TAG, "No content provider found for permission revoke: " 6288 + uri.toSafeString()); 6289 return; 6290 } 6291 6292 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6293 } 6294 } 6295 6296 /** 6297 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6298 * given package. 6299 * 6300 * @param packageName Package name to match, or {@code null} to apply to all 6301 * packages. 6302 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6303 * to all users. 6304 * @param persistable If persistable grants should be removed. 6305 */ 6306 private void removeUriPermissionsForPackageLocked( 6307 String packageName, int userHandle, boolean persistable) { 6308 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6309 throw new IllegalArgumentException("Must narrow by either package or user"); 6310 } 6311 6312 boolean persistChanged = false; 6313 6314 final int size = mGrantedUriPermissions.size(); 6315 for (int i = 0; i < size; i++) { 6316 // Only inspect grants matching user 6317 if (userHandle == UserHandle.USER_ALL 6318 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6319 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6320 .values().iterator(); 6321 while (it.hasNext()) { 6322 final UriPermission perm = it.next(); 6323 6324 // Only inspect grants matching package 6325 if (packageName == null || perm.sourcePkg.equals(packageName) 6326 || perm.targetPkg.equals(packageName)) { 6327 persistChanged |= perm.clearModes(~0, persistable); 6328 6329 // Only remove when no modes remain; any persisted grants 6330 // will keep this alive. 6331 if (perm.modeFlags == 0) { 6332 it.remove(); 6333 } 6334 } 6335 } 6336 } 6337 } 6338 6339 if (persistChanged) { 6340 schedulePersistUriGrants(); 6341 } 6342 } 6343 6344 @Override 6345 public IBinder newUriPermissionOwner(String name) { 6346 enforceNotIsolatedCaller("newUriPermissionOwner"); 6347 synchronized(this) { 6348 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6349 return owner.getExternalTokenLocked(); 6350 } 6351 } 6352 6353 @Override 6354 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6355 Uri uri, int modeFlags) { 6356 synchronized(this) { 6357 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6358 if (owner == null) { 6359 throw new IllegalArgumentException("Unknown owner: " + token); 6360 } 6361 if (fromUid != Binder.getCallingUid()) { 6362 if (Binder.getCallingUid() != Process.myUid()) { 6363 // Only system code can grant URI permissions on behalf 6364 // of other users. 6365 throw new SecurityException("nice try"); 6366 } 6367 } 6368 if (targetPkg == null) { 6369 throw new IllegalArgumentException("null target"); 6370 } 6371 if (uri == null) { 6372 throw new IllegalArgumentException("null uri"); 6373 } 6374 6375 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6376 } 6377 } 6378 6379 @Override 6380 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6381 synchronized(this) { 6382 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6383 if (owner == null) { 6384 throw new IllegalArgumentException("Unknown owner: " + token); 6385 } 6386 6387 if (uri == null) { 6388 owner.removeUriPermissionsLocked(mode); 6389 } else { 6390 owner.removeUriPermissionLocked(uri, mode); 6391 } 6392 } 6393 } 6394 6395 private void schedulePersistUriGrants() { 6396 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6397 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6398 10 * DateUtils.SECOND_IN_MILLIS); 6399 } 6400 } 6401 6402 private void writeGrantedUriPermissions() { 6403 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6404 6405 // Snapshot permissions so we can persist without lock 6406 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6407 synchronized (this) { 6408 final int size = mGrantedUriPermissions.size(); 6409 for (int i = 0 ; i < size; i++) { 6410 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6411 if (perm.persistedModeFlags != 0) { 6412 persist.add(perm.snapshot()); 6413 } 6414 } 6415 } 6416 } 6417 6418 FileOutputStream fos = null; 6419 try { 6420 fos = mGrantFile.startWrite(); 6421 6422 XmlSerializer out = new FastXmlSerializer(); 6423 out.setOutput(fos, "utf-8"); 6424 out.startDocument(null, true); 6425 out.startTag(null, TAG_URI_GRANTS); 6426 for (UriPermission.Snapshot perm : persist) { 6427 out.startTag(null, TAG_URI_GRANT); 6428 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6429 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6430 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6431 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6432 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6433 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6434 out.endTag(null, TAG_URI_GRANT); 6435 } 6436 out.endTag(null, TAG_URI_GRANTS); 6437 out.endDocument(); 6438 6439 mGrantFile.finishWrite(fos); 6440 } catch (IOException e) { 6441 if (fos != null) { 6442 mGrantFile.failWrite(fos); 6443 } 6444 } 6445 } 6446 6447 private void readGrantedUriPermissionsLocked() { 6448 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6449 6450 final long now = System.currentTimeMillis(); 6451 6452 FileInputStream fis = null; 6453 try { 6454 fis = mGrantFile.openRead(); 6455 final XmlPullParser in = Xml.newPullParser(); 6456 in.setInput(fis, null); 6457 6458 int type; 6459 while ((type = in.next()) != END_DOCUMENT) { 6460 final String tag = in.getName(); 6461 if (type == START_TAG) { 6462 if (TAG_URI_GRANT.equals(tag)) { 6463 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6464 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6465 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6466 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6467 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6468 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6469 6470 // Sanity check that provider still belongs to source package 6471 final ProviderInfo pi = getProviderInfoLocked( 6472 uri.getAuthority(), userHandle); 6473 if (pi != null && sourcePkg.equals(pi.packageName)) { 6474 int targetUid = -1; 6475 try { 6476 targetUid = AppGlobals.getPackageManager() 6477 .getPackageUid(targetPkg, userHandle); 6478 } catch (RemoteException e) { 6479 } 6480 if (targetUid != -1) { 6481 final UriPermission perm = findOrCreateUriPermissionLocked( 6482 sourcePkg, targetPkg, targetUid, uri); 6483 perm.initPersistedModes(modeFlags, createdTime); 6484 } 6485 } else { 6486 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6487 + " but instead found " + pi); 6488 } 6489 } 6490 } 6491 } 6492 } catch (FileNotFoundException e) { 6493 // Missing grants is okay 6494 } catch (IOException e) { 6495 Log.wtf(TAG, "Failed reading Uri grants", e); 6496 } catch (XmlPullParserException e) { 6497 Log.wtf(TAG, "Failed reading Uri grants", e); 6498 } finally { 6499 IoUtils.closeQuietly(fis); 6500 } 6501 } 6502 6503 @Override 6504 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6505 enforceNotIsolatedCaller("takePersistableUriPermission"); 6506 6507 Preconditions.checkFlagsArgument(modeFlags, 6508 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6509 6510 synchronized (this) { 6511 final int callingUid = Binder.getCallingUid(); 6512 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6513 if (perm == null) { 6514 throw new SecurityException("No permission grant found for UID " + callingUid 6515 + " and Uri " + uri.toSafeString()); 6516 } 6517 6518 boolean persistChanged = perm.takePersistableModes(modeFlags); 6519 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6520 6521 if (persistChanged) { 6522 schedulePersistUriGrants(); 6523 } 6524 } 6525 } 6526 6527 @Override 6528 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6529 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6530 6531 Preconditions.checkFlagsArgument(modeFlags, 6532 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6533 6534 synchronized (this) { 6535 final int callingUid = Binder.getCallingUid(); 6536 6537 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6538 if (perm == null) { 6539 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6540 + uri.toSafeString()); 6541 return; 6542 } 6543 6544 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6545 removeUriPermissionIfNeededLocked(perm); 6546 if (persistChanged) { 6547 schedulePersistUriGrants(); 6548 } 6549 } 6550 } 6551 6552 /** 6553 * Prune any older {@link UriPermission} for the given UID until outstanding 6554 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6555 * 6556 * @return if any mutations occured that require persisting. 6557 */ 6558 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6559 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6560 if (perms == null) return false; 6561 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6562 6563 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6564 for (UriPermission perm : perms.values()) { 6565 if (perm.persistedModeFlags != 0) { 6566 persisted.add(perm); 6567 } 6568 } 6569 6570 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6571 if (trimCount <= 0) return false; 6572 6573 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6574 for (int i = 0; i < trimCount; i++) { 6575 final UriPermission perm = persisted.get(i); 6576 6577 if (DEBUG_URI_PERMISSION) { 6578 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6579 } 6580 6581 perm.releasePersistableModes(~0); 6582 removeUriPermissionIfNeededLocked(perm); 6583 } 6584 6585 return true; 6586 } 6587 6588 @Override 6589 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6590 String packageName, boolean incoming) { 6591 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6592 Preconditions.checkNotNull(packageName, "packageName"); 6593 6594 final int callingUid = Binder.getCallingUid(); 6595 final IPackageManager pm = AppGlobals.getPackageManager(); 6596 try { 6597 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6598 if (packageUid != callingUid) { 6599 throw new SecurityException( 6600 "Package " + packageName + " does not belong to calling UID " + callingUid); 6601 } 6602 } catch (RemoteException e) { 6603 throw new SecurityException("Failed to verify package name ownership"); 6604 } 6605 6606 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6607 synchronized (this) { 6608 if (incoming) { 6609 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6610 if (perms == null) { 6611 Slog.w(TAG, "No permission grants found for " + packageName); 6612 } else { 6613 final int size = perms.size(); 6614 for (int i = 0; i < size; i++) { 6615 final UriPermission perm = perms.valueAt(i); 6616 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6617 result.add(perm.buildPersistedPublicApiObject()); 6618 } 6619 } 6620 } 6621 } else { 6622 final int size = mGrantedUriPermissions.size(); 6623 for (int i = 0; i < size; i++) { 6624 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6625 final int permsSize = perms.size(); 6626 for (int j = 0; j < permsSize; j++) { 6627 final UriPermission perm = perms.valueAt(j); 6628 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6629 result.add(perm.buildPersistedPublicApiObject()); 6630 } 6631 } 6632 } 6633 } 6634 } 6635 return new ParceledListSlice<android.content.UriPermission>(result); 6636 } 6637 6638 @Override 6639 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6640 synchronized (this) { 6641 ProcessRecord app = 6642 who != null ? getRecordForAppLocked(who) : null; 6643 if (app == null) return; 6644 6645 Message msg = Message.obtain(); 6646 msg.what = WAIT_FOR_DEBUGGER_MSG; 6647 msg.obj = app; 6648 msg.arg1 = waiting ? 1 : 0; 6649 mHandler.sendMessage(msg); 6650 } 6651 } 6652 6653 @Override 6654 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6655 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6656 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6657 outInfo.availMem = Process.getFreeMemory(); 6658 outInfo.totalMem = Process.getTotalMemory(); 6659 outInfo.threshold = homeAppMem; 6660 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6661 outInfo.hiddenAppThreshold = cachedAppMem; 6662 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6663 ProcessList.SERVICE_ADJ); 6664 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6665 ProcessList.VISIBLE_APP_ADJ); 6666 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6667 ProcessList.FOREGROUND_APP_ADJ); 6668 } 6669 6670 // ========================================================= 6671 // TASK MANAGEMENT 6672 // ========================================================= 6673 6674 @Override 6675 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6676 IThumbnailReceiver receiver) { 6677 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6678 6679 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6680 ActivityRecord topRecord = null; 6681 6682 synchronized(this) { 6683 if (localLOGV) Slog.v( 6684 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6685 + ", receiver=" + receiver); 6686 6687 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6688 != PackageManager.PERMISSION_GRANTED) { 6689 if (receiver != null) { 6690 // If the caller wants to wait for pending thumbnails, 6691 // it ain't gonna get them. 6692 try { 6693 receiver.finished(); 6694 } catch (RemoteException ex) { 6695 } 6696 } 6697 String msg = "Permission Denial: getTasks() from pid=" 6698 + Binder.getCallingPid() 6699 + ", uid=" + Binder.getCallingUid() 6700 + " requires " + android.Manifest.permission.GET_TASKS; 6701 Slog.w(TAG, msg); 6702 throw new SecurityException(msg); 6703 } 6704 6705 // TODO: Improve with MRU list from all ActivityStacks. 6706 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6707 6708 if (!pending.pendingRecords.isEmpty()) { 6709 mPendingThumbnails.add(pending); 6710 } 6711 } 6712 6713 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6714 6715 if (topRecord != null) { 6716 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6717 try { 6718 IApplicationThread topThumbnail = topRecord.app.thread; 6719 topThumbnail.requestThumbnail(topRecord.appToken); 6720 } catch (Exception e) { 6721 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6722 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6723 } 6724 } 6725 6726 if (pending == null && receiver != null) { 6727 // In this case all thumbnails were available and the client 6728 // is being asked to be told when the remaining ones come in... 6729 // which is unusually, since the top-most currently running 6730 // activity should never have a canned thumbnail! Oh well. 6731 try { 6732 receiver.finished(); 6733 } catch (RemoteException ex) { 6734 } 6735 } 6736 6737 return list; 6738 } 6739 6740 TaskRecord getMostRecentTask() { 6741 return mRecentTasks.get(0); 6742 } 6743 6744 @Override 6745 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6746 int flags, int userId) { 6747 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6748 false, true, "getRecentTasks", null); 6749 6750 synchronized (this) { 6751 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6752 "getRecentTasks()"); 6753 final boolean detailed = checkCallingPermission( 6754 android.Manifest.permission.GET_DETAILED_TASKS) 6755 == PackageManager.PERMISSION_GRANTED; 6756 6757 IPackageManager pm = AppGlobals.getPackageManager(); 6758 6759 final int N = mRecentTasks.size(); 6760 ArrayList<ActivityManager.RecentTaskInfo> res 6761 = new ArrayList<ActivityManager.RecentTaskInfo>( 6762 maxNum < N ? maxNum : N); 6763 for (int i=0; i<N && maxNum > 0; i++) { 6764 TaskRecord tr = mRecentTasks.get(i); 6765 // Only add calling user's recent tasks 6766 if (tr.userId != userId) continue; 6767 // Return the entry if desired by the caller. We always return 6768 // the first entry, because callers always expect this to be the 6769 // foreground app. We may filter others if the caller has 6770 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6771 // we should exclude the entry. 6772 6773 if (i == 0 6774 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6775 || (tr.intent == null) 6776 || ((tr.intent.getFlags() 6777 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6778 ActivityManager.RecentTaskInfo rti 6779 = new ActivityManager.RecentTaskInfo(); 6780 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6781 rti.persistentId = tr.taskId; 6782 rti.baseIntent = new Intent( 6783 tr.intent != null ? tr.intent : tr.affinityIntent); 6784 if (!detailed) { 6785 rti.baseIntent.replaceExtras((Bundle)null); 6786 } 6787 rti.origActivity = tr.origActivity; 6788 rti.description = tr.lastDescription; 6789 rti.stackId = tr.stack.mStackId; 6790 6791 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6792 // Check whether this activity is currently available. 6793 try { 6794 if (rti.origActivity != null) { 6795 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6796 == null) { 6797 continue; 6798 } 6799 } else if (rti.baseIntent != null) { 6800 if (pm.queryIntentActivities(rti.baseIntent, 6801 null, 0, userId) == null) { 6802 continue; 6803 } 6804 } 6805 } catch (RemoteException e) { 6806 // Will never happen. 6807 } 6808 } 6809 6810 res.add(rti); 6811 maxNum--; 6812 } 6813 } 6814 return res; 6815 } 6816 } 6817 6818 private TaskRecord recentTaskForIdLocked(int id) { 6819 final int N = mRecentTasks.size(); 6820 for (int i=0; i<N; i++) { 6821 TaskRecord tr = mRecentTasks.get(i); 6822 if (tr.taskId == id) { 6823 return tr; 6824 } 6825 } 6826 return null; 6827 } 6828 6829 @Override 6830 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6831 synchronized (this) { 6832 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6833 "getTaskThumbnails()"); 6834 TaskRecord tr = recentTaskForIdLocked(id); 6835 if (tr != null) { 6836 return tr.getTaskThumbnailsLocked(); 6837 } 6838 } 6839 return null; 6840 } 6841 6842 @Override 6843 public Bitmap getTaskTopThumbnail(int id) { 6844 synchronized (this) { 6845 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6846 "getTaskTopThumbnail()"); 6847 TaskRecord tr = recentTaskForIdLocked(id); 6848 if (tr != null) { 6849 return tr.getTaskTopThumbnailLocked(); 6850 } 6851 } 6852 return null; 6853 } 6854 6855 @Override 6856 public boolean removeSubTask(int taskId, int subTaskIndex) { 6857 synchronized (this) { 6858 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6859 "removeSubTask()"); 6860 long ident = Binder.clearCallingIdentity(); 6861 try { 6862 TaskRecord tr = recentTaskForIdLocked(taskId); 6863 if (tr != null) { 6864 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6865 } 6866 return false; 6867 } finally { 6868 Binder.restoreCallingIdentity(ident); 6869 } 6870 } 6871 } 6872 6873 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6874 if (!pr.killedByAm) { 6875 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6876 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6877 pr.processName, pr.setAdj, reason); 6878 pr.killedByAm = true; 6879 Process.killProcessQuiet(pr.pid); 6880 } 6881 } 6882 6883 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6884 tr.disposeThumbnail(); 6885 mRecentTasks.remove(tr); 6886 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6887 Intent baseIntent = new Intent( 6888 tr.intent != null ? tr.intent : tr.affinityIntent); 6889 ComponentName component = baseIntent.getComponent(); 6890 if (component == null) { 6891 Slog.w(TAG, "Now component for base intent of task: " + tr); 6892 return; 6893 } 6894 6895 // Find any running services associated with this app. 6896 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6897 6898 if (killProcesses) { 6899 // Find any running processes associated with this app. 6900 final String pkg = component.getPackageName(); 6901 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6902 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 6903 for (int i=0; i<pmap.size(); i++) { 6904 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 6905 for (int j=0; j<uids.size(); j++) { 6906 ProcessRecord proc = uids.valueAt(j); 6907 if (proc.userId != tr.userId) { 6908 continue; 6909 } 6910 if (!proc.pkgList.containsKey(pkg)) { 6911 continue; 6912 } 6913 procs.add(proc); 6914 } 6915 } 6916 6917 // Kill the running processes. 6918 for (int i=0; i<procs.size(); i++) { 6919 ProcessRecord pr = procs.get(i); 6920 if (pr == mHomeProcess) { 6921 // Don't kill the home process along with tasks from the same package. 6922 continue; 6923 } 6924 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 6925 killUnneededProcessLocked(pr, "remove task"); 6926 } else { 6927 pr.waitingToKill = "remove task"; 6928 } 6929 } 6930 } 6931 } 6932 6933 @Override 6934 public boolean removeTask(int taskId, int flags) { 6935 synchronized (this) { 6936 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6937 "removeTask()"); 6938 long ident = Binder.clearCallingIdentity(); 6939 try { 6940 TaskRecord tr = recentTaskForIdLocked(taskId); 6941 if (tr != null) { 6942 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 6943 if (r != null) { 6944 cleanUpRemovedTaskLocked(tr, flags); 6945 return true; 6946 } 6947 if (tr.mActivities.size() == 0) { 6948 // Caller is just removing a recent task that is 6949 // not actively running. That is easy! 6950 cleanUpRemovedTaskLocked(tr, flags); 6951 return true; 6952 } 6953 Slog.w(TAG, "removeTask: task " + taskId 6954 + " does not have activities to remove, " 6955 + " but numActivities=" + tr.numActivities 6956 + ": " + tr); 6957 } 6958 } finally { 6959 Binder.restoreCallingIdentity(ident); 6960 } 6961 } 6962 return false; 6963 } 6964 6965 /** 6966 * TODO: Add mController hook 6967 */ 6968 @Override 6969 public void moveTaskToFront(int task, int flags, Bundle options) { 6970 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6971 "moveTaskToFront()"); 6972 6973 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task); 6974 synchronized(this) { 6975 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6976 Binder.getCallingUid(), "Task to front")) { 6977 ActivityOptions.abort(options); 6978 return; 6979 } 6980 final long origId = Binder.clearCallingIdentity(); 6981 try { 6982 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 6983 } finally { 6984 Binder.restoreCallingIdentity(origId); 6985 } 6986 ActivityOptions.abort(options); 6987 } 6988 } 6989 6990 @Override 6991 public void moveTaskToBack(int taskId) { 6992 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6993 "moveTaskToBack()"); 6994 6995 synchronized(this) { 6996 TaskRecord tr = recentTaskForIdLocked(taskId); 6997 if (tr != null) { 6998 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 6999 ActivityStack stack = tr.stack; 7000 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7001 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7002 Binder.getCallingUid(), "Task to back")) { 7003 return; 7004 } 7005 } 7006 final long origId = Binder.clearCallingIdentity(); 7007 try { 7008 stack.moveTaskToBackLocked(taskId, null); 7009 } finally { 7010 Binder.restoreCallingIdentity(origId); 7011 } 7012 } 7013 } 7014 } 7015 7016 /** 7017 * Moves an activity, and all of the other activities within the same task, to the bottom 7018 * of the history stack. The activity's order within the task is unchanged. 7019 * 7020 * @param token A reference to the activity we wish to move 7021 * @param nonRoot If false then this only works if the activity is the root 7022 * of a task; if true it will work for any activity in a task. 7023 * @return Returns true if the move completed, false if not. 7024 */ 7025 @Override 7026 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7027 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7028 synchronized(this) { 7029 final long origId = Binder.clearCallingIdentity(); 7030 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7031 if (taskId >= 0) { 7032 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7033 } 7034 Binder.restoreCallingIdentity(origId); 7035 } 7036 return false; 7037 } 7038 7039 @Override 7040 public void moveTaskBackwards(int task) { 7041 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7042 "moveTaskBackwards()"); 7043 7044 synchronized(this) { 7045 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7046 Binder.getCallingUid(), "Task backwards")) { 7047 return; 7048 } 7049 final long origId = Binder.clearCallingIdentity(); 7050 moveTaskBackwardsLocked(task); 7051 Binder.restoreCallingIdentity(origId); 7052 } 7053 } 7054 7055 private final void moveTaskBackwardsLocked(int task) { 7056 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7057 } 7058 7059 @Override 7060 public IBinder getHomeActivityToken() throws RemoteException { 7061 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7062 "getHomeActivityToken()"); 7063 synchronized (this) { 7064 return mStackSupervisor.getHomeActivityToken(); 7065 } 7066 } 7067 7068 @Override 7069 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7070 IActivityContainerCallback callback) throws RemoteException { 7071 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7072 "createActivityContainer()"); 7073 synchronized (this) { 7074 if (parentActivityToken == null) { 7075 throw new IllegalArgumentException("parent token must not be null"); 7076 } 7077 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7078 if (r == null) { 7079 return null; 7080 } 7081 return mStackSupervisor.createActivityContainer(r, callback); 7082 } 7083 } 7084 7085 @Override 7086 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7087 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7088 "deleteActivityContainer()"); 7089 synchronized (this) { 7090 mStackSupervisor.deleteActivityContainer(container); 7091 } 7092 } 7093 7094 @Override 7095 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7096 throws RemoteException { 7097 synchronized (this) { 7098 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7099 if (stack != null) { 7100 return stack.mActivityContainer; 7101 } 7102 return null; 7103 } 7104 } 7105 7106 @Override 7107 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7108 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7109 "moveTaskToStack()"); 7110 if (stackId == HOME_STACK_ID) { 7111 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7112 new RuntimeException("here").fillInStackTrace()); 7113 } 7114 synchronized (this) { 7115 long ident = Binder.clearCallingIdentity(); 7116 try { 7117 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7118 + stackId + " toTop=" + toTop); 7119 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7120 } finally { 7121 Binder.restoreCallingIdentity(ident); 7122 } 7123 } 7124 } 7125 7126 @Override 7127 public void resizeStack(int stackBoxId, Rect bounds) { 7128 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7129 "resizeStackBox()"); 7130 long ident = Binder.clearCallingIdentity(); 7131 try { 7132 mWindowManager.resizeStack(stackBoxId, bounds); 7133 } finally { 7134 Binder.restoreCallingIdentity(ident); 7135 } 7136 } 7137 7138 @Override 7139 public List<StackInfo> getAllStackInfos() { 7140 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7141 "getAllStackInfos()"); 7142 long ident = Binder.clearCallingIdentity(); 7143 try { 7144 synchronized (this) { 7145 return mStackSupervisor.getAllStackInfosLocked(); 7146 } 7147 } finally { 7148 Binder.restoreCallingIdentity(ident); 7149 } 7150 } 7151 7152 @Override 7153 public StackInfo getStackInfo(int stackId) { 7154 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7155 "getStackInfo()"); 7156 long ident = Binder.clearCallingIdentity(); 7157 try { 7158 synchronized (this) { 7159 return mStackSupervisor.getStackInfoLocked(stackId); 7160 } 7161 } finally { 7162 Binder.restoreCallingIdentity(ident); 7163 } 7164 } 7165 7166 @Override 7167 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7168 synchronized(this) { 7169 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7170 } 7171 } 7172 7173 // ========================================================= 7174 // THUMBNAILS 7175 // ========================================================= 7176 7177 public void reportThumbnail(IBinder token, 7178 Bitmap thumbnail, CharSequence description) { 7179 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7180 final long origId = Binder.clearCallingIdentity(); 7181 sendPendingThumbnail(null, token, thumbnail, description, true); 7182 Binder.restoreCallingIdentity(origId); 7183 } 7184 7185 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7186 Bitmap thumbnail, CharSequence description, boolean always) { 7187 TaskRecord task; 7188 ArrayList<PendingThumbnailsRecord> receivers = null; 7189 7190 //System.out.println("Send pending thumbnail: " + r); 7191 7192 synchronized(this) { 7193 if (r == null) { 7194 r = ActivityRecord.isInStackLocked(token); 7195 if (r == null) { 7196 return; 7197 } 7198 } 7199 if (thumbnail == null && r.thumbHolder != null) { 7200 thumbnail = r.thumbHolder.lastThumbnail; 7201 description = r.thumbHolder.lastDescription; 7202 } 7203 if (thumbnail == null && !always) { 7204 // If there is no thumbnail, and this entry is not actually 7205 // going away, then abort for now and pick up the next 7206 // thumbnail we get. 7207 return; 7208 } 7209 task = r.task; 7210 7211 int N = mPendingThumbnails.size(); 7212 int i=0; 7213 while (i<N) { 7214 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7215 //System.out.println("Looking in " + pr.pendingRecords); 7216 if (pr.pendingRecords.remove(r)) { 7217 if (receivers == null) { 7218 receivers = new ArrayList<PendingThumbnailsRecord>(); 7219 } 7220 receivers.add(pr); 7221 if (pr.pendingRecords.size() == 0) { 7222 pr.finished = true; 7223 mPendingThumbnails.remove(i); 7224 N--; 7225 continue; 7226 } 7227 } 7228 i++; 7229 } 7230 } 7231 7232 if (receivers != null) { 7233 final int N = receivers.size(); 7234 for (int i=0; i<N; i++) { 7235 try { 7236 PendingThumbnailsRecord pr = receivers.get(i); 7237 pr.receiver.newThumbnail( 7238 task != null ? task.taskId : -1, thumbnail, description); 7239 if (pr.finished) { 7240 pr.receiver.finished(); 7241 } 7242 } catch (Exception e) { 7243 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7244 } 7245 } 7246 } 7247 } 7248 7249 // ========================================================= 7250 // CONTENT PROVIDERS 7251 // ========================================================= 7252 7253 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7254 List<ProviderInfo> providers = null; 7255 try { 7256 providers = AppGlobals.getPackageManager(). 7257 queryContentProviders(app.processName, app.uid, 7258 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7259 } catch (RemoteException ex) { 7260 } 7261 if (DEBUG_MU) 7262 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7263 int userId = app.userId; 7264 if (providers != null) { 7265 int N = providers.size(); 7266 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7267 for (int i=0; i<N; i++) { 7268 ProviderInfo cpi = 7269 (ProviderInfo)providers.get(i); 7270 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7271 cpi.name, cpi.flags); 7272 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7273 // This is a singleton provider, but a user besides the 7274 // default user is asking to initialize a process it runs 7275 // in... well, no, it doesn't actually run in this process, 7276 // it runs in the process of the default user. Get rid of it. 7277 providers.remove(i); 7278 N--; 7279 i--; 7280 continue; 7281 } 7282 7283 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7284 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7285 if (cpr == null) { 7286 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7287 mProviderMap.putProviderByClass(comp, cpr); 7288 } 7289 if (DEBUG_MU) 7290 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7291 app.pubProviders.put(cpi.name, cpr); 7292 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7293 // Don't add this if it is a platform component that is marked 7294 // to run in multiple processes, because this is actually 7295 // part of the framework so doesn't make sense to track as a 7296 // separate apk in the process. 7297 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7298 } 7299 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7300 } 7301 } 7302 return providers; 7303 } 7304 7305 /** 7306 * Check if {@link ProcessRecord} has a possible chance at accessing the 7307 * given {@link ProviderInfo}. Final permission checking is always done 7308 * in {@link ContentProvider}. 7309 */ 7310 private final String checkContentProviderPermissionLocked( 7311 ProviderInfo cpi, ProcessRecord r) { 7312 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7313 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7314 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7315 cpi.applicationInfo.uid, cpi.exported) 7316 == PackageManager.PERMISSION_GRANTED) { 7317 return null; 7318 } 7319 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7320 cpi.applicationInfo.uid, cpi.exported) 7321 == PackageManager.PERMISSION_GRANTED) { 7322 return null; 7323 } 7324 7325 PathPermission[] pps = cpi.pathPermissions; 7326 if (pps != null) { 7327 int i = pps.length; 7328 while (i > 0) { 7329 i--; 7330 PathPermission pp = pps[i]; 7331 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7332 cpi.applicationInfo.uid, cpi.exported) 7333 == PackageManager.PERMISSION_GRANTED) { 7334 return null; 7335 } 7336 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7337 cpi.applicationInfo.uid, cpi.exported) 7338 == PackageManager.PERMISSION_GRANTED) { 7339 return null; 7340 } 7341 } 7342 } 7343 7344 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7345 if (perms != null) { 7346 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7347 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7348 return null; 7349 } 7350 } 7351 } 7352 7353 String msg; 7354 if (!cpi.exported) { 7355 msg = "Permission Denial: opening provider " + cpi.name 7356 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7357 + ", uid=" + callingUid + ") that is not exported from uid " 7358 + cpi.applicationInfo.uid; 7359 } else { 7360 msg = "Permission Denial: opening provider " + cpi.name 7361 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7362 + ", uid=" + callingUid + ") requires " 7363 + cpi.readPermission + " or " + cpi.writePermission; 7364 } 7365 Slog.w(TAG, msg); 7366 return msg; 7367 } 7368 7369 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7370 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7371 if (r != null) { 7372 for (int i=0; i<r.conProviders.size(); i++) { 7373 ContentProviderConnection conn = r.conProviders.get(i); 7374 if (conn.provider == cpr) { 7375 if (DEBUG_PROVIDER) Slog.v(TAG, 7376 "Adding provider requested by " 7377 + r.processName + " from process " 7378 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7379 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7380 if (stable) { 7381 conn.stableCount++; 7382 conn.numStableIncs++; 7383 } else { 7384 conn.unstableCount++; 7385 conn.numUnstableIncs++; 7386 } 7387 return conn; 7388 } 7389 } 7390 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7391 if (stable) { 7392 conn.stableCount = 1; 7393 conn.numStableIncs = 1; 7394 } else { 7395 conn.unstableCount = 1; 7396 conn.numUnstableIncs = 1; 7397 } 7398 cpr.connections.add(conn); 7399 r.conProviders.add(conn); 7400 return conn; 7401 } 7402 cpr.addExternalProcessHandleLocked(externalProcessToken); 7403 return null; 7404 } 7405 7406 boolean decProviderCountLocked(ContentProviderConnection conn, 7407 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7408 if (conn != null) { 7409 cpr = conn.provider; 7410 if (DEBUG_PROVIDER) Slog.v(TAG, 7411 "Removing provider requested by " 7412 + conn.client.processName + " from process " 7413 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7414 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7415 if (stable) { 7416 conn.stableCount--; 7417 } else { 7418 conn.unstableCount--; 7419 } 7420 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7421 cpr.connections.remove(conn); 7422 conn.client.conProviders.remove(conn); 7423 return true; 7424 } 7425 return false; 7426 } 7427 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7428 return false; 7429 } 7430 7431 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7432 String name, IBinder token, boolean stable, int userId) { 7433 ContentProviderRecord cpr; 7434 ContentProviderConnection conn = null; 7435 ProviderInfo cpi = null; 7436 7437 synchronized(this) { 7438 ProcessRecord r = null; 7439 if (caller != null) { 7440 r = getRecordForAppLocked(caller); 7441 if (r == null) { 7442 throw new SecurityException( 7443 "Unable to find app for caller " + caller 7444 + " (pid=" + Binder.getCallingPid() 7445 + ") when getting content provider " + name); 7446 } 7447 } 7448 7449 // First check if this content provider has been published... 7450 cpr = mProviderMap.getProviderByName(name, userId); 7451 boolean providerRunning = cpr != null; 7452 if (providerRunning) { 7453 cpi = cpr.info; 7454 String msg; 7455 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7456 throw new SecurityException(msg); 7457 } 7458 7459 if (r != null && cpr.canRunHere(r)) { 7460 // This provider has been published or is in the process 7461 // of being published... but it is also allowed to run 7462 // in the caller's process, so don't make a connection 7463 // and just let the caller instantiate its own instance. 7464 ContentProviderHolder holder = cpr.newHolder(null); 7465 // don't give caller the provider object, it needs 7466 // to make its own. 7467 holder.provider = null; 7468 return holder; 7469 } 7470 7471 final long origId = Binder.clearCallingIdentity(); 7472 7473 // In this case the provider instance already exists, so we can 7474 // return it right away. 7475 conn = incProviderCountLocked(r, cpr, token, stable); 7476 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7477 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7478 // If this is a perceptible app accessing the provider, 7479 // make sure to count it as being accessed and thus 7480 // back up on the LRU list. This is good because 7481 // content providers are often expensive to start. 7482 updateLruProcessLocked(cpr.proc, false, null); 7483 } 7484 } 7485 7486 if (cpr.proc != null) { 7487 if (false) { 7488 if (cpr.name.flattenToShortString().equals( 7489 "com.android.providers.calendar/.CalendarProvider2")) { 7490 Slog.v(TAG, "****************** KILLING " 7491 + cpr.name.flattenToShortString()); 7492 Process.killProcess(cpr.proc.pid); 7493 } 7494 } 7495 boolean success = updateOomAdjLocked(cpr.proc); 7496 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7497 // NOTE: there is still a race here where a signal could be 7498 // pending on the process even though we managed to update its 7499 // adj level. Not sure what to do about this, but at least 7500 // the race is now smaller. 7501 if (!success) { 7502 // Uh oh... it looks like the provider's process 7503 // has been killed on us. We need to wait for a new 7504 // process to be started, and make sure its death 7505 // doesn't kill our process. 7506 Slog.i(TAG, 7507 "Existing provider " + cpr.name.flattenToShortString() 7508 + " is crashing; detaching " + r); 7509 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7510 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7511 if (!lastRef) { 7512 // This wasn't the last ref our process had on 7513 // the provider... we have now been killed, bail. 7514 return null; 7515 } 7516 providerRunning = false; 7517 conn = null; 7518 } 7519 } 7520 7521 Binder.restoreCallingIdentity(origId); 7522 } 7523 7524 boolean singleton; 7525 if (!providerRunning) { 7526 try { 7527 cpi = AppGlobals.getPackageManager(). 7528 resolveContentProvider(name, 7529 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7530 } catch (RemoteException ex) { 7531 } 7532 if (cpi == null) { 7533 return null; 7534 } 7535 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7536 cpi.name, cpi.flags); 7537 if (singleton) { 7538 userId = 0; 7539 } 7540 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7541 7542 String msg; 7543 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7544 throw new SecurityException(msg); 7545 } 7546 7547 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7548 && !cpi.processName.equals("system")) { 7549 // If this content provider does not run in the system 7550 // process, and the system is not yet ready to run other 7551 // processes, then fail fast instead of hanging. 7552 throw new IllegalArgumentException( 7553 "Attempt to launch content provider before system ready"); 7554 } 7555 7556 // Make sure that the user who owns this provider is started. If not, 7557 // we don't want to allow it to run. 7558 if (mStartedUsers.get(userId) == null) { 7559 Slog.w(TAG, "Unable to launch app " 7560 + cpi.applicationInfo.packageName + "/" 7561 + cpi.applicationInfo.uid + " for provider " 7562 + name + ": user " + userId + " is stopped"); 7563 return null; 7564 } 7565 7566 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7567 cpr = mProviderMap.getProviderByClass(comp, userId); 7568 final boolean firstClass = cpr == null; 7569 if (firstClass) { 7570 try { 7571 ApplicationInfo ai = 7572 AppGlobals.getPackageManager(). 7573 getApplicationInfo( 7574 cpi.applicationInfo.packageName, 7575 STOCK_PM_FLAGS, userId); 7576 if (ai == null) { 7577 Slog.w(TAG, "No package info for content provider " 7578 + cpi.name); 7579 return null; 7580 } 7581 ai = getAppInfoForUser(ai, userId); 7582 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7583 } catch (RemoteException ex) { 7584 // pm is in same process, this will never happen. 7585 } 7586 } 7587 7588 if (r != null && cpr.canRunHere(r)) { 7589 // If this is a multiprocess provider, then just return its 7590 // info and allow the caller to instantiate it. Only do 7591 // this if the provider is the same user as the caller's 7592 // process, or can run as root (so can be in any process). 7593 return cpr.newHolder(null); 7594 } 7595 7596 if (DEBUG_PROVIDER) { 7597 RuntimeException e = new RuntimeException("here"); 7598 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7599 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7600 } 7601 7602 // This is single process, and our app is now connecting to it. 7603 // See if we are already in the process of launching this 7604 // provider. 7605 final int N = mLaunchingProviders.size(); 7606 int i; 7607 for (i=0; i<N; i++) { 7608 if (mLaunchingProviders.get(i) == cpr) { 7609 break; 7610 } 7611 } 7612 7613 // If the provider is not already being launched, then get it 7614 // started. 7615 if (i >= N) { 7616 final long origId = Binder.clearCallingIdentity(); 7617 7618 try { 7619 // Content provider is now in use, its package can't be stopped. 7620 try { 7621 AppGlobals.getPackageManager().setPackageStoppedState( 7622 cpr.appInfo.packageName, false, userId); 7623 } catch (RemoteException e) { 7624 } catch (IllegalArgumentException e) { 7625 Slog.w(TAG, "Failed trying to unstop package " 7626 + cpr.appInfo.packageName + ": " + e); 7627 } 7628 7629 // Use existing process if already started 7630 ProcessRecord proc = getProcessRecordLocked( 7631 cpi.processName, cpr.appInfo.uid, false); 7632 if (proc != null && proc.thread != null) { 7633 if (DEBUG_PROVIDER) { 7634 Slog.d(TAG, "Installing in existing process " + proc); 7635 } 7636 proc.pubProviders.put(cpi.name, cpr); 7637 try { 7638 proc.thread.scheduleInstallProvider(cpi); 7639 } catch (RemoteException e) { 7640 } 7641 } else { 7642 proc = startProcessLocked(cpi.processName, 7643 cpr.appInfo, false, 0, "content provider", 7644 new ComponentName(cpi.applicationInfo.packageName, 7645 cpi.name), false, false, false); 7646 if (proc == null) { 7647 Slog.w(TAG, "Unable to launch app " 7648 + cpi.applicationInfo.packageName + "/" 7649 + cpi.applicationInfo.uid + " for provider " 7650 + name + ": process is bad"); 7651 return null; 7652 } 7653 } 7654 cpr.launchingApp = proc; 7655 mLaunchingProviders.add(cpr); 7656 } finally { 7657 Binder.restoreCallingIdentity(origId); 7658 } 7659 } 7660 7661 // Make sure the provider is published (the same provider class 7662 // may be published under multiple names). 7663 if (firstClass) { 7664 mProviderMap.putProviderByClass(comp, cpr); 7665 } 7666 7667 mProviderMap.putProviderByName(name, cpr); 7668 conn = incProviderCountLocked(r, cpr, token, stable); 7669 if (conn != null) { 7670 conn.waiting = true; 7671 } 7672 } 7673 } 7674 7675 // Wait for the provider to be published... 7676 synchronized (cpr) { 7677 while (cpr.provider == null) { 7678 if (cpr.launchingApp == null) { 7679 Slog.w(TAG, "Unable to launch app " 7680 + cpi.applicationInfo.packageName + "/" 7681 + cpi.applicationInfo.uid + " for provider " 7682 + name + ": launching app became null"); 7683 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7684 UserHandle.getUserId(cpi.applicationInfo.uid), 7685 cpi.applicationInfo.packageName, 7686 cpi.applicationInfo.uid, name); 7687 return null; 7688 } 7689 try { 7690 if (DEBUG_MU) { 7691 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7692 + cpr.launchingApp); 7693 } 7694 if (conn != null) { 7695 conn.waiting = true; 7696 } 7697 cpr.wait(); 7698 } catch (InterruptedException ex) { 7699 } finally { 7700 if (conn != null) { 7701 conn.waiting = false; 7702 } 7703 } 7704 } 7705 } 7706 return cpr != null ? cpr.newHolder(conn) : null; 7707 } 7708 7709 public final ContentProviderHolder getContentProvider( 7710 IApplicationThread caller, String name, int userId, boolean stable) { 7711 enforceNotIsolatedCaller("getContentProvider"); 7712 if (caller == null) { 7713 String msg = "null IApplicationThread when getting content provider " 7714 + name; 7715 Slog.w(TAG, msg); 7716 throw new SecurityException(msg); 7717 } 7718 7719 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7720 false, true, "getContentProvider", null); 7721 return getContentProviderImpl(caller, name, null, stable, userId); 7722 } 7723 7724 public ContentProviderHolder getContentProviderExternal( 7725 String name, int userId, IBinder token) { 7726 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7727 "Do not have permission in call getContentProviderExternal()"); 7728 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7729 false, true, "getContentProvider", null); 7730 return getContentProviderExternalUnchecked(name, token, userId); 7731 } 7732 7733 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7734 IBinder token, int userId) { 7735 return getContentProviderImpl(null, name, token, true, userId); 7736 } 7737 7738 /** 7739 * Drop a content provider from a ProcessRecord's bookkeeping 7740 */ 7741 public void removeContentProvider(IBinder connection, boolean stable) { 7742 enforceNotIsolatedCaller("removeContentProvider"); 7743 synchronized (this) { 7744 ContentProviderConnection conn; 7745 try { 7746 conn = (ContentProviderConnection)connection; 7747 } catch (ClassCastException e) { 7748 String msg ="removeContentProvider: " + connection 7749 + " not a ContentProviderConnection"; 7750 Slog.w(TAG, msg); 7751 throw new IllegalArgumentException(msg); 7752 } 7753 if (conn == null) { 7754 throw new NullPointerException("connection is null"); 7755 } 7756 if (decProviderCountLocked(conn, null, null, stable)) { 7757 updateOomAdjLocked(); 7758 } 7759 } 7760 } 7761 7762 public void removeContentProviderExternal(String name, IBinder token) { 7763 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7764 "Do not have permission in call removeContentProviderExternal()"); 7765 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7766 } 7767 7768 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7769 synchronized (this) { 7770 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7771 if(cpr == null) { 7772 //remove from mProvidersByClass 7773 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7774 return; 7775 } 7776 7777 //update content provider record entry info 7778 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7779 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7780 if (localCpr.hasExternalProcessHandles()) { 7781 if (localCpr.removeExternalProcessHandleLocked(token)) { 7782 updateOomAdjLocked(); 7783 } else { 7784 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7785 + " with no external reference for token: " 7786 + token + "."); 7787 } 7788 } else { 7789 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7790 + " with no external references."); 7791 } 7792 } 7793 } 7794 7795 public final void publishContentProviders(IApplicationThread caller, 7796 List<ContentProviderHolder> providers) { 7797 if (providers == null) { 7798 return; 7799 } 7800 7801 enforceNotIsolatedCaller("publishContentProviders"); 7802 synchronized (this) { 7803 final ProcessRecord r = getRecordForAppLocked(caller); 7804 if (DEBUG_MU) 7805 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 7806 if (r == null) { 7807 throw new SecurityException( 7808 "Unable to find app for caller " + caller 7809 + " (pid=" + Binder.getCallingPid() 7810 + ") when publishing content providers"); 7811 } 7812 7813 final long origId = Binder.clearCallingIdentity(); 7814 7815 final int N = providers.size(); 7816 for (int i=0; i<N; i++) { 7817 ContentProviderHolder src = providers.get(i); 7818 if (src == null || src.info == null || src.provider == null) { 7819 continue; 7820 } 7821 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 7822 if (DEBUG_MU) 7823 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 7824 if (dst != null) { 7825 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 7826 mProviderMap.putProviderByClass(comp, dst); 7827 String names[] = dst.info.authority.split(";"); 7828 for (int j = 0; j < names.length; j++) { 7829 mProviderMap.putProviderByName(names[j], dst); 7830 } 7831 7832 int NL = mLaunchingProviders.size(); 7833 int j; 7834 for (j=0; j<NL; j++) { 7835 if (mLaunchingProviders.get(j) == dst) { 7836 mLaunchingProviders.remove(j); 7837 j--; 7838 NL--; 7839 } 7840 } 7841 synchronized (dst) { 7842 dst.provider = src.provider; 7843 dst.proc = r; 7844 dst.notifyAll(); 7845 } 7846 updateOomAdjLocked(r); 7847 } 7848 } 7849 7850 Binder.restoreCallingIdentity(origId); 7851 } 7852 } 7853 7854 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 7855 ContentProviderConnection conn; 7856 try { 7857 conn = (ContentProviderConnection)connection; 7858 } catch (ClassCastException e) { 7859 String msg ="refContentProvider: " + connection 7860 + " not a ContentProviderConnection"; 7861 Slog.w(TAG, msg); 7862 throw new IllegalArgumentException(msg); 7863 } 7864 if (conn == null) { 7865 throw new NullPointerException("connection is null"); 7866 } 7867 7868 synchronized (this) { 7869 if (stable > 0) { 7870 conn.numStableIncs += stable; 7871 } 7872 stable = conn.stableCount + stable; 7873 if (stable < 0) { 7874 throw new IllegalStateException("stableCount < 0: " + stable); 7875 } 7876 7877 if (unstable > 0) { 7878 conn.numUnstableIncs += unstable; 7879 } 7880 unstable = conn.unstableCount + unstable; 7881 if (unstable < 0) { 7882 throw new IllegalStateException("unstableCount < 0: " + unstable); 7883 } 7884 7885 if ((stable+unstable) <= 0) { 7886 throw new IllegalStateException("ref counts can't go to zero here: stable=" 7887 + stable + " unstable=" + unstable); 7888 } 7889 conn.stableCount = stable; 7890 conn.unstableCount = unstable; 7891 return !conn.dead; 7892 } 7893 } 7894 7895 public void unstableProviderDied(IBinder connection) { 7896 ContentProviderConnection conn; 7897 try { 7898 conn = (ContentProviderConnection)connection; 7899 } catch (ClassCastException e) { 7900 String msg ="refContentProvider: " + connection 7901 + " not a ContentProviderConnection"; 7902 Slog.w(TAG, msg); 7903 throw new IllegalArgumentException(msg); 7904 } 7905 if (conn == null) { 7906 throw new NullPointerException("connection is null"); 7907 } 7908 7909 // Safely retrieve the content provider associated with the connection. 7910 IContentProvider provider; 7911 synchronized (this) { 7912 provider = conn.provider.provider; 7913 } 7914 7915 if (provider == null) { 7916 // Um, yeah, we're way ahead of you. 7917 return; 7918 } 7919 7920 // Make sure the caller is being honest with us. 7921 if (provider.asBinder().pingBinder()) { 7922 // Er, no, still looks good to us. 7923 synchronized (this) { 7924 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 7925 + " says " + conn + " died, but we don't agree"); 7926 return; 7927 } 7928 } 7929 7930 // Well look at that! It's dead! 7931 synchronized (this) { 7932 if (conn.provider.provider != provider) { 7933 // But something changed... good enough. 7934 return; 7935 } 7936 7937 ProcessRecord proc = conn.provider.proc; 7938 if (proc == null || proc.thread == null) { 7939 // Seems like the process is already cleaned up. 7940 return; 7941 } 7942 7943 // As far as we're concerned, this is just like receiving a 7944 // death notification... just a bit prematurely. 7945 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 7946 + ") early provider death"); 7947 final long ident = Binder.clearCallingIdentity(); 7948 try { 7949 appDiedLocked(proc, proc.pid, proc.thread); 7950 } finally { 7951 Binder.restoreCallingIdentity(ident); 7952 } 7953 } 7954 } 7955 7956 @Override 7957 public void appNotRespondingViaProvider(IBinder connection) { 7958 enforceCallingPermission( 7959 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 7960 7961 final ContentProviderConnection conn = (ContentProviderConnection) connection; 7962 if (conn == null) { 7963 Slog.w(TAG, "ContentProviderConnection is null"); 7964 return; 7965 } 7966 7967 final ProcessRecord host = conn.provider.proc; 7968 if (host == null) { 7969 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 7970 return; 7971 } 7972 7973 final long token = Binder.clearCallingIdentity(); 7974 try { 7975 appNotResponding(host, null, null, false, "ContentProvider not responding"); 7976 } finally { 7977 Binder.restoreCallingIdentity(token); 7978 } 7979 } 7980 7981 public final void installSystemProviders() { 7982 List<ProviderInfo> providers; 7983 synchronized (this) { 7984 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 7985 providers = generateApplicationProvidersLocked(app); 7986 if (providers != null) { 7987 for (int i=providers.size()-1; i>=0; i--) { 7988 ProviderInfo pi = (ProviderInfo)providers.get(i); 7989 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 7990 Slog.w(TAG, "Not installing system proc provider " + pi.name 7991 + ": not system .apk"); 7992 providers.remove(i); 7993 } 7994 } 7995 } 7996 } 7997 if (providers != null) { 7998 mSystemThread.installSystemProviders(providers); 7999 } 8000 8001 mCoreSettingsObserver = new CoreSettingsObserver(this); 8002 8003 mUsageStatsService.monitorPackages(); 8004 } 8005 8006 /** 8007 * Allows app to retrieve the MIME type of a URI without having permission 8008 * to access its content provider. 8009 * 8010 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8011 * 8012 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8013 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8014 */ 8015 public String getProviderMimeType(Uri uri, int userId) { 8016 enforceNotIsolatedCaller("getProviderMimeType"); 8017 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8018 userId, false, true, "getProviderMimeType", null); 8019 final String name = uri.getAuthority(); 8020 final long ident = Binder.clearCallingIdentity(); 8021 ContentProviderHolder holder = null; 8022 8023 try { 8024 holder = getContentProviderExternalUnchecked(name, null, userId); 8025 if (holder != null) { 8026 return holder.provider.getType(uri); 8027 } 8028 } catch (RemoteException e) { 8029 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8030 return null; 8031 } finally { 8032 if (holder != null) { 8033 removeContentProviderExternalUnchecked(name, null, userId); 8034 } 8035 Binder.restoreCallingIdentity(ident); 8036 } 8037 8038 return null; 8039 } 8040 8041 // ========================================================= 8042 // GLOBAL MANAGEMENT 8043 // ========================================================= 8044 8045 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8046 boolean isolated) { 8047 String proc = customProcess != null ? customProcess : info.processName; 8048 BatteryStatsImpl.Uid.Proc ps = null; 8049 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8050 int uid = info.uid; 8051 if (isolated) { 8052 int userId = UserHandle.getUserId(uid); 8053 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8054 while (true) { 8055 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8056 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8057 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8058 } 8059 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8060 mNextIsolatedProcessUid++; 8061 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8062 // No process for this uid, use it. 8063 break; 8064 } 8065 stepsLeft--; 8066 if (stepsLeft <= 0) { 8067 return null; 8068 } 8069 } 8070 } 8071 return new ProcessRecord(stats, info, proc, uid); 8072 } 8073 8074 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8075 ProcessRecord app; 8076 if (!isolated) { 8077 app = getProcessRecordLocked(info.processName, info.uid, true); 8078 } else { 8079 app = null; 8080 } 8081 8082 if (app == null) { 8083 app = newProcessRecordLocked(info, null, isolated); 8084 mProcessNames.put(info.processName, app.uid, app); 8085 if (isolated) { 8086 mIsolatedProcesses.put(app.uid, app); 8087 } 8088 updateLruProcessLocked(app, false, null); 8089 updateOomAdjLocked(); 8090 } 8091 8092 // This package really, really can not be stopped. 8093 try { 8094 AppGlobals.getPackageManager().setPackageStoppedState( 8095 info.packageName, false, UserHandle.getUserId(app.uid)); 8096 } catch (RemoteException e) { 8097 } catch (IllegalArgumentException e) { 8098 Slog.w(TAG, "Failed trying to unstop package " 8099 + info.packageName + ": " + e); 8100 } 8101 8102 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8103 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8104 app.persistent = true; 8105 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8106 } 8107 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8108 mPersistentStartingProcesses.add(app); 8109 startProcessLocked(app, "added application", app.processName); 8110 } 8111 8112 return app; 8113 } 8114 8115 public void unhandledBack() { 8116 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8117 "unhandledBack()"); 8118 8119 synchronized(this) { 8120 final long origId = Binder.clearCallingIdentity(); 8121 try { 8122 getFocusedStack().unhandledBackLocked(); 8123 } finally { 8124 Binder.restoreCallingIdentity(origId); 8125 } 8126 } 8127 } 8128 8129 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8130 enforceNotIsolatedCaller("openContentUri"); 8131 final int userId = UserHandle.getCallingUserId(); 8132 String name = uri.getAuthority(); 8133 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8134 ParcelFileDescriptor pfd = null; 8135 if (cph != null) { 8136 // We record the binder invoker's uid in thread-local storage before 8137 // going to the content provider to open the file. Later, in the code 8138 // that handles all permissions checks, we look for this uid and use 8139 // that rather than the Activity Manager's own uid. The effect is that 8140 // we do the check against the caller's permissions even though it looks 8141 // to the content provider like the Activity Manager itself is making 8142 // the request. 8143 sCallerIdentity.set(new Identity( 8144 Binder.getCallingPid(), Binder.getCallingUid())); 8145 try { 8146 pfd = cph.provider.openFile(null, uri, "r", null); 8147 } catch (FileNotFoundException e) { 8148 // do nothing; pfd will be returned null 8149 } finally { 8150 // Ensure that whatever happens, we clean up the identity state 8151 sCallerIdentity.remove(); 8152 } 8153 8154 // We've got the fd now, so we're done with the provider. 8155 removeContentProviderExternalUnchecked(name, null, userId); 8156 } else { 8157 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8158 } 8159 return pfd; 8160 } 8161 8162 // Actually is sleeping or shutting down or whatever else in the future 8163 // is an inactive state. 8164 public boolean isSleepingOrShuttingDown() { 8165 return mSleeping || mShuttingDown; 8166 } 8167 8168 void goingToSleep() { 8169 synchronized(this) { 8170 mWentToSleep = true; 8171 updateEventDispatchingLocked(); 8172 8173 if (!mSleeping) { 8174 mSleeping = true; 8175 mStackSupervisor.goingToSleepLocked(); 8176 8177 // Initialize the wake times of all processes. 8178 checkExcessivePowerUsageLocked(false); 8179 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8180 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8181 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8182 } 8183 } 8184 } 8185 8186 @Override 8187 public boolean shutdown(int timeout) { 8188 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8189 != PackageManager.PERMISSION_GRANTED) { 8190 throw new SecurityException("Requires permission " 8191 + android.Manifest.permission.SHUTDOWN); 8192 } 8193 8194 boolean timedout = false; 8195 8196 synchronized(this) { 8197 mShuttingDown = true; 8198 updateEventDispatchingLocked(); 8199 timedout = mStackSupervisor.shutdownLocked(timeout); 8200 } 8201 8202 mAppOpsService.shutdown(); 8203 mUsageStatsService.shutdown(); 8204 mBatteryStatsService.shutdown(); 8205 synchronized (this) { 8206 mProcessStats.shutdownLocked(); 8207 } 8208 8209 return timedout; 8210 } 8211 8212 public final void activitySlept(IBinder token) { 8213 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8214 8215 final long origId = Binder.clearCallingIdentity(); 8216 8217 synchronized (this) { 8218 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8219 if (r != null) { 8220 mStackSupervisor.activitySleptLocked(r); 8221 } 8222 } 8223 8224 Binder.restoreCallingIdentity(origId); 8225 } 8226 8227 void logLockScreen(String msg) { 8228 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8229 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8230 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8231 mStackSupervisor.mDismissKeyguardOnNextActivity); 8232 } 8233 8234 private void comeOutOfSleepIfNeededLocked() { 8235 if (!mWentToSleep && !mLockScreenShown) { 8236 if (mSleeping) { 8237 mSleeping = false; 8238 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8239 } 8240 } 8241 } 8242 8243 void wakingUp() { 8244 synchronized(this) { 8245 mWentToSleep = false; 8246 updateEventDispatchingLocked(); 8247 comeOutOfSleepIfNeededLocked(); 8248 } 8249 } 8250 8251 private void updateEventDispatchingLocked() { 8252 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8253 } 8254 8255 public void setLockScreenShown(boolean shown) { 8256 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8257 != PackageManager.PERMISSION_GRANTED) { 8258 throw new SecurityException("Requires permission " 8259 + android.Manifest.permission.DEVICE_POWER); 8260 } 8261 8262 synchronized(this) { 8263 long ident = Binder.clearCallingIdentity(); 8264 try { 8265 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8266 mLockScreenShown = shown; 8267 comeOutOfSleepIfNeededLocked(); 8268 } finally { 8269 Binder.restoreCallingIdentity(ident); 8270 } 8271 } 8272 } 8273 8274 public void stopAppSwitches() { 8275 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8276 != PackageManager.PERMISSION_GRANTED) { 8277 throw new SecurityException("Requires permission " 8278 + android.Manifest.permission.STOP_APP_SWITCHES); 8279 } 8280 8281 synchronized(this) { 8282 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8283 + APP_SWITCH_DELAY_TIME; 8284 mDidAppSwitch = false; 8285 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8286 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8287 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8288 } 8289 } 8290 8291 public void resumeAppSwitches() { 8292 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8293 != PackageManager.PERMISSION_GRANTED) { 8294 throw new SecurityException("Requires permission " 8295 + android.Manifest.permission.STOP_APP_SWITCHES); 8296 } 8297 8298 synchronized(this) { 8299 // Note that we don't execute any pending app switches... we will 8300 // let those wait until either the timeout, or the next start 8301 // activity request. 8302 mAppSwitchesAllowedTime = 0; 8303 } 8304 } 8305 8306 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8307 String name) { 8308 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8309 return true; 8310 } 8311 8312 final int perm = checkComponentPermission( 8313 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8314 callingUid, -1, true); 8315 if (perm == PackageManager.PERMISSION_GRANTED) { 8316 return true; 8317 } 8318 8319 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8320 return false; 8321 } 8322 8323 public void setDebugApp(String packageName, boolean waitForDebugger, 8324 boolean persistent) { 8325 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8326 "setDebugApp()"); 8327 8328 long ident = Binder.clearCallingIdentity(); 8329 try { 8330 // Note that this is not really thread safe if there are multiple 8331 // callers into it at the same time, but that's not a situation we 8332 // care about. 8333 if (persistent) { 8334 final ContentResolver resolver = mContext.getContentResolver(); 8335 Settings.Global.putString( 8336 resolver, Settings.Global.DEBUG_APP, 8337 packageName); 8338 Settings.Global.putInt( 8339 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8340 waitForDebugger ? 1 : 0); 8341 } 8342 8343 synchronized (this) { 8344 if (!persistent) { 8345 mOrigDebugApp = mDebugApp; 8346 mOrigWaitForDebugger = mWaitForDebugger; 8347 } 8348 mDebugApp = packageName; 8349 mWaitForDebugger = waitForDebugger; 8350 mDebugTransient = !persistent; 8351 if (packageName != null) { 8352 forceStopPackageLocked(packageName, -1, false, false, true, true, 8353 UserHandle.USER_ALL, "set debug app"); 8354 } 8355 } 8356 } finally { 8357 Binder.restoreCallingIdentity(ident); 8358 } 8359 } 8360 8361 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8362 synchronized (this) { 8363 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8364 if (!isDebuggable) { 8365 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8366 throw new SecurityException("Process not debuggable: " + app.packageName); 8367 } 8368 } 8369 8370 mOpenGlTraceApp = processName; 8371 } 8372 } 8373 8374 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8375 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8376 synchronized (this) { 8377 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8378 if (!isDebuggable) { 8379 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8380 throw new SecurityException("Process not debuggable: " + app.packageName); 8381 } 8382 } 8383 mProfileApp = processName; 8384 mProfileFile = profileFile; 8385 if (mProfileFd != null) { 8386 try { 8387 mProfileFd.close(); 8388 } catch (IOException e) { 8389 } 8390 mProfileFd = null; 8391 } 8392 mProfileFd = profileFd; 8393 mProfileType = 0; 8394 mAutoStopProfiler = autoStopProfiler; 8395 } 8396 } 8397 8398 @Override 8399 public void setAlwaysFinish(boolean enabled) { 8400 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8401 "setAlwaysFinish()"); 8402 8403 Settings.Global.putInt( 8404 mContext.getContentResolver(), 8405 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8406 8407 synchronized (this) { 8408 mAlwaysFinishActivities = enabled; 8409 } 8410 } 8411 8412 @Override 8413 public void setActivityController(IActivityController controller) { 8414 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8415 "setActivityController()"); 8416 synchronized (this) { 8417 mController = controller; 8418 Watchdog.getInstance().setActivityController(controller); 8419 } 8420 } 8421 8422 @Override 8423 public void setUserIsMonkey(boolean userIsMonkey) { 8424 synchronized (this) { 8425 synchronized (mPidsSelfLocked) { 8426 final int callingPid = Binder.getCallingPid(); 8427 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8428 if (precessRecord == null) { 8429 throw new SecurityException("Unknown process: " + callingPid); 8430 } 8431 if (precessRecord.instrumentationUiAutomationConnection == null) { 8432 throw new SecurityException("Only an instrumentation process " 8433 + "with a UiAutomation can call setUserIsMonkey"); 8434 } 8435 } 8436 mUserIsMonkey = userIsMonkey; 8437 } 8438 } 8439 8440 @Override 8441 public boolean isUserAMonkey() { 8442 synchronized (this) { 8443 // If there is a controller also implies the user is a monkey. 8444 return (mUserIsMonkey || mController != null); 8445 } 8446 } 8447 8448 public void requestBugReport() { 8449 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8450 SystemProperties.set("ctl.start", "bugreport"); 8451 } 8452 8453 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8454 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8455 } 8456 8457 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8458 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8459 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8460 } 8461 return KEY_DISPATCHING_TIMEOUT; 8462 } 8463 8464 @Override 8465 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8466 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8467 != PackageManager.PERMISSION_GRANTED) { 8468 throw new SecurityException("Requires permission " 8469 + android.Manifest.permission.FILTER_EVENTS); 8470 } 8471 ProcessRecord proc; 8472 long timeout; 8473 synchronized (this) { 8474 synchronized (mPidsSelfLocked) { 8475 proc = mPidsSelfLocked.get(pid); 8476 } 8477 timeout = getInputDispatchingTimeoutLocked(proc); 8478 } 8479 8480 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8481 return -1; 8482 } 8483 8484 return timeout; 8485 } 8486 8487 /** 8488 * Handle input dispatching timeouts. 8489 * Returns whether input dispatching should be aborted or not. 8490 */ 8491 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8492 final ActivityRecord activity, final ActivityRecord parent, 8493 final boolean aboveSystem, String reason) { 8494 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8495 != PackageManager.PERMISSION_GRANTED) { 8496 throw new SecurityException("Requires permission " 8497 + android.Manifest.permission.FILTER_EVENTS); 8498 } 8499 8500 final String annotation; 8501 if (reason == null) { 8502 annotation = "Input dispatching timed out"; 8503 } else { 8504 annotation = "Input dispatching timed out (" + reason + ")"; 8505 } 8506 8507 if (proc != null) { 8508 synchronized (this) { 8509 if (proc.debugging) { 8510 return false; 8511 } 8512 8513 if (mDidDexOpt) { 8514 // Give more time since we were dexopting. 8515 mDidDexOpt = false; 8516 return false; 8517 } 8518 8519 if (proc.instrumentationClass != null) { 8520 Bundle info = new Bundle(); 8521 info.putString("shortMsg", "keyDispatchingTimedOut"); 8522 info.putString("longMsg", annotation); 8523 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8524 return true; 8525 } 8526 } 8527 mHandler.post(new Runnable() { 8528 @Override 8529 public void run() { 8530 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8531 } 8532 }); 8533 } 8534 8535 return true; 8536 } 8537 8538 public Bundle getAssistContextExtras(int requestType) { 8539 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8540 "getAssistContextExtras()"); 8541 PendingAssistExtras pae; 8542 Bundle extras = new Bundle(); 8543 synchronized (this) { 8544 ActivityRecord activity = getFocusedStack().mResumedActivity; 8545 if (activity == null) { 8546 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8547 return null; 8548 } 8549 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8550 if (activity.app == null || activity.app.thread == null) { 8551 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8552 return extras; 8553 } 8554 if (activity.app.pid == Binder.getCallingPid()) { 8555 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8556 return extras; 8557 } 8558 pae = new PendingAssistExtras(activity); 8559 try { 8560 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8561 requestType); 8562 mPendingAssistExtras.add(pae); 8563 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8564 } catch (RemoteException e) { 8565 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8566 return extras; 8567 } 8568 } 8569 synchronized (pae) { 8570 while (!pae.haveResult) { 8571 try { 8572 pae.wait(); 8573 } catch (InterruptedException e) { 8574 } 8575 } 8576 if (pae.result != null) { 8577 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8578 } 8579 } 8580 synchronized (this) { 8581 mPendingAssistExtras.remove(pae); 8582 mHandler.removeCallbacks(pae); 8583 } 8584 return extras; 8585 } 8586 8587 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8588 PendingAssistExtras pae = (PendingAssistExtras)token; 8589 synchronized (pae) { 8590 pae.result = extras; 8591 pae.haveResult = true; 8592 pae.notifyAll(); 8593 } 8594 } 8595 8596 public void registerProcessObserver(IProcessObserver observer) { 8597 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8598 "registerProcessObserver()"); 8599 synchronized (this) { 8600 mProcessObservers.register(observer); 8601 } 8602 } 8603 8604 @Override 8605 public void unregisterProcessObserver(IProcessObserver observer) { 8606 synchronized (this) { 8607 mProcessObservers.unregister(observer); 8608 } 8609 } 8610 8611 @Override 8612 public boolean convertFromTranslucent(IBinder token) { 8613 final long origId = Binder.clearCallingIdentity(); 8614 try { 8615 synchronized (this) { 8616 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8617 if (r == null) { 8618 return false; 8619 } 8620 if (r.changeWindowTranslucency(true)) { 8621 mWindowManager.setAppFullscreen(token, true); 8622 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8623 return true; 8624 } 8625 return false; 8626 } 8627 } finally { 8628 Binder.restoreCallingIdentity(origId); 8629 } 8630 } 8631 8632 @Override 8633 public boolean convertToTranslucent(IBinder token) { 8634 final long origId = Binder.clearCallingIdentity(); 8635 try { 8636 synchronized (this) { 8637 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8638 if (r == null) { 8639 return false; 8640 } 8641 if (r.changeWindowTranslucency(false)) { 8642 r.task.stack.convertToTranslucent(r); 8643 mWindowManager.setAppFullscreen(token, false); 8644 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8645 return true; 8646 } 8647 return false; 8648 } 8649 } finally { 8650 Binder.restoreCallingIdentity(origId); 8651 } 8652 } 8653 8654 @Override 8655 public void setImmersive(IBinder token, boolean immersive) { 8656 synchronized(this) { 8657 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8658 if (r == null) { 8659 throw new IllegalArgumentException(); 8660 } 8661 r.immersive = immersive; 8662 8663 // update associated state if we're frontmost 8664 if (r == mFocusedActivity) { 8665 if (DEBUG_IMMERSIVE) { 8666 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8667 } 8668 applyUpdateLockStateLocked(r); 8669 } 8670 } 8671 } 8672 8673 @Override 8674 public boolean isImmersive(IBinder token) { 8675 synchronized (this) { 8676 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8677 if (r == null) { 8678 throw new IllegalArgumentException(); 8679 } 8680 return r.immersive; 8681 } 8682 } 8683 8684 public boolean isTopActivityImmersive() { 8685 enforceNotIsolatedCaller("startActivity"); 8686 synchronized (this) { 8687 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8688 return (r != null) ? r.immersive : false; 8689 } 8690 } 8691 8692 public final void enterSafeMode() { 8693 synchronized(this) { 8694 // It only makes sense to do this before the system is ready 8695 // and started launching other packages. 8696 if (!mSystemReady) { 8697 try { 8698 AppGlobals.getPackageManager().enterSafeMode(); 8699 } catch (RemoteException e) { 8700 } 8701 } 8702 } 8703 } 8704 8705 public final void showSafeModeOverlay() { 8706 View v = LayoutInflater.from(mContext).inflate( 8707 com.android.internal.R.layout.safe_mode, null); 8708 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8709 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8710 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8711 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8712 lp.gravity = Gravity.BOTTOM | Gravity.START; 8713 lp.format = v.getBackground().getOpacity(); 8714 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8715 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8716 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8717 ((WindowManager)mContext.getSystemService( 8718 Context.WINDOW_SERVICE)).addView(v, lp); 8719 } 8720 8721 public void noteWakeupAlarm(IIntentSender sender) { 8722 if (!(sender instanceof PendingIntentRecord)) { 8723 return; 8724 } 8725 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8726 synchronized (stats) { 8727 if (mBatteryStatsService.isOnBattery()) { 8728 mBatteryStatsService.enforceCallingPermission(); 8729 PendingIntentRecord rec = (PendingIntentRecord)sender; 8730 int MY_UID = Binder.getCallingUid(); 8731 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8732 BatteryStatsImpl.Uid.Pkg pkg = 8733 stats.getPackageStatsLocked(uid, rec.key.packageName); 8734 pkg.incWakeupsLocked(); 8735 } 8736 } 8737 } 8738 8739 public boolean killPids(int[] pids, String pReason, boolean secure) { 8740 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8741 throw new SecurityException("killPids only available to the system"); 8742 } 8743 String reason = (pReason == null) ? "Unknown" : pReason; 8744 // XXX Note: don't acquire main activity lock here, because the window 8745 // manager calls in with its locks held. 8746 8747 boolean killed = false; 8748 synchronized (mPidsSelfLocked) { 8749 int[] types = new int[pids.length]; 8750 int worstType = 0; 8751 for (int i=0; i<pids.length; i++) { 8752 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8753 if (proc != null) { 8754 int type = proc.setAdj; 8755 types[i] = type; 8756 if (type > worstType) { 8757 worstType = type; 8758 } 8759 } 8760 } 8761 8762 // If the worst oom_adj is somewhere in the cached proc LRU range, 8763 // then constrain it so we will kill all cached procs. 8764 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8765 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8766 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8767 } 8768 8769 // If this is not a secure call, don't let it kill processes that 8770 // are important. 8771 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8772 worstType = ProcessList.SERVICE_ADJ; 8773 } 8774 8775 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8776 for (int i=0; i<pids.length; i++) { 8777 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8778 if (proc == null) { 8779 continue; 8780 } 8781 int adj = proc.setAdj; 8782 if (adj >= worstType && !proc.killedByAm) { 8783 killUnneededProcessLocked(proc, reason); 8784 killed = true; 8785 } 8786 } 8787 } 8788 return killed; 8789 } 8790 8791 @Override 8792 public void killUid(int uid, String reason) { 8793 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8794 throw new SecurityException("killUid only available to the system"); 8795 } 8796 synchronized (this) { 8797 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 8798 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 8799 reason != null ? reason : "kill uid"); 8800 } 8801 } 8802 8803 @Override 8804 public boolean killProcessesBelowForeground(String reason) { 8805 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8806 throw new SecurityException("killProcessesBelowForeground() only available to system"); 8807 } 8808 8809 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 8810 } 8811 8812 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 8813 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8814 throw new SecurityException("killProcessesBelowAdj() only available to system"); 8815 } 8816 8817 boolean killed = false; 8818 synchronized (mPidsSelfLocked) { 8819 final int size = mPidsSelfLocked.size(); 8820 for (int i = 0; i < size; i++) { 8821 final int pid = mPidsSelfLocked.keyAt(i); 8822 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8823 if (proc == null) continue; 8824 8825 final int adj = proc.setAdj; 8826 if (adj > belowAdj && !proc.killedByAm) { 8827 killUnneededProcessLocked(proc, reason); 8828 killed = true; 8829 } 8830 } 8831 } 8832 return killed; 8833 } 8834 8835 @Override 8836 public void hang(final IBinder who, boolean allowRestart) { 8837 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8838 != PackageManager.PERMISSION_GRANTED) { 8839 throw new SecurityException("Requires permission " 8840 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8841 } 8842 8843 final IBinder.DeathRecipient death = new DeathRecipient() { 8844 @Override 8845 public void binderDied() { 8846 synchronized (this) { 8847 notifyAll(); 8848 } 8849 } 8850 }; 8851 8852 try { 8853 who.linkToDeath(death, 0); 8854 } catch (RemoteException e) { 8855 Slog.w(TAG, "hang: given caller IBinder is already dead."); 8856 return; 8857 } 8858 8859 synchronized (this) { 8860 Watchdog.getInstance().setAllowRestart(allowRestart); 8861 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 8862 synchronized (death) { 8863 while (who.isBinderAlive()) { 8864 try { 8865 death.wait(); 8866 } catch (InterruptedException e) { 8867 } 8868 } 8869 } 8870 Watchdog.getInstance().setAllowRestart(true); 8871 } 8872 } 8873 8874 @Override 8875 public void restart() { 8876 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8877 != PackageManager.PERMISSION_GRANTED) { 8878 throw new SecurityException("Requires permission " 8879 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8880 } 8881 8882 Log.i(TAG, "Sending shutdown broadcast..."); 8883 8884 BroadcastReceiver br = new BroadcastReceiver() { 8885 @Override public void onReceive(Context context, Intent intent) { 8886 // Now the broadcast is done, finish up the low-level shutdown. 8887 Log.i(TAG, "Shutting down activity manager..."); 8888 shutdown(10000); 8889 Log.i(TAG, "Shutdown complete, restarting!"); 8890 Process.killProcess(Process.myPid()); 8891 System.exit(10); 8892 } 8893 }; 8894 8895 // First send the high-level shut down broadcast. 8896 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 8897 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 8898 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 8899 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 8900 mContext.sendOrderedBroadcastAsUser(intent, 8901 UserHandle.ALL, null, br, mHandler, 0, null, null); 8902 */ 8903 br.onReceive(mContext, intent); 8904 } 8905 8906 private long getLowRamTimeSinceIdle(long now) { 8907 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 8908 } 8909 8910 @Override 8911 public void performIdleMaintenance() { 8912 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8913 != PackageManager.PERMISSION_GRANTED) { 8914 throw new SecurityException("Requires permission " 8915 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8916 } 8917 8918 synchronized (this) { 8919 final long now = SystemClock.uptimeMillis(); 8920 final long timeSinceLastIdle = now - mLastIdleTime; 8921 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 8922 mLastIdleTime = now; 8923 mLowRamTimeSinceLastIdle = 0; 8924 if (mLowRamStartTime != 0) { 8925 mLowRamStartTime = now; 8926 } 8927 8928 StringBuilder sb = new StringBuilder(128); 8929 sb.append("Idle maintenance over "); 8930 TimeUtils.formatDuration(timeSinceLastIdle, sb); 8931 sb.append(" low RAM for "); 8932 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 8933 Slog.i(TAG, sb.toString()); 8934 8935 // If at least 1/3 of our time since the last idle period has been spent 8936 // with RAM low, then we want to kill processes. 8937 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 8938 8939 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 8940 ProcessRecord proc = mLruProcesses.get(i); 8941 if (proc.notCachedSinceIdle) { 8942 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 8943 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 8944 if (doKilling && proc.initialIdlePss != 0 8945 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 8946 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 8947 + " from " + proc.initialIdlePss + ")"); 8948 } 8949 } 8950 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 8951 proc.notCachedSinceIdle = true; 8952 proc.initialIdlePss = 0; 8953 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 8954 mSleeping, now); 8955 } 8956 } 8957 8958 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 8959 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 8960 } 8961 } 8962 8963 private void retrieveSettings() { 8964 final ContentResolver resolver = mContext.getContentResolver(); 8965 String debugApp = Settings.Global.getString( 8966 resolver, Settings.Global.DEBUG_APP); 8967 boolean waitForDebugger = Settings.Global.getInt( 8968 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 8969 boolean alwaysFinishActivities = Settings.Global.getInt( 8970 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 8971 boolean forceRtl = Settings.Global.getInt( 8972 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 8973 // Transfer any global setting for forcing RTL layout, into a System Property 8974 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 8975 8976 Configuration configuration = new Configuration(); 8977 Settings.System.getConfiguration(resolver, configuration); 8978 if (forceRtl) { 8979 // This will take care of setting the correct layout direction flags 8980 configuration.setLayoutDirection(configuration.locale); 8981 } 8982 8983 synchronized (this) { 8984 mDebugApp = mOrigDebugApp = debugApp; 8985 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 8986 mAlwaysFinishActivities = alwaysFinishActivities; 8987 // This happens before any activities are started, so we can 8988 // change mConfiguration in-place. 8989 updateConfigurationLocked(configuration, null, false, true); 8990 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 8991 } 8992 } 8993 8994 public boolean testIsSystemReady() { 8995 // no need to synchronize(this) just to read & return the value 8996 return mSystemReady; 8997 } 8998 8999 private static File getCalledPreBootReceiversFile() { 9000 File dataDir = Environment.getDataDirectory(); 9001 File systemDir = new File(dataDir, "system"); 9002 File fname = new File(systemDir, "called_pre_boots.dat"); 9003 return fname; 9004 } 9005 9006 static final int LAST_DONE_VERSION = 10000; 9007 9008 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9009 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9010 File file = getCalledPreBootReceiversFile(); 9011 FileInputStream fis = null; 9012 try { 9013 fis = new FileInputStream(file); 9014 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9015 int fvers = dis.readInt(); 9016 if (fvers == LAST_DONE_VERSION) { 9017 String vers = dis.readUTF(); 9018 String codename = dis.readUTF(); 9019 String build = dis.readUTF(); 9020 if (android.os.Build.VERSION.RELEASE.equals(vers) 9021 && android.os.Build.VERSION.CODENAME.equals(codename) 9022 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9023 int num = dis.readInt(); 9024 while (num > 0) { 9025 num--; 9026 String pkg = dis.readUTF(); 9027 String cls = dis.readUTF(); 9028 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9029 } 9030 } 9031 } 9032 } catch (FileNotFoundException e) { 9033 } catch (IOException e) { 9034 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9035 } finally { 9036 if (fis != null) { 9037 try { 9038 fis.close(); 9039 } catch (IOException e) { 9040 } 9041 } 9042 } 9043 return lastDoneReceivers; 9044 } 9045 9046 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9047 File file = getCalledPreBootReceiversFile(); 9048 FileOutputStream fos = null; 9049 DataOutputStream dos = null; 9050 try { 9051 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9052 fos = new FileOutputStream(file); 9053 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9054 dos.writeInt(LAST_DONE_VERSION); 9055 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9056 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9057 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9058 dos.writeInt(list.size()); 9059 for (int i=0; i<list.size(); i++) { 9060 dos.writeUTF(list.get(i).getPackageName()); 9061 dos.writeUTF(list.get(i).getClassName()); 9062 } 9063 } catch (IOException e) { 9064 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9065 file.delete(); 9066 } finally { 9067 FileUtils.sync(fos); 9068 if (dos != null) { 9069 try { 9070 dos.close(); 9071 } catch (IOException e) { 9072 // TODO Auto-generated catch block 9073 e.printStackTrace(); 9074 } 9075 } 9076 } 9077 } 9078 9079 public void systemReady(final Runnable goingCallback) { 9080 synchronized(this) { 9081 if (mSystemReady) { 9082 if (goingCallback != null) goingCallback.run(); 9083 return; 9084 } 9085 9086 // Check to see if there are any update receivers to run. 9087 if (!mDidUpdate) { 9088 if (mWaitingUpdate) { 9089 return; 9090 } 9091 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9092 List<ResolveInfo> ris = null; 9093 try { 9094 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9095 intent, null, 0, 0); 9096 } catch (RemoteException e) { 9097 } 9098 if (ris != null) { 9099 for (int i=ris.size()-1; i>=0; i--) { 9100 if ((ris.get(i).activityInfo.applicationInfo.flags 9101 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9102 ris.remove(i); 9103 } 9104 } 9105 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9106 9107 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9108 9109 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9110 for (int i=0; i<ris.size(); i++) { 9111 ActivityInfo ai = ris.get(i).activityInfo; 9112 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9113 if (lastDoneReceivers.contains(comp)) { 9114 // We already did the pre boot receiver for this app with the current 9115 // platform version, so don't do it again... 9116 ris.remove(i); 9117 i--; 9118 // ...however, do keep it as one that has been done, so we don't 9119 // forget about it when rewriting the file of last done receivers. 9120 doneReceivers.add(comp); 9121 } 9122 } 9123 9124 final int[] users = getUsersLocked(); 9125 for (int i=0; i<ris.size(); i++) { 9126 ActivityInfo ai = ris.get(i).activityInfo; 9127 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9128 doneReceivers.add(comp); 9129 intent.setComponent(comp); 9130 for (int j=0; j<users.length; j++) { 9131 IIntentReceiver finisher = null; 9132 if (i == ris.size()-1 && j == users.length-1) { 9133 finisher = new IIntentReceiver.Stub() { 9134 public void performReceive(Intent intent, int resultCode, 9135 String data, Bundle extras, boolean ordered, 9136 boolean sticky, int sendingUser) { 9137 // The raw IIntentReceiver interface is called 9138 // with the AM lock held, so redispatch to 9139 // execute our code without the lock. 9140 mHandler.post(new Runnable() { 9141 public void run() { 9142 synchronized (ActivityManagerService.this) { 9143 mDidUpdate = true; 9144 } 9145 writeLastDonePreBootReceivers(doneReceivers); 9146 showBootMessage(mContext.getText( 9147 R.string.android_upgrading_complete), 9148 false); 9149 systemReady(goingCallback); 9150 } 9151 }); 9152 } 9153 }; 9154 } 9155 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9156 + " for user " + users[j]); 9157 broadcastIntentLocked(null, null, intent, null, finisher, 9158 0, null, null, null, AppOpsManager.OP_NONE, 9159 true, false, MY_PID, Process.SYSTEM_UID, 9160 users[j]); 9161 if (finisher != null) { 9162 mWaitingUpdate = true; 9163 } 9164 } 9165 } 9166 } 9167 if (mWaitingUpdate) { 9168 return; 9169 } 9170 mDidUpdate = true; 9171 } 9172 9173 mAppOpsService.systemReady(); 9174 mSystemReady = true; 9175 } 9176 9177 ArrayList<ProcessRecord> procsToKill = null; 9178 synchronized(mPidsSelfLocked) { 9179 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9180 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9181 if (!isAllowedWhileBooting(proc.info)){ 9182 if (procsToKill == null) { 9183 procsToKill = new ArrayList<ProcessRecord>(); 9184 } 9185 procsToKill.add(proc); 9186 } 9187 } 9188 } 9189 9190 synchronized(this) { 9191 if (procsToKill != null) { 9192 for (int i=procsToKill.size()-1; i>=0; i--) { 9193 ProcessRecord proc = procsToKill.get(i); 9194 Slog.i(TAG, "Removing system update proc: " + proc); 9195 removeProcessLocked(proc, true, false, "system update done"); 9196 } 9197 } 9198 9199 // Now that we have cleaned up any update processes, we 9200 // are ready to start launching real processes and know that 9201 // we won't trample on them any more. 9202 mProcessesReady = true; 9203 } 9204 9205 Slog.i(TAG, "System now ready"); 9206 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9207 SystemClock.uptimeMillis()); 9208 9209 synchronized(this) { 9210 // Make sure we have no pre-ready processes sitting around. 9211 9212 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9213 ResolveInfo ri = mContext.getPackageManager() 9214 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9215 STOCK_PM_FLAGS); 9216 CharSequence errorMsg = null; 9217 if (ri != null) { 9218 ActivityInfo ai = ri.activityInfo; 9219 ApplicationInfo app = ai.applicationInfo; 9220 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9221 mTopAction = Intent.ACTION_FACTORY_TEST; 9222 mTopData = null; 9223 mTopComponent = new ComponentName(app.packageName, 9224 ai.name); 9225 } else { 9226 errorMsg = mContext.getResources().getText( 9227 com.android.internal.R.string.factorytest_not_system); 9228 } 9229 } else { 9230 errorMsg = mContext.getResources().getText( 9231 com.android.internal.R.string.factorytest_no_action); 9232 } 9233 if (errorMsg != null) { 9234 mTopAction = null; 9235 mTopData = null; 9236 mTopComponent = null; 9237 Message msg = Message.obtain(); 9238 msg.what = SHOW_FACTORY_ERROR_MSG; 9239 msg.getData().putCharSequence("msg", errorMsg); 9240 mHandler.sendMessage(msg); 9241 } 9242 } 9243 } 9244 9245 retrieveSettings(); 9246 9247 synchronized (this) { 9248 readGrantedUriPermissionsLocked(); 9249 } 9250 9251 if (goingCallback != null) goingCallback.run(); 9252 9253 synchronized (this) { 9254 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9255 try { 9256 List apps = AppGlobals.getPackageManager(). 9257 getPersistentApplications(STOCK_PM_FLAGS); 9258 if (apps != null) { 9259 int N = apps.size(); 9260 int i; 9261 for (i=0; i<N; i++) { 9262 ApplicationInfo info 9263 = (ApplicationInfo)apps.get(i); 9264 if (info != null && 9265 !info.packageName.equals("android")) { 9266 addAppLocked(info, false); 9267 } 9268 } 9269 } 9270 } catch (RemoteException ex) { 9271 // pm is in same process, this will never happen. 9272 } 9273 } 9274 9275 // Start up initial activity. 9276 mBooting = true; 9277 9278 try { 9279 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9280 Message msg = Message.obtain(); 9281 msg.what = SHOW_UID_ERROR_MSG; 9282 mHandler.sendMessage(msg); 9283 } 9284 } catch (RemoteException e) { 9285 } 9286 9287 long ident = Binder.clearCallingIdentity(); 9288 try { 9289 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9290 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9291 | Intent.FLAG_RECEIVER_FOREGROUND); 9292 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9293 broadcastIntentLocked(null, null, intent, 9294 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9295 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9296 intent = new Intent(Intent.ACTION_USER_STARTING); 9297 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9298 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9299 broadcastIntentLocked(null, null, intent, 9300 null, new IIntentReceiver.Stub() { 9301 @Override 9302 public void performReceive(Intent intent, int resultCode, String data, 9303 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9304 throws RemoteException { 9305 } 9306 }, 0, null, null, 9307 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9308 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9309 } finally { 9310 Binder.restoreCallingIdentity(ident); 9311 } 9312 mStackSupervisor.resumeTopActivitiesLocked(); 9313 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9314 } 9315 } 9316 9317 private boolean makeAppCrashingLocked(ProcessRecord app, 9318 String shortMsg, String longMsg, String stackTrace) { 9319 app.crashing = true; 9320 app.crashingReport = generateProcessError(app, 9321 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9322 startAppProblemLocked(app); 9323 app.stopFreezingAllLocked(); 9324 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9325 } 9326 9327 private void makeAppNotRespondingLocked(ProcessRecord app, 9328 String activity, String shortMsg, String longMsg) { 9329 app.notResponding = true; 9330 app.notRespondingReport = generateProcessError(app, 9331 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9332 activity, shortMsg, longMsg, null); 9333 startAppProblemLocked(app); 9334 app.stopFreezingAllLocked(); 9335 } 9336 9337 /** 9338 * Generate a process error record, suitable for attachment to a ProcessRecord. 9339 * 9340 * @param app The ProcessRecord in which the error occurred. 9341 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9342 * ActivityManager.AppErrorStateInfo 9343 * @param activity The activity associated with the crash, if known. 9344 * @param shortMsg Short message describing the crash. 9345 * @param longMsg Long message describing the crash. 9346 * @param stackTrace Full crash stack trace, may be null. 9347 * 9348 * @return Returns a fully-formed AppErrorStateInfo record. 9349 */ 9350 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9351 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9352 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9353 9354 report.condition = condition; 9355 report.processName = app.processName; 9356 report.pid = app.pid; 9357 report.uid = app.info.uid; 9358 report.tag = activity; 9359 report.shortMsg = shortMsg; 9360 report.longMsg = longMsg; 9361 report.stackTrace = stackTrace; 9362 9363 return report; 9364 } 9365 9366 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9367 synchronized (this) { 9368 app.crashing = false; 9369 app.crashingReport = null; 9370 app.notResponding = false; 9371 app.notRespondingReport = null; 9372 if (app.anrDialog == fromDialog) { 9373 app.anrDialog = null; 9374 } 9375 if (app.waitDialog == fromDialog) { 9376 app.waitDialog = null; 9377 } 9378 if (app.pid > 0 && app.pid != MY_PID) { 9379 handleAppCrashLocked(app, null, null, null); 9380 killUnneededProcessLocked(app, "user request after error"); 9381 } 9382 } 9383 } 9384 9385 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9386 String stackTrace) { 9387 long now = SystemClock.uptimeMillis(); 9388 9389 Long crashTime; 9390 if (!app.isolated) { 9391 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9392 } else { 9393 crashTime = null; 9394 } 9395 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9396 // This process loses! 9397 Slog.w(TAG, "Process " + app.info.processName 9398 + " has crashed too many times: killing!"); 9399 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9400 app.userId, app.info.processName, app.uid); 9401 mStackSupervisor.handleAppCrashLocked(app); 9402 if (!app.persistent) { 9403 // We don't want to start this process again until the user 9404 // explicitly does so... but for persistent process, we really 9405 // need to keep it running. If a persistent process is actually 9406 // repeatedly crashing, then badness for everyone. 9407 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9408 app.info.processName); 9409 if (!app.isolated) { 9410 // XXX We don't have a way to mark isolated processes 9411 // as bad, since they don't have a peristent identity. 9412 mBadProcesses.put(app.info.processName, app.uid, 9413 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9414 mProcessCrashTimes.remove(app.info.processName, app.uid); 9415 } 9416 app.bad = true; 9417 app.removed = true; 9418 // Don't let services in this process be restarted and potentially 9419 // annoy the user repeatedly. Unless it is persistent, since those 9420 // processes run critical code. 9421 removeProcessLocked(app, false, false, "crash"); 9422 mStackSupervisor.resumeTopActivitiesLocked(); 9423 return false; 9424 } 9425 mStackSupervisor.resumeTopActivitiesLocked(); 9426 } else { 9427 mStackSupervisor.finishTopRunningActivityLocked(app); 9428 } 9429 9430 // Bump up the crash count of any services currently running in the proc. 9431 for (int i=app.services.size()-1; i>=0; i--) { 9432 // Any services running in the application need to be placed 9433 // back in the pending list. 9434 ServiceRecord sr = app.services.valueAt(i); 9435 sr.crashCount++; 9436 } 9437 9438 // If the crashing process is what we consider to be the "home process" and it has been 9439 // replaced by a third-party app, clear the package preferred activities from packages 9440 // with a home activity running in the process to prevent a repeatedly crashing app 9441 // from blocking the user to manually clear the list. 9442 final ArrayList<ActivityRecord> activities = app.activities; 9443 if (app == mHomeProcess && activities.size() > 0 9444 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9445 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9446 final ActivityRecord r = activities.get(activityNdx); 9447 if (r.isHomeActivity()) { 9448 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9449 try { 9450 ActivityThread.getPackageManager() 9451 .clearPackagePreferredActivities(r.packageName); 9452 } catch (RemoteException c) { 9453 // pm is in same process, this will never happen. 9454 } 9455 } 9456 } 9457 } 9458 9459 if (!app.isolated) { 9460 // XXX Can't keep track of crash times for isolated processes, 9461 // because they don't have a perisistent identity. 9462 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9463 } 9464 9465 return true; 9466 } 9467 9468 void startAppProblemLocked(ProcessRecord app) { 9469 if (app.userId == mCurrentUserId) { 9470 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9471 mContext, app.info.packageName, app.info.flags); 9472 } else { 9473 // If this app is not running under the current user, then we 9474 // can't give it a report button because that would require 9475 // launching the report UI under a different user. 9476 app.errorReportReceiver = null; 9477 } 9478 skipCurrentReceiverLocked(app); 9479 } 9480 9481 void skipCurrentReceiverLocked(ProcessRecord app) { 9482 for (BroadcastQueue queue : mBroadcastQueues) { 9483 queue.skipCurrentReceiverLocked(app); 9484 } 9485 } 9486 9487 /** 9488 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9489 * The application process will exit immediately after this call returns. 9490 * @param app object of the crashing app, null for the system server 9491 * @param crashInfo describing the exception 9492 */ 9493 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9494 ProcessRecord r = findAppProcess(app, "Crash"); 9495 final String processName = app == null ? "system_server" 9496 : (r == null ? "unknown" : r.processName); 9497 9498 handleApplicationCrashInner("crash", r, processName, crashInfo); 9499 } 9500 9501 /* Native crash reporting uses this inner version because it needs to be somewhat 9502 * decoupled from the AM-managed cleanup lifecycle 9503 */ 9504 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9505 ApplicationErrorReport.CrashInfo crashInfo) { 9506 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9507 UserHandle.getUserId(Binder.getCallingUid()), processName, 9508 r == null ? -1 : r.info.flags, 9509 crashInfo.exceptionClassName, 9510 crashInfo.exceptionMessage, 9511 crashInfo.throwFileName, 9512 crashInfo.throwLineNumber); 9513 9514 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9515 9516 crashApplication(r, crashInfo); 9517 } 9518 9519 public void handleApplicationStrictModeViolation( 9520 IBinder app, 9521 int violationMask, 9522 StrictMode.ViolationInfo info) { 9523 ProcessRecord r = findAppProcess(app, "StrictMode"); 9524 if (r == null) { 9525 return; 9526 } 9527 9528 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9529 Integer stackFingerprint = info.hashCode(); 9530 boolean logIt = true; 9531 synchronized (mAlreadyLoggedViolatedStacks) { 9532 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9533 logIt = false; 9534 // TODO: sub-sample into EventLog for these, with 9535 // the info.durationMillis? Then we'd get 9536 // the relative pain numbers, without logging all 9537 // the stack traces repeatedly. We'd want to do 9538 // likewise in the client code, which also does 9539 // dup suppression, before the Binder call. 9540 } else { 9541 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9542 mAlreadyLoggedViolatedStacks.clear(); 9543 } 9544 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9545 } 9546 } 9547 if (logIt) { 9548 logStrictModeViolationToDropBox(r, info); 9549 } 9550 } 9551 9552 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9553 AppErrorResult result = new AppErrorResult(); 9554 synchronized (this) { 9555 final long origId = Binder.clearCallingIdentity(); 9556 9557 Message msg = Message.obtain(); 9558 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9559 HashMap<String, Object> data = new HashMap<String, Object>(); 9560 data.put("result", result); 9561 data.put("app", r); 9562 data.put("violationMask", violationMask); 9563 data.put("info", info); 9564 msg.obj = data; 9565 mHandler.sendMessage(msg); 9566 9567 Binder.restoreCallingIdentity(origId); 9568 } 9569 int res = result.get(); 9570 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9571 } 9572 } 9573 9574 // Depending on the policy in effect, there could be a bunch of 9575 // these in quick succession so we try to batch these together to 9576 // minimize disk writes, number of dropbox entries, and maximize 9577 // compression, by having more fewer, larger records. 9578 private void logStrictModeViolationToDropBox( 9579 ProcessRecord process, 9580 StrictMode.ViolationInfo info) { 9581 if (info == null) { 9582 return; 9583 } 9584 final boolean isSystemApp = process == null || 9585 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9586 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9587 final String processName = process == null ? "unknown" : process.processName; 9588 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9589 final DropBoxManager dbox = (DropBoxManager) 9590 mContext.getSystemService(Context.DROPBOX_SERVICE); 9591 9592 // Exit early if the dropbox isn't configured to accept this report type. 9593 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9594 9595 boolean bufferWasEmpty; 9596 boolean needsFlush; 9597 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9598 synchronized (sb) { 9599 bufferWasEmpty = sb.length() == 0; 9600 appendDropBoxProcessHeaders(process, processName, sb); 9601 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9602 sb.append("System-App: ").append(isSystemApp).append("\n"); 9603 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9604 if (info.violationNumThisLoop != 0) { 9605 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9606 } 9607 if (info.numAnimationsRunning != 0) { 9608 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9609 } 9610 if (info.broadcastIntentAction != null) { 9611 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9612 } 9613 if (info.durationMillis != -1) { 9614 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9615 } 9616 if (info.numInstances != -1) { 9617 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9618 } 9619 if (info.tags != null) { 9620 for (String tag : info.tags) { 9621 sb.append("Span-Tag: ").append(tag).append("\n"); 9622 } 9623 } 9624 sb.append("\n"); 9625 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9626 sb.append(info.crashInfo.stackTrace); 9627 } 9628 sb.append("\n"); 9629 9630 // Only buffer up to ~64k. Various logging bits truncate 9631 // things at 128k. 9632 needsFlush = (sb.length() > 64 * 1024); 9633 } 9634 9635 // Flush immediately if the buffer's grown too large, or this 9636 // is a non-system app. Non-system apps are isolated with a 9637 // different tag & policy and not batched. 9638 // 9639 // Batching is useful during internal testing with 9640 // StrictMode settings turned up high. Without batching, 9641 // thousands of separate files could be created on boot. 9642 if (!isSystemApp || needsFlush) { 9643 new Thread("Error dump: " + dropboxTag) { 9644 @Override 9645 public void run() { 9646 String report; 9647 synchronized (sb) { 9648 report = sb.toString(); 9649 sb.delete(0, sb.length()); 9650 sb.trimToSize(); 9651 } 9652 if (report.length() != 0) { 9653 dbox.addText(dropboxTag, report); 9654 } 9655 } 9656 }.start(); 9657 return; 9658 } 9659 9660 // System app batching: 9661 if (!bufferWasEmpty) { 9662 // An existing dropbox-writing thread is outstanding, so 9663 // we don't need to start it up. The existing thread will 9664 // catch the buffer appends we just did. 9665 return; 9666 } 9667 9668 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9669 // (After this point, we shouldn't access AMS internal data structures.) 9670 new Thread("Error dump: " + dropboxTag) { 9671 @Override 9672 public void run() { 9673 // 5 second sleep to let stacks arrive and be batched together 9674 try { 9675 Thread.sleep(5000); // 5 seconds 9676 } catch (InterruptedException e) {} 9677 9678 String errorReport; 9679 synchronized (mStrictModeBuffer) { 9680 errorReport = mStrictModeBuffer.toString(); 9681 if (errorReport.length() == 0) { 9682 return; 9683 } 9684 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9685 mStrictModeBuffer.trimToSize(); 9686 } 9687 dbox.addText(dropboxTag, errorReport); 9688 } 9689 }.start(); 9690 } 9691 9692 /** 9693 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9694 * @param app object of the crashing app, null for the system server 9695 * @param tag reported by the caller 9696 * @param crashInfo describing the context of the error 9697 * @return true if the process should exit immediately (WTF is fatal) 9698 */ 9699 public boolean handleApplicationWtf(IBinder app, String tag, 9700 ApplicationErrorReport.CrashInfo crashInfo) { 9701 ProcessRecord r = findAppProcess(app, "WTF"); 9702 final String processName = app == null ? "system_server" 9703 : (r == null ? "unknown" : r.processName); 9704 9705 EventLog.writeEvent(EventLogTags.AM_WTF, 9706 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9707 processName, 9708 r == null ? -1 : r.info.flags, 9709 tag, crashInfo.exceptionMessage); 9710 9711 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9712 9713 if (r != null && r.pid != Process.myPid() && 9714 Settings.Global.getInt(mContext.getContentResolver(), 9715 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9716 crashApplication(r, crashInfo); 9717 return true; 9718 } else { 9719 return false; 9720 } 9721 } 9722 9723 /** 9724 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9725 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9726 */ 9727 private ProcessRecord findAppProcess(IBinder app, String reason) { 9728 if (app == null) { 9729 return null; 9730 } 9731 9732 synchronized (this) { 9733 final int NP = mProcessNames.getMap().size(); 9734 for (int ip=0; ip<NP; ip++) { 9735 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9736 final int NA = apps.size(); 9737 for (int ia=0; ia<NA; ia++) { 9738 ProcessRecord p = apps.valueAt(ia); 9739 if (p.thread != null && p.thread.asBinder() == app) { 9740 return p; 9741 } 9742 } 9743 } 9744 9745 Slog.w(TAG, "Can't find mystery application for " + reason 9746 + " from pid=" + Binder.getCallingPid() 9747 + " uid=" + Binder.getCallingUid() + ": " + app); 9748 return null; 9749 } 9750 } 9751 9752 /** 9753 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9754 * to append various headers to the dropbox log text. 9755 */ 9756 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9757 StringBuilder sb) { 9758 // Watchdog thread ends up invoking this function (with 9759 // a null ProcessRecord) to add the stack file to dropbox. 9760 // Do not acquire a lock on this (am) in such cases, as it 9761 // could cause a potential deadlock, if and when watchdog 9762 // is invoked due to unavailability of lock on am and it 9763 // would prevent watchdog from killing system_server. 9764 if (process == null) { 9765 sb.append("Process: ").append(processName).append("\n"); 9766 return; 9767 } 9768 // Note: ProcessRecord 'process' is guarded by the service 9769 // instance. (notably process.pkgList, which could otherwise change 9770 // concurrently during execution of this method) 9771 synchronized (this) { 9772 sb.append("Process: ").append(processName).append("\n"); 9773 int flags = process.info.flags; 9774 IPackageManager pm = AppGlobals.getPackageManager(); 9775 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 9776 for (int ip=0; ip<process.pkgList.size(); ip++) { 9777 String pkg = process.pkgList.keyAt(ip); 9778 sb.append("Package: ").append(pkg); 9779 try { 9780 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 9781 if (pi != null) { 9782 sb.append(" v").append(pi.versionCode); 9783 if (pi.versionName != null) { 9784 sb.append(" (").append(pi.versionName).append(")"); 9785 } 9786 } 9787 } catch (RemoteException e) { 9788 Slog.e(TAG, "Error getting package info: " + pkg, e); 9789 } 9790 sb.append("\n"); 9791 } 9792 } 9793 } 9794 9795 private static String processClass(ProcessRecord process) { 9796 if (process == null || process.pid == MY_PID) { 9797 return "system_server"; 9798 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9799 return "system_app"; 9800 } else { 9801 return "data_app"; 9802 } 9803 } 9804 9805 /** 9806 * Write a description of an error (crash, WTF, ANR) to the drop box. 9807 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 9808 * @param process which caused the error, null means the system server 9809 * @param activity which triggered the error, null if unknown 9810 * @param parent activity related to the error, null if unknown 9811 * @param subject line related to the error, null if absent 9812 * @param report in long form describing the error, null if absent 9813 * @param logFile to include in the report, null if none 9814 * @param crashInfo giving an application stack trace, null if absent 9815 */ 9816 public void addErrorToDropBox(String eventType, 9817 ProcessRecord process, String processName, ActivityRecord activity, 9818 ActivityRecord parent, String subject, 9819 final String report, final File logFile, 9820 final ApplicationErrorReport.CrashInfo crashInfo) { 9821 // NOTE -- this must never acquire the ActivityManagerService lock, 9822 // otherwise the watchdog may be prevented from resetting the system. 9823 9824 final String dropboxTag = processClass(process) + "_" + eventType; 9825 final DropBoxManager dbox = (DropBoxManager) 9826 mContext.getSystemService(Context.DROPBOX_SERVICE); 9827 9828 // Exit early if the dropbox isn't configured to accept this report type. 9829 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9830 9831 final StringBuilder sb = new StringBuilder(1024); 9832 appendDropBoxProcessHeaders(process, processName, sb); 9833 if (activity != null) { 9834 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 9835 } 9836 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 9837 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 9838 } 9839 if (parent != null && parent != activity) { 9840 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 9841 } 9842 if (subject != null) { 9843 sb.append("Subject: ").append(subject).append("\n"); 9844 } 9845 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9846 if (Debug.isDebuggerConnected()) { 9847 sb.append("Debugger: Connected\n"); 9848 } 9849 sb.append("\n"); 9850 9851 // Do the rest in a worker thread to avoid blocking the caller on I/O 9852 // (After this point, we shouldn't access AMS internal data structures.) 9853 Thread worker = new Thread("Error dump: " + dropboxTag) { 9854 @Override 9855 public void run() { 9856 if (report != null) { 9857 sb.append(report); 9858 } 9859 if (logFile != null) { 9860 try { 9861 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 9862 "\n\n[[TRUNCATED]]")); 9863 } catch (IOException e) { 9864 Slog.e(TAG, "Error reading " + logFile, e); 9865 } 9866 } 9867 if (crashInfo != null && crashInfo.stackTrace != null) { 9868 sb.append(crashInfo.stackTrace); 9869 } 9870 9871 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 9872 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 9873 if (lines > 0) { 9874 sb.append("\n"); 9875 9876 // Merge several logcat streams, and take the last N lines 9877 InputStreamReader input = null; 9878 try { 9879 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 9880 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 9881 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 9882 9883 try { logcat.getOutputStream().close(); } catch (IOException e) {} 9884 try { logcat.getErrorStream().close(); } catch (IOException e) {} 9885 input = new InputStreamReader(logcat.getInputStream()); 9886 9887 int num; 9888 char[] buf = new char[8192]; 9889 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 9890 } catch (IOException e) { 9891 Slog.e(TAG, "Error running logcat", e); 9892 } finally { 9893 if (input != null) try { input.close(); } catch (IOException e) {} 9894 } 9895 } 9896 9897 dbox.addText(dropboxTag, sb.toString()); 9898 } 9899 }; 9900 9901 if (process == null) { 9902 // If process is null, we are being called from some internal code 9903 // and may be about to die -- run this synchronously. 9904 worker.run(); 9905 } else { 9906 worker.start(); 9907 } 9908 } 9909 9910 /** 9911 * Bring up the "unexpected error" dialog box for a crashing app. 9912 * Deal with edge cases (intercepts from instrumented applications, 9913 * ActivityController, error intent receivers, that sort of thing). 9914 * @param r the application crashing 9915 * @param crashInfo describing the failure 9916 */ 9917 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 9918 long timeMillis = System.currentTimeMillis(); 9919 String shortMsg = crashInfo.exceptionClassName; 9920 String longMsg = crashInfo.exceptionMessage; 9921 String stackTrace = crashInfo.stackTrace; 9922 if (shortMsg != null && longMsg != null) { 9923 longMsg = shortMsg + ": " + longMsg; 9924 } else if (shortMsg != null) { 9925 longMsg = shortMsg; 9926 } 9927 9928 AppErrorResult result = new AppErrorResult(); 9929 synchronized (this) { 9930 if (mController != null) { 9931 try { 9932 String name = r != null ? r.processName : null; 9933 int pid = r != null ? r.pid : Binder.getCallingPid(); 9934 if (!mController.appCrashed(name, pid, 9935 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 9936 Slog.w(TAG, "Force-killing crashed app " + name 9937 + " at watcher's request"); 9938 Process.killProcess(pid); 9939 return; 9940 } 9941 } catch (RemoteException e) { 9942 mController = null; 9943 Watchdog.getInstance().setActivityController(null); 9944 } 9945 } 9946 9947 final long origId = Binder.clearCallingIdentity(); 9948 9949 // If this process is running instrumentation, finish it. 9950 if (r != null && r.instrumentationClass != null) { 9951 Slog.w(TAG, "Error in app " + r.processName 9952 + " running instrumentation " + r.instrumentationClass + ":"); 9953 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 9954 if (longMsg != null) Slog.w(TAG, " " + longMsg); 9955 Bundle info = new Bundle(); 9956 info.putString("shortMsg", shortMsg); 9957 info.putString("longMsg", longMsg); 9958 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 9959 Binder.restoreCallingIdentity(origId); 9960 return; 9961 } 9962 9963 // If we can't identify the process or it's already exceeded its crash quota, 9964 // quit right away without showing a crash dialog. 9965 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 9966 Binder.restoreCallingIdentity(origId); 9967 return; 9968 } 9969 9970 Message msg = Message.obtain(); 9971 msg.what = SHOW_ERROR_MSG; 9972 HashMap data = new HashMap(); 9973 data.put("result", result); 9974 data.put("app", r); 9975 msg.obj = data; 9976 mHandler.sendMessage(msg); 9977 9978 Binder.restoreCallingIdentity(origId); 9979 } 9980 9981 int res = result.get(); 9982 9983 Intent appErrorIntent = null; 9984 synchronized (this) { 9985 if (r != null && !r.isolated) { 9986 // XXX Can't keep track of crash time for isolated processes, 9987 // since they don't have a persistent identity. 9988 mProcessCrashTimes.put(r.info.processName, r.uid, 9989 SystemClock.uptimeMillis()); 9990 } 9991 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 9992 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 9993 } 9994 } 9995 9996 if (appErrorIntent != null) { 9997 try { 9998 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 9999 } catch (ActivityNotFoundException e) { 10000 Slog.w(TAG, "bug report receiver dissappeared", e); 10001 } 10002 } 10003 } 10004 10005 Intent createAppErrorIntentLocked(ProcessRecord r, 10006 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10007 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10008 if (report == null) { 10009 return null; 10010 } 10011 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10012 result.setComponent(r.errorReportReceiver); 10013 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10014 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10015 return result; 10016 } 10017 10018 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10019 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10020 if (r.errorReportReceiver == null) { 10021 return null; 10022 } 10023 10024 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10025 return null; 10026 } 10027 10028 ApplicationErrorReport report = new ApplicationErrorReport(); 10029 report.packageName = r.info.packageName; 10030 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10031 report.processName = r.processName; 10032 report.time = timeMillis; 10033 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10034 10035 if (r.crashing || r.forceCrashReport) { 10036 report.type = ApplicationErrorReport.TYPE_CRASH; 10037 report.crashInfo = crashInfo; 10038 } else if (r.notResponding) { 10039 report.type = ApplicationErrorReport.TYPE_ANR; 10040 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10041 10042 report.anrInfo.activity = r.notRespondingReport.tag; 10043 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10044 report.anrInfo.info = r.notRespondingReport.longMsg; 10045 } 10046 10047 return report; 10048 } 10049 10050 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10051 enforceNotIsolatedCaller("getProcessesInErrorState"); 10052 // assume our apps are happy - lazy create the list 10053 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10054 10055 final boolean allUsers = ActivityManager.checkUidPermission( 10056 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10057 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10058 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10059 10060 synchronized (this) { 10061 10062 // iterate across all processes 10063 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10064 ProcessRecord app = mLruProcesses.get(i); 10065 if (!allUsers && app.userId != userId) { 10066 continue; 10067 } 10068 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10069 // This one's in trouble, so we'll generate a report for it 10070 // crashes are higher priority (in case there's a crash *and* an anr) 10071 ActivityManager.ProcessErrorStateInfo report = null; 10072 if (app.crashing) { 10073 report = app.crashingReport; 10074 } else if (app.notResponding) { 10075 report = app.notRespondingReport; 10076 } 10077 10078 if (report != null) { 10079 if (errList == null) { 10080 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10081 } 10082 errList.add(report); 10083 } else { 10084 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10085 " crashing = " + app.crashing + 10086 " notResponding = " + app.notResponding); 10087 } 10088 } 10089 } 10090 } 10091 10092 return errList; 10093 } 10094 10095 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10096 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10097 if (currApp != null) { 10098 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10099 } 10100 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10101 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10102 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10103 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10104 if (currApp != null) { 10105 currApp.lru = 0; 10106 } 10107 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10108 } else if (adj >= ProcessList.SERVICE_ADJ) { 10109 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10110 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10111 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10112 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10113 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10114 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10115 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10116 } else { 10117 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10118 } 10119 } 10120 10121 private void fillInProcMemInfo(ProcessRecord app, 10122 ActivityManager.RunningAppProcessInfo outInfo) { 10123 outInfo.pid = app.pid; 10124 outInfo.uid = app.info.uid; 10125 if (mHeavyWeightProcess == app) { 10126 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10127 } 10128 if (app.persistent) { 10129 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10130 } 10131 if (app.activities.size() > 0) { 10132 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10133 } 10134 outInfo.lastTrimLevel = app.trimMemoryLevel; 10135 int adj = app.curAdj; 10136 outInfo.importance = oomAdjToImportance(adj, outInfo); 10137 outInfo.importanceReasonCode = app.adjTypeCode; 10138 } 10139 10140 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10141 enforceNotIsolatedCaller("getRunningAppProcesses"); 10142 // Lazy instantiation of list 10143 List<ActivityManager.RunningAppProcessInfo> runList = null; 10144 final boolean allUsers = ActivityManager.checkUidPermission( 10145 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10146 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10147 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10148 synchronized (this) { 10149 // Iterate across all processes 10150 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10151 ProcessRecord app = mLruProcesses.get(i); 10152 if (!allUsers && app.userId != userId) { 10153 continue; 10154 } 10155 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10156 // Generate process state info for running application 10157 ActivityManager.RunningAppProcessInfo currApp = 10158 new ActivityManager.RunningAppProcessInfo(app.processName, 10159 app.pid, app.getPackageList()); 10160 fillInProcMemInfo(app, currApp); 10161 if (app.adjSource instanceof ProcessRecord) { 10162 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10163 currApp.importanceReasonImportance = oomAdjToImportance( 10164 app.adjSourceOom, null); 10165 } else if (app.adjSource instanceof ActivityRecord) { 10166 ActivityRecord r = (ActivityRecord)app.adjSource; 10167 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10168 } 10169 if (app.adjTarget instanceof ComponentName) { 10170 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10171 } 10172 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10173 // + " lru=" + currApp.lru); 10174 if (runList == null) { 10175 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10176 } 10177 runList.add(currApp); 10178 } 10179 } 10180 } 10181 return runList; 10182 } 10183 10184 public List<ApplicationInfo> getRunningExternalApplications() { 10185 enforceNotIsolatedCaller("getRunningExternalApplications"); 10186 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10187 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10188 if (runningApps != null && runningApps.size() > 0) { 10189 Set<String> extList = new HashSet<String>(); 10190 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10191 if (app.pkgList != null) { 10192 for (String pkg : app.pkgList) { 10193 extList.add(pkg); 10194 } 10195 } 10196 } 10197 IPackageManager pm = AppGlobals.getPackageManager(); 10198 for (String pkg : extList) { 10199 try { 10200 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10201 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10202 retList.add(info); 10203 } 10204 } catch (RemoteException e) { 10205 } 10206 } 10207 } 10208 return retList; 10209 } 10210 10211 @Override 10212 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10213 enforceNotIsolatedCaller("getMyMemoryState"); 10214 synchronized (this) { 10215 ProcessRecord proc; 10216 synchronized (mPidsSelfLocked) { 10217 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10218 } 10219 fillInProcMemInfo(proc, outInfo); 10220 } 10221 } 10222 10223 @Override 10224 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10225 if (checkCallingPermission(android.Manifest.permission.DUMP) 10226 != PackageManager.PERMISSION_GRANTED) { 10227 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10228 + Binder.getCallingPid() 10229 + ", uid=" + Binder.getCallingUid() 10230 + " without permission " 10231 + android.Manifest.permission.DUMP); 10232 return; 10233 } 10234 10235 boolean dumpAll = false; 10236 boolean dumpClient = false; 10237 String dumpPackage = null; 10238 10239 int opti = 0; 10240 while (opti < args.length) { 10241 String opt = args[opti]; 10242 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10243 break; 10244 } 10245 opti++; 10246 if ("-a".equals(opt)) { 10247 dumpAll = true; 10248 } else if ("-c".equals(opt)) { 10249 dumpClient = true; 10250 } else if ("-h".equals(opt)) { 10251 pw.println("Activity manager dump options:"); 10252 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10253 pw.println(" cmd may be one of:"); 10254 pw.println(" a[ctivities]: activity stack state"); 10255 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10256 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10257 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10258 pw.println(" o[om]: out of memory management"); 10259 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10260 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10261 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10262 pw.println(" service [COMP_SPEC]: service client-side state"); 10263 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10264 pw.println(" all: dump all activities"); 10265 pw.println(" top: dump the top activity"); 10266 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10267 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10268 pw.println(" a partial substring in a component name, a"); 10269 pw.println(" hex object identifier."); 10270 pw.println(" -a: include all available server state."); 10271 pw.println(" -c: include client state."); 10272 return; 10273 } else { 10274 pw.println("Unknown argument: " + opt + "; use -h for help"); 10275 } 10276 } 10277 10278 long origId = Binder.clearCallingIdentity(); 10279 boolean more = false; 10280 // Is the caller requesting to dump a particular piece of data? 10281 if (opti < args.length) { 10282 String cmd = args[opti]; 10283 opti++; 10284 if ("activities".equals(cmd) || "a".equals(cmd)) { 10285 synchronized (this) { 10286 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10287 } 10288 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10289 String[] newArgs; 10290 String name; 10291 if (opti >= args.length) { 10292 name = null; 10293 newArgs = EMPTY_STRING_ARRAY; 10294 } else { 10295 name = args[opti]; 10296 opti++; 10297 newArgs = new String[args.length - opti]; 10298 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10299 args.length - opti); 10300 } 10301 synchronized (this) { 10302 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10303 } 10304 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10305 String[] newArgs; 10306 String name; 10307 if (opti >= args.length) { 10308 name = null; 10309 newArgs = EMPTY_STRING_ARRAY; 10310 } else { 10311 name = args[opti]; 10312 opti++; 10313 newArgs = new String[args.length - opti]; 10314 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10315 args.length - opti); 10316 } 10317 synchronized (this) { 10318 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10319 } 10320 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10321 String[] newArgs; 10322 String name; 10323 if (opti >= args.length) { 10324 name = null; 10325 newArgs = EMPTY_STRING_ARRAY; 10326 } else { 10327 name = args[opti]; 10328 opti++; 10329 newArgs = new String[args.length - opti]; 10330 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10331 args.length - opti); 10332 } 10333 synchronized (this) { 10334 dumpProcessesLocked(fd, pw, args, opti, true, name); 10335 } 10336 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10337 synchronized (this) { 10338 dumpOomLocked(fd, pw, args, opti, true); 10339 } 10340 } else if ("provider".equals(cmd)) { 10341 String[] newArgs; 10342 String name; 10343 if (opti >= args.length) { 10344 name = null; 10345 newArgs = EMPTY_STRING_ARRAY; 10346 } else { 10347 name = args[opti]; 10348 opti++; 10349 newArgs = new String[args.length - opti]; 10350 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10351 } 10352 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10353 pw.println("No providers match: " + name); 10354 pw.println("Use -h for help."); 10355 } 10356 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10357 synchronized (this) { 10358 dumpProvidersLocked(fd, pw, args, opti, true, null); 10359 } 10360 } else if ("service".equals(cmd)) { 10361 String[] newArgs; 10362 String name; 10363 if (opti >= args.length) { 10364 name = null; 10365 newArgs = EMPTY_STRING_ARRAY; 10366 } else { 10367 name = args[opti]; 10368 opti++; 10369 newArgs = new String[args.length - opti]; 10370 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10371 args.length - opti); 10372 } 10373 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10374 pw.println("No services match: " + name); 10375 pw.println("Use -h for help."); 10376 } 10377 } else if ("package".equals(cmd)) { 10378 String[] newArgs; 10379 if (opti >= args.length) { 10380 pw.println("package: no package name specified"); 10381 pw.println("Use -h for help."); 10382 } else { 10383 dumpPackage = args[opti]; 10384 opti++; 10385 newArgs = new String[args.length - opti]; 10386 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10387 args.length - opti); 10388 args = newArgs; 10389 opti = 0; 10390 more = true; 10391 } 10392 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10393 synchronized (this) { 10394 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10395 } 10396 } else { 10397 // Dumping a single activity? 10398 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10399 pw.println("Bad activity command, or no activities match: " + cmd); 10400 pw.println("Use -h for help."); 10401 } 10402 } 10403 if (!more) { 10404 Binder.restoreCallingIdentity(origId); 10405 return; 10406 } 10407 } 10408 10409 // No piece of data specified, dump everything. 10410 synchronized (this) { 10411 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10412 pw.println(); 10413 if (dumpAll) { 10414 pw.println("-------------------------------------------------------------------------------"); 10415 } 10416 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10417 pw.println(); 10418 if (dumpAll) { 10419 pw.println("-------------------------------------------------------------------------------"); 10420 } 10421 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10422 pw.println(); 10423 if (dumpAll) { 10424 pw.println("-------------------------------------------------------------------------------"); 10425 } 10426 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10427 pw.println(); 10428 if (dumpAll) { 10429 pw.println("-------------------------------------------------------------------------------"); 10430 } 10431 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10432 pw.println(); 10433 if (dumpAll) { 10434 pw.println("-------------------------------------------------------------------------------"); 10435 } 10436 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10437 } 10438 Binder.restoreCallingIdentity(origId); 10439 } 10440 10441 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10442 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10443 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10444 10445 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10446 dumpPackage); 10447 boolean needSep = printedAnything; 10448 10449 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10450 dumpPackage, needSep, " mFocusedActivity: "); 10451 if (printed) { 10452 printedAnything = true; 10453 needSep = false; 10454 } 10455 10456 if (dumpPackage == null) { 10457 if (needSep) { 10458 pw.println(); 10459 } 10460 needSep = true; 10461 printedAnything = true; 10462 mStackSupervisor.dump(pw, " "); 10463 } 10464 10465 if (mRecentTasks.size() > 0) { 10466 boolean printedHeader = false; 10467 10468 final int N = mRecentTasks.size(); 10469 for (int i=0; i<N; i++) { 10470 TaskRecord tr = mRecentTasks.get(i); 10471 if (dumpPackage != null) { 10472 if (tr.realActivity == null || 10473 !dumpPackage.equals(tr.realActivity)) { 10474 continue; 10475 } 10476 } 10477 if (!printedHeader) { 10478 if (needSep) { 10479 pw.println(); 10480 } 10481 pw.println(" Recent tasks:"); 10482 printedHeader = true; 10483 printedAnything = true; 10484 } 10485 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10486 pw.println(tr); 10487 if (dumpAll) { 10488 mRecentTasks.get(i).dump(pw, " "); 10489 } 10490 } 10491 } 10492 10493 if (!printedAnything) { 10494 pw.println(" (nothing)"); 10495 } 10496 } 10497 10498 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10499 int opti, boolean dumpAll, String dumpPackage) { 10500 boolean needSep = false; 10501 boolean printedAnything = false; 10502 int numPers = 0; 10503 10504 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10505 10506 if (dumpAll) { 10507 final int NP = mProcessNames.getMap().size(); 10508 for (int ip=0; ip<NP; ip++) { 10509 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10510 final int NA = procs.size(); 10511 for (int ia=0; ia<NA; ia++) { 10512 ProcessRecord r = procs.valueAt(ia); 10513 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10514 continue; 10515 } 10516 if (!needSep) { 10517 pw.println(" All known processes:"); 10518 needSep = true; 10519 printedAnything = true; 10520 } 10521 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10522 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10523 pw.print(" "); pw.println(r); 10524 r.dump(pw, " "); 10525 if (r.persistent) { 10526 numPers++; 10527 } 10528 } 10529 } 10530 } 10531 10532 if (mIsolatedProcesses.size() > 0) { 10533 boolean printed = false; 10534 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10535 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10536 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10537 continue; 10538 } 10539 if (!printed) { 10540 if (needSep) { 10541 pw.println(); 10542 } 10543 pw.println(" Isolated process list (sorted by uid):"); 10544 printedAnything = true; 10545 printed = true; 10546 needSep = true; 10547 } 10548 pw.println(String.format("%sIsolated #%2d: %s", 10549 " ", i, r.toString())); 10550 } 10551 } 10552 10553 if (mLruProcesses.size() > 0) { 10554 if (needSep) { 10555 pw.println(); 10556 } 10557 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10558 pw.print(" total, non-act at "); 10559 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10560 pw.print(", non-svc at "); 10561 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10562 pw.println("):"); 10563 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10564 needSep = true; 10565 printedAnything = true; 10566 } 10567 10568 if (dumpAll || dumpPackage != null) { 10569 synchronized (mPidsSelfLocked) { 10570 boolean printed = false; 10571 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10572 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10573 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10574 continue; 10575 } 10576 if (!printed) { 10577 if (needSep) pw.println(); 10578 needSep = true; 10579 pw.println(" PID mappings:"); 10580 printed = true; 10581 printedAnything = true; 10582 } 10583 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10584 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10585 } 10586 } 10587 } 10588 10589 if (mForegroundProcesses.size() > 0) { 10590 synchronized (mPidsSelfLocked) { 10591 boolean printed = false; 10592 for (int i=0; i<mForegroundProcesses.size(); i++) { 10593 ProcessRecord r = mPidsSelfLocked.get( 10594 mForegroundProcesses.valueAt(i).pid); 10595 if (dumpPackage != null && (r == null 10596 || !r.pkgList.containsKey(dumpPackage))) { 10597 continue; 10598 } 10599 if (!printed) { 10600 if (needSep) pw.println(); 10601 needSep = true; 10602 pw.println(" Foreground Processes:"); 10603 printed = true; 10604 printedAnything = true; 10605 } 10606 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10607 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10608 } 10609 } 10610 } 10611 10612 if (mPersistentStartingProcesses.size() > 0) { 10613 if (needSep) pw.println(); 10614 needSep = true; 10615 printedAnything = true; 10616 pw.println(" Persisent processes that are starting:"); 10617 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10618 "Starting Norm", "Restarting PERS", dumpPackage); 10619 } 10620 10621 if (mRemovedProcesses.size() > 0) { 10622 if (needSep) pw.println(); 10623 needSep = true; 10624 printedAnything = true; 10625 pw.println(" Processes that are being removed:"); 10626 dumpProcessList(pw, this, mRemovedProcesses, " ", 10627 "Removed Norm", "Removed PERS", dumpPackage); 10628 } 10629 10630 if (mProcessesOnHold.size() > 0) { 10631 if (needSep) pw.println(); 10632 needSep = true; 10633 printedAnything = true; 10634 pw.println(" Processes that are on old until the system is ready:"); 10635 dumpProcessList(pw, this, mProcessesOnHold, " ", 10636 "OnHold Norm", "OnHold PERS", dumpPackage); 10637 } 10638 10639 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10640 10641 if (mProcessCrashTimes.getMap().size() > 0) { 10642 boolean printed = false; 10643 long now = SystemClock.uptimeMillis(); 10644 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10645 final int NP = pmap.size(); 10646 for (int ip=0; ip<NP; ip++) { 10647 String pname = pmap.keyAt(ip); 10648 SparseArray<Long> uids = pmap.valueAt(ip); 10649 final int N = uids.size(); 10650 for (int i=0; i<N; i++) { 10651 int puid = uids.keyAt(i); 10652 ProcessRecord r = mProcessNames.get(pname, puid); 10653 if (dumpPackage != null && (r == null 10654 || !r.pkgList.containsKey(dumpPackage))) { 10655 continue; 10656 } 10657 if (!printed) { 10658 if (needSep) pw.println(); 10659 needSep = true; 10660 pw.println(" Time since processes crashed:"); 10661 printed = true; 10662 printedAnything = true; 10663 } 10664 pw.print(" Process "); pw.print(pname); 10665 pw.print(" uid "); pw.print(puid); 10666 pw.print(": last crashed "); 10667 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10668 pw.println(" ago"); 10669 } 10670 } 10671 } 10672 10673 if (mBadProcesses.getMap().size() > 0) { 10674 boolean printed = false; 10675 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10676 final int NP = pmap.size(); 10677 for (int ip=0; ip<NP; ip++) { 10678 String pname = pmap.keyAt(ip); 10679 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10680 final int N = uids.size(); 10681 for (int i=0; i<N; i++) { 10682 int puid = uids.keyAt(i); 10683 ProcessRecord r = mProcessNames.get(pname, puid); 10684 if (dumpPackage != null && (r == null 10685 || !r.pkgList.containsKey(dumpPackage))) { 10686 continue; 10687 } 10688 if (!printed) { 10689 if (needSep) pw.println(); 10690 needSep = true; 10691 pw.println(" Bad processes:"); 10692 printedAnything = true; 10693 } 10694 BadProcessInfo info = uids.valueAt(i); 10695 pw.print(" Bad process "); pw.print(pname); 10696 pw.print(" uid "); pw.print(puid); 10697 pw.print(": crashed at time "); pw.println(info.time); 10698 if (info.shortMsg != null) { 10699 pw.print(" Short msg: "); pw.println(info.shortMsg); 10700 } 10701 if (info.longMsg != null) { 10702 pw.print(" Long msg: "); pw.println(info.longMsg); 10703 } 10704 if (info.stack != null) { 10705 pw.println(" Stack:"); 10706 int lastPos = 0; 10707 for (int pos=0; pos<info.stack.length(); pos++) { 10708 if (info.stack.charAt(pos) == '\n') { 10709 pw.print(" "); 10710 pw.write(info.stack, lastPos, pos-lastPos); 10711 pw.println(); 10712 lastPos = pos+1; 10713 } 10714 } 10715 if (lastPos < info.stack.length()) { 10716 pw.print(" "); 10717 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10718 pw.println(); 10719 } 10720 } 10721 } 10722 } 10723 } 10724 10725 if (dumpPackage == null) { 10726 pw.println(); 10727 needSep = false; 10728 pw.println(" mStartedUsers:"); 10729 for (int i=0; i<mStartedUsers.size(); i++) { 10730 UserStartedState uss = mStartedUsers.valueAt(i); 10731 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10732 pw.print(": "); uss.dump("", pw); 10733 } 10734 pw.print(" mStartedUserArray: ["); 10735 for (int i=0; i<mStartedUserArray.length; i++) { 10736 if (i > 0) pw.print(", "); 10737 pw.print(mStartedUserArray[i]); 10738 } 10739 pw.println("]"); 10740 pw.print(" mUserLru: ["); 10741 for (int i=0; i<mUserLru.size(); i++) { 10742 if (i > 0) pw.print(", "); 10743 pw.print(mUserLru.get(i)); 10744 } 10745 pw.println("]"); 10746 if (dumpAll) { 10747 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10748 } 10749 } 10750 if (mHomeProcess != null && (dumpPackage == null 10751 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10752 if (needSep) { 10753 pw.println(); 10754 needSep = false; 10755 } 10756 pw.println(" mHomeProcess: " + mHomeProcess); 10757 } 10758 if (mPreviousProcess != null && (dumpPackage == null 10759 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 10760 if (needSep) { 10761 pw.println(); 10762 needSep = false; 10763 } 10764 pw.println(" mPreviousProcess: " + mPreviousProcess); 10765 } 10766 if (dumpAll) { 10767 StringBuilder sb = new StringBuilder(128); 10768 sb.append(" mPreviousProcessVisibleTime: "); 10769 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 10770 pw.println(sb); 10771 } 10772 if (mHeavyWeightProcess != null && (dumpPackage == null 10773 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 10774 if (needSep) { 10775 pw.println(); 10776 needSep = false; 10777 } 10778 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10779 } 10780 if (dumpPackage == null) { 10781 pw.println(" mConfiguration: " + mConfiguration); 10782 } 10783 if (dumpAll) { 10784 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 10785 if (mCompatModePackages.getPackages().size() > 0) { 10786 boolean printed = false; 10787 for (Map.Entry<String, Integer> entry 10788 : mCompatModePackages.getPackages().entrySet()) { 10789 String pkg = entry.getKey(); 10790 int mode = entry.getValue(); 10791 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 10792 continue; 10793 } 10794 if (!printed) { 10795 pw.println(" mScreenCompatPackages:"); 10796 printed = true; 10797 } 10798 pw.print(" "); pw.print(pkg); pw.print(": "); 10799 pw.print(mode); pw.println(); 10800 } 10801 } 10802 } 10803 if (dumpPackage == null) { 10804 if (mSleeping || mWentToSleep || mLockScreenShown) { 10805 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 10806 + " mLockScreenShown " + mLockScreenShown); 10807 } 10808 if (mShuttingDown) { 10809 pw.println(" mShuttingDown=" + mShuttingDown); 10810 } 10811 } 10812 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 10813 || mOrigWaitForDebugger) { 10814 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 10815 || dumpPackage.equals(mOrigDebugApp)) { 10816 if (needSep) { 10817 pw.println(); 10818 needSep = false; 10819 } 10820 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 10821 + " mDebugTransient=" + mDebugTransient 10822 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 10823 } 10824 } 10825 if (mOpenGlTraceApp != null) { 10826 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 10827 if (needSep) { 10828 pw.println(); 10829 needSep = false; 10830 } 10831 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 10832 } 10833 } 10834 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 10835 || mProfileFd != null) { 10836 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 10837 if (needSep) { 10838 pw.println(); 10839 needSep = false; 10840 } 10841 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 10842 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 10843 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 10844 + mAutoStopProfiler); 10845 } 10846 } 10847 if (dumpPackage == null) { 10848 if (mAlwaysFinishActivities || mController != null) { 10849 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 10850 + " mController=" + mController); 10851 } 10852 if (dumpAll) { 10853 pw.println(" Total persistent processes: " + numPers); 10854 pw.println(" mProcessesReady=" + mProcessesReady 10855 + " mSystemReady=" + mSystemReady); 10856 pw.println(" mBooting=" + mBooting 10857 + " mBooted=" + mBooted 10858 + " mFactoryTest=" + mFactoryTest); 10859 pw.print(" mLastPowerCheckRealtime="); 10860 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 10861 pw.println(""); 10862 pw.print(" mLastPowerCheckUptime="); 10863 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 10864 pw.println(""); 10865 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 10866 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 10867 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 10868 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 10869 + " (" + mLruProcesses.size() + " total)" 10870 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 10871 + " mNumServiceProcs=" + mNumServiceProcs 10872 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 10873 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 10874 + " mLastMemoryLevel" + mLastMemoryLevel 10875 + " mLastNumProcesses" + mLastNumProcesses); 10876 long now = SystemClock.uptimeMillis(); 10877 pw.print(" mLastIdleTime="); 10878 TimeUtils.formatDuration(now, mLastIdleTime, pw); 10879 pw.print(" mLowRamSinceLastIdle="); 10880 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 10881 pw.println(); 10882 } 10883 } 10884 10885 if (!printedAnything) { 10886 pw.println(" (nothing)"); 10887 } 10888 } 10889 10890 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 10891 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 10892 if (mProcessesToGc.size() > 0) { 10893 boolean printed = false; 10894 long now = SystemClock.uptimeMillis(); 10895 for (int i=0; i<mProcessesToGc.size(); i++) { 10896 ProcessRecord proc = mProcessesToGc.get(i); 10897 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 10898 continue; 10899 } 10900 if (!printed) { 10901 if (needSep) pw.println(); 10902 needSep = true; 10903 pw.println(" Processes that are waiting to GC:"); 10904 printed = true; 10905 } 10906 pw.print(" Process "); pw.println(proc); 10907 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 10908 pw.print(", last gced="); 10909 pw.print(now-proc.lastRequestedGc); 10910 pw.print(" ms ago, last lowMem="); 10911 pw.print(now-proc.lastLowMemory); 10912 pw.println(" ms ago"); 10913 10914 } 10915 } 10916 return needSep; 10917 } 10918 10919 void printOomLevel(PrintWriter pw, String name, int adj) { 10920 pw.print(" "); 10921 if (adj >= 0) { 10922 pw.print(' '); 10923 if (adj < 10) pw.print(' '); 10924 } else { 10925 if (adj > -10) pw.print(' '); 10926 } 10927 pw.print(adj); 10928 pw.print(": "); 10929 pw.print(name); 10930 pw.print(" ("); 10931 pw.print(mProcessList.getMemLevel(adj)/1024); 10932 pw.println(" kB)"); 10933 } 10934 10935 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10936 int opti, boolean dumpAll) { 10937 boolean needSep = false; 10938 10939 if (mLruProcesses.size() > 0) { 10940 if (needSep) pw.println(); 10941 needSep = true; 10942 pw.println(" OOM levels:"); 10943 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 10944 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 10945 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 10946 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 10947 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 10948 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 10949 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 10950 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 10951 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 10952 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 10953 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 10954 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 10955 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 10956 10957 if (needSep) pw.println(); 10958 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 10959 pw.print(" total, non-act at "); 10960 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10961 pw.print(", non-svc at "); 10962 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10963 pw.println("):"); 10964 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 10965 needSep = true; 10966 } 10967 10968 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 10969 10970 pw.println(); 10971 pw.println(" mHomeProcess: " + mHomeProcess); 10972 pw.println(" mPreviousProcess: " + mPreviousProcess); 10973 if (mHeavyWeightProcess != null) { 10974 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10975 } 10976 10977 return true; 10978 } 10979 10980 /** 10981 * There are three ways to call this: 10982 * - no provider specified: dump all the providers 10983 * - a flattened component name that matched an existing provider was specified as the 10984 * first arg: dump that one provider 10985 * - the first arg isn't the flattened component name of an existing provider: 10986 * dump all providers whose component contains the first arg as a substring 10987 */ 10988 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 10989 int opti, boolean dumpAll) { 10990 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 10991 } 10992 10993 static class ItemMatcher { 10994 ArrayList<ComponentName> components; 10995 ArrayList<String> strings; 10996 ArrayList<Integer> objects; 10997 boolean all; 10998 10999 ItemMatcher() { 11000 all = true; 11001 } 11002 11003 void build(String name) { 11004 ComponentName componentName = ComponentName.unflattenFromString(name); 11005 if (componentName != null) { 11006 if (components == null) { 11007 components = new ArrayList<ComponentName>(); 11008 } 11009 components.add(componentName); 11010 all = false; 11011 } else { 11012 int objectId = 0; 11013 // Not a '/' separated full component name; maybe an object ID? 11014 try { 11015 objectId = Integer.parseInt(name, 16); 11016 if (objects == null) { 11017 objects = new ArrayList<Integer>(); 11018 } 11019 objects.add(objectId); 11020 all = false; 11021 } catch (RuntimeException e) { 11022 // Not an integer; just do string match. 11023 if (strings == null) { 11024 strings = new ArrayList<String>(); 11025 } 11026 strings.add(name); 11027 all = false; 11028 } 11029 } 11030 } 11031 11032 int build(String[] args, int opti) { 11033 for (; opti<args.length; opti++) { 11034 String name = args[opti]; 11035 if ("--".equals(name)) { 11036 return opti+1; 11037 } 11038 build(name); 11039 } 11040 return opti; 11041 } 11042 11043 boolean match(Object object, ComponentName comp) { 11044 if (all) { 11045 return true; 11046 } 11047 if (components != null) { 11048 for (int i=0; i<components.size(); i++) { 11049 if (components.get(i).equals(comp)) { 11050 return true; 11051 } 11052 } 11053 } 11054 if (objects != null) { 11055 for (int i=0; i<objects.size(); i++) { 11056 if (System.identityHashCode(object) == objects.get(i)) { 11057 return true; 11058 } 11059 } 11060 } 11061 if (strings != null) { 11062 String flat = comp.flattenToString(); 11063 for (int i=0; i<strings.size(); i++) { 11064 if (flat.contains(strings.get(i))) { 11065 return true; 11066 } 11067 } 11068 } 11069 return false; 11070 } 11071 } 11072 11073 /** 11074 * There are three things that cmd can be: 11075 * - a flattened component name that matches an existing activity 11076 * - the cmd arg isn't the flattened component name of an existing activity: 11077 * dump all activity whose component contains the cmd as a substring 11078 * - A hex number of the ActivityRecord object instance. 11079 */ 11080 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11081 int opti, boolean dumpAll) { 11082 ArrayList<ActivityRecord> activities; 11083 11084 synchronized (this) { 11085 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11086 } 11087 11088 if (activities.size() <= 0) { 11089 return false; 11090 } 11091 11092 String[] newArgs = new String[args.length - opti]; 11093 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11094 11095 TaskRecord lastTask = null; 11096 boolean needSep = false; 11097 for (int i=activities.size()-1; i>=0; i--) { 11098 ActivityRecord r = activities.get(i); 11099 if (needSep) { 11100 pw.println(); 11101 } 11102 needSep = true; 11103 synchronized (this) { 11104 if (lastTask != r.task) { 11105 lastTask = r.task; 11106 pw.print("TASK "); pw.print(lastTask.affinity); 11107 pw.print(" id="); pw.println(lastTask.taskId); 11108 if (dumpAll) { 11109 lastTask.dump(pw, " "); 11110 } 11111 } 11112 } 11113 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11114 } 11115 return true; 11116 } 11117 11118 /** 11119 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11120 * there is a thread associated with the activity. 11121 */ 11122 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11123 final ActivityRecord r, String[] args, boolean dumpAll) { 11124 String innerPrefix = prefix + " "; 11125 synchronized (this) { 11126 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11127 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11128 pw.print(" pid="); 11129 if (r.app != null) pw.println(r.app.pid); 11130 else pw.println("(not running)"); 11131 if (dumpAll) { 11132 r.dump(pw, innerPrefix); 11133 } 11134 } 11135 if (r.app != null && r.app.thread != null) { 11136 // flush anything that is already in the PrintWriter since the thread is going 11137 // to write to the file descriptor directly 11138 pw.flush(); 11139 try { 11140 TransferPipe tp = new TransferPipe(); 11141 try { 11142 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11143 r.appToken, innerPrefix, args); 11144 tp.go(fd); 11145 } finally { 11146 tp.kill(); 11147 } 11148 } catch (IOException e) { 11149 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11150 } catch (RemoteException e) { 11151 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11152 } 11153 } 11154 } 11155 11156 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11157 int opti, boolean dumpAll, String dumpPackage) { 11158 boolean needSep = false; 11159 boolean onlyHistory = false; 11160 boolean printedAnything = false; 11161 11162 if ("history".equals(dumpPackage)) { 11163 if (opti < args.length && "-s".equals(args[opti])) { 11164 dumpAll = false; 11165 } 11166 onlyHistory = true; 11167 dumpPackage = null; 11168 } 11169 11170 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11171 if (!onlyHistory && dumpAll) { 11172 if (mRegisteredReceivers.size() > 0) { 11173 boolean printed = false; 11174 Iterator it = mRegisteredReceivers.values().iterator(); 11175 while (it.hasNext()) { 11176 ReceiverList r = (ReceiverList)it.next(); 11177 if (dumpPackage != null && (r.app == null || 11178 !dumpPackage.equals(r.app.info.packageName))) { 11179 continue; 11180 } 11181 if (!printed) { 11182 pw.println(" Registered Receivers:"); 11183 needSep = true; 11184 printed = true; 11185 printedAnything = true; 11186 } 11187 pw.print(" * "); pw.println(r); 11188 r.dump(pw, " "); 11189 } 11190 } 11191 11192 if (mReceiverResolver.dump(pw, needSep ? 11193 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11194 " ", dumpPackage, false)) { 11195 needSep = true; 11196 printedAnything = true; 11197 } 11198 } 11199 11200 for (BroadcastQueue q : mBroadcastQueues) { 11201 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11202 printedAnything |= needSep; 11203 } 11204 11205 needSep = true; 11206 11207 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11208 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11209 if (needSep) { 11210 pw.println(); 11211 } 11212 needSep = true; 11213 printedAnything = true; 11214 pw.print(" Sticky broadcasts for user "); 11215 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11216 StringBuilder sb = new StringBuilder(128); 11217 for (Map.Entry<String, ArrayList<Intent>> ent 11218 : mStickyBroadcasts.valueAt(user).entrySet()) { 11219 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11220 if (dumpAll) { 11221 pw.println(":"); 11222 ArrayList<Intent> intents = ent.getValue(); 11223 final int N = intents.size(); 11224 for (int i=0; i<N; i++) { 11225 sb.setLength(0); 11226 sb.append(" Intent: "); 11227 intents.get(i).toShortString(sb, false, true, false, false); 11228 pw.println(sb.toString()); 11229 Bundle bundle = intents.get(i).getExtras(); 11230 if (bundle != null) { 11231 pw.print(" "); 11232 pw.println(bundle.toString()); 11233 } 11234 } 11235 } else { 11236 pw.println(""); 11237 } 11238 } 11239 } 11240 } 11241 11242 if (!onlyHistory && dumpAll) { 11243 pw.println(); 11244 for (BroadcastQueue queue : mBroadcastQueues) { 11245 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11246 + queue.mBroadcastsScheduled); 11247 } 11248 pw.println(" mHandler:"); 11249 mHandler.dump(new PrintWriterPrinter(pw), " "); 11250 needSep = true; 11251 printedAnything = true; 11252 } 11253 11254 if (!printedAnything) { 11255 pw.println(" (nothing)"); 11256 } 11257 } 11258 11259 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11260 int opti, boolean dumpAll, String dumpPackage) { 11261 boolean needSep; 11262 boolean printedAnything = false; 11263 11264 ItemMatcher matcher = new ItemMatcher(); 11265 matcher.build(args, opti); 11266 11267 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11268 11269 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11270 printedAnything |= needSep; 11271 11272 if (mLaunchingProviders.size() > 0) { 11273 boolean printed = false; 11274 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11275 ContentProviderRecord r = mLaunchingProviders.get(i); 11276 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11277 continue; 11278 } 11279 if (!printed) { 11280 if (needSep) pw.println(); 11281 needSep = true; 11282 pw.println(" Launching content providers:"); 11283 printed = true; 11284 printedAnything = true; 11285 } 11286 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11287 pw.println(r); 11288 } 11289 } 11290 11291 if (mGrantedUriPermissions.size() > 0) { 11292 boolean printed = false; 11293 int dumpUid = -2; 11294 if (dumpPackage != null) { 11295 try { 11296 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11297 } catch (NameNotFoundException e) { 11298 dumpUid = -1; 11299 } 11300 } 11301 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11302 int uid = mGrantedUriPermissions.keyAt(i); 11303 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11304 continue; 11305 } 11306 ArrayMap<Uri, UriPermission> perms 11307 = mGrantedUriPermissions.valueAt(i); 11308 if (!printed) { 11309 if (needSep) pw.println(); 11310 needSep = true; 11311 pw.println(" Granted Uri Permissions:"); 11312 printed = true; 11313 printedAnything = true; 11314 } 11315 pw.print(" * UID "); pw.print(uid); 11316 pw.println(" holds:"); 11317 for (UriPermission perm : perms.values()) { 11318 pw.print(" "); pw.println(perm); 11319 if (dumpAll) { 11320 perm.dump(pw, " "); 11321 } 11322 } 11323 } 11324 } 11325 11326 if (!printedAnything) { 11327 pw.println(" (nothing)"); 11328 } 11329 } 11330 11331 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11332 int opti, boolean dumpAll, String dumpPackage) { 11333 boolean printed = false; 11334 11335 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11336 11337 if (mIntentSenderRecords.size() > 0) { 11338 Iterator<WeakReference<PendingIntentRecord>> it 11339 = mIntentSenderRecords.values().iterator(); 11340 while (it.hasNext()) { 11341 WeakReference<PendingIntentRecord> ref = it.next(); 11342 PendingIntentRecord rec = ref != null ? ref.get(): null; 11343 if (dumpPackage != null && (rec == null 11344 || !dumpPackage.equals(rec.key.packageName))) { 11345 continue; 11346 } 11347 printed = true; 11348 if (rec != null) { 11349 pw.print(" * "); pw.println(rec); 11350 if (dumpAll) { 11351 rec.dump(pw, " "); 11352 } 11353 } else { 11354 pw.print(" * "); pw.println(ref); 11355 } 11356 } 11357 } 11358 11359 if (!printed) { 11360 pw.println(" (nothing)"); 11361 } 11362 } 11363 11364 private static final int dumpProcessList(PrintWriter pw, 11365 ActivityManagerService service, List list, 11366 String prefix, String normalLabel, String persistentLabel, 11367 String dumpPackage) { 11368 int numPers = 0; 11369 final int N = list.size()-1; 11370 for (int i=N; i>=0; i--) { 11371 ProcessRecord r = (ProcessRecord)list.get(i); 11372 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11373 continue; 11374 } 11375 pw.println(String.format("%s%s #%2d: %s", 11376 prefix, (r.persistent ? persistentLabel : normalLabel), 11377 i, r.toString())); 11378 if (r.persistent) { 11379 numPers++; 11380 } 11381 } 11382 return numPers; 11383 } 11384 11385 private static final boolean dumpProcessOomList(PrintWriter pw, 11386 ActivityManagerService service, List<ProcessRecord> origList, 11387 String prefix, String normalLabel, String persistentLabel, 11388 boolean inclDetails, String dumpPackage) { 11389 11390 ArrayList<Pair<ProcessRecord, Integer>> list 11391 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11392 for (int i=0; i<origList.size(); i++) { 11393 ProcessRecord r = origList.get(i); 11394 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11395 continue; 11396 } 11397 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11398 } 11399 11400 if (list.size() <= 0) { 11401 return false; 11402 } 11403 11404 Comparator<Pair<ProcessRecord, Integer>> comparator 11405 = new Comparator<Pair<ProcessRecord, Integer>>() { 11406 @Override 11407 public int compare(Pair<ProcessRecord, Integer> object1, 11408 Pair<ProcessRecord, Integer> object2) { 11409 if (object1.first.setAdj != object2.first.setAdj) { 11410 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11411 } 11412 if (object1.second.intValue() != object2.second.intValue()) { 11413 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11414 } 11415 return 0; 11416 } 11417 }; 11418 11419 Collections.sort(list, comparator); 11420 11421 final long curRealtime = SystemClock.elapsedRealtime(); 11422 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11423 final long curUptime = SystemClock.uptimeMillis(); 11424 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11425 11426 for (int i=list.size()-1; i>=0; i--) { 11427 ProcessRecord r = list.get(i).first; 11428 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11429 char schedGroup; 11430 switch (r.setSchedGroup) { 11431 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11432 schedGroup = 'B'; 11433 break; 11434 case Process.THREAD_GROUP_DEFAULT: 11435 schedGroup = 'F'; 11436 break; 11437 default: 11438 schedGroup = '?'; 11439 break; 11440 } 11441 char foreground; 11442 if (r.foregroundActivities) { 11443 foreground = 'A'; 11444 } else if (r.foregroundServices) { 11445 foreground = 'S'; 11446 } else { 11447 foreground = ' '; 11448 } 11449 String procState = ProcessList.makeProcStateString(r.curProcState); 11450 pw.print(prefix); 11451 pw.print(r.persistent ? persistentLabel : normalLabel); 11452 pw.print(" #"); 11453 int num = (origList.size()-1)-list.get(i).second; 11454 if (num < 10) pw.print(' '); 11455 pw.print(num); 11456 pw.print(": "); 11457 pw.print(oomAdj); 11458 pw.print(' '); 11459 pw.print(schedGroup); 11460 pw.print('/'); 11461 pw.print(foreground); 11462 pw.print('/'); 11463 pw.print(procState); 11464 pw.print(" trm:"); 11465 if (r.trimMemoryLevel < 10) pw.print(' '); 11466 pw.print(r.trimMemoryLevel); 11467 pw.print(' '); 11468 pw.print(r.toShortString()); 11469 pw.print(" ("); 11470 pw.print(r.adjType); 11471 pw.println(')'); 11472 if (r.adjSource != null || r.adjTarget != null) { 11473 pw.print(prefix); 11474 pw.print(" "); 11475 if (r.adjTarget instanceof ComponentName) { 11476 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11477 } else if (r.adjTarget != null) { 11478 pw.print(r.adjTarget.toString()); 11479 } else { 11480 pw.print("{null}"); 11481 } 11482 pw.print("<="); 11483 if (r.adjSource instanceof ProcessRecord) { 11484 pw.print("Proc{"); 11485 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11486 pw.println("}"); 11487 } else if (r.adjSource != null) { 11488 pw.println(r.adjSource.toString()); 11489 } else { 11490 pw.println("{null}"); 11491 } 11492 } 11493 if (inclDetails) { 11494 pw.print(prefix); 11495 pw.print(" "); 11496 pw.print("oom: max="); pw.print(r.maxAdj); 11497 pw.print(" curRaw="); pw.print(r.curRawAdj); 11498 pw.print(" setRaw="); pw.print(r.setRawAdj); 11499 pw.print(" cur="); pw.print(r.curAdj); 11500 pw.print(" set="); pw.println(r.setAdj); 11501 pw.print(prefix); 11502 pw.print(" "); 11503 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11504 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11505 pw.print(" lastPss="); pw.print(r.lastPss); 11506 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11507 pw.print(prefix); 11508 pw.print(" "); 11509 pw.print("keeping="); pw.print(r.keeping); 11510 pw.print(" cached="); pw.print(r.cached); 11511 pw.print(" empty="); pw.print(r.empty); 11512 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11513 11514 if (!r.keeping) { 11515 if (r.lastWakeTime != 0) { 11516 long wtime; 11517 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11518 synchronized (stats) { 11519 wtime = stats.getProcessWakeTime(r.info.uid, 11520 r.pid, curRealtime); 11521 } 11522 long timeUsed = wtime - r.lastWakeTime; 11523 pw.print(prefix); 11524 pw.print(" "); 11525 pw.print("keep awake over "); 11526 TimeUtils.formatDuration(realtimeSince, pw); 11527 pw.print(" used "); 11528 TimeUtils.formatDuration(timeUsed, pw); 11529 pw.print(" ("); 11530 pw.print((timeUsed*100)/realtimeSince); 11531 pw.println("%)"); 11532 } 11533 if (r.lastCpuTime != 0) { 11534 long timeUsed = r.curCpuTime - r.lastCpuTime; 11535 pw.print(prefix); 11536 pw.print(" "); 11537 pw.print("run cpu over "); 11538 TimeUtils.formatDuration(uptimeSince, pw); 11539 pw.print(" used "); 11540 TimeUtils.formatDuration(timeUsed, pw); 11541 pw.print(" ("); 11542 pw.print((timeUsed*100)/uptimeSince); 11543 pw.println("%)"); 11544 } 11545 } 11546 } 11547 } 11548 return true; 11549 } 11550 11551 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11552 ArrayList<ProcessRecord> procs; 11553 synchronized (this) { 11554 if (args != null && args.length > start 11555 && args[start].charAt(0) != '-') { 11556 procs = new ArrayList<ProcessRecord>(); 11557 int pid = -1; 11558 try { 11559 pid = Integer.parseInt(args[start]); 11560 } catch (NumberFormatException e) { 11561 } 11562 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11563 ProcessRecord proc = mLruProcesses.get(i); 11564 if (proc.pid == pid) { 11565 procs.add(proc); 11566 } else if (proc.processName.equals(args[start])) { 11567 procs.add(proc); 11568 } 11569 } 11570 if (procs.size() <= 0) { 11571 return null; 11572 } 11573 } else { 11574 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11575 } 11576 } 11577 return procs; 11578 } 11579 11580 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11581 PrintWriter pw, String[] args) { 11582 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11583 if (procs == null) { 11584 pw.println("No process found for: " + args[0]); 11585 return; 11586 } 11587 11588 long uptime = SystemClock.uptimeMillis(); 11589 long realtime = SystemClock.elapsedRealtime(); 11590 pw.println("Applications Graphics Acceleration Info:"); 11591 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11592 11593 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11594 ProcessRecord r = procs.get(i); 11595 if (r.thread != null) { 11596 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11597 pw.flush(); 11598 try { 11599 TransferPipe tp = new TransferPipe(); 11600 try { 11601 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11602 tp.go(fd); 11603 } finally { 11604 tp.kill(); 11605 } 11606 } catch (IOException e) { 11607 pw.println("Failure while dumping the app: " + r); 11608 pw.flush(); 11609 } catch (RemoteException e) { 11610 pw.println("Got a RemoteException while dumping the app " + r); 11611 pw.flush(); 11612 } 11613 } 11614 } 11615 } 11616 11617 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11618 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11619 if (procs == null) { 11620 pw.println("No process found for: " + args[0]); 11621 return; 11622 } 11623 11624 pw.println("Applications Database Info:"); 11625 11626 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11627 ProcessRecord r = procs.get(i); 11628 if (r.thread != null) { 11629 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11630 pw.flush(); 11631 try { 11632 TransferPipe tp = new TransferPipe(); 11633 try { 11634 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11635 tp.go(fd); 11636 } finally { 11637 tp.kill(); 11638 } 11639 } catch (IOException e) { 11640 pw.println("Failure while dumping the app: " + r); 11641 pw.flush(); 11642 } catch (RemoteException e) { 11643 pw.println("Got a RemoteException while dumping the app " + r); 11644 pw.flush(); 11645 } 11646 } 11647 } 11648 } 11649 11650 final static class MemItem { 11651 final boolean isProc; 11652 final String label; 11653 final String shortLabel; 11654 final long pss; 11655 final int id; 11656 final boolean hasActivities; 11657 ArrayList<MemItem> subitems; 11658 11659 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11660 boolean _hasActivities) { 11661 isProc = true; 11662 label = _label; 11663 shortLabel = _shortLabel; 11664 pss = _pss; 11665 id = _id; 11666 hasActivities = _hasActivities; 11667 } 11668 11669 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11670 isProc = false; 11671 label = _label; 11672 shortLabel = _shortLabel; 11673 pss = _pss; 11674 id = _id; 11675 hasActivities = false; 11676 } 11677 } 11678 11679 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11680 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11681 if (sort && !isCompact) { 11682 Collections.sort(items, new Comparator<MemItem>() { 11683 @Override 11684 public int compare(MemItem lhs, MemItem rhs) { 11685 if (lhs.pss < rhs.pss) { 11686 return 1; 11687 } else if (lhs.pss > rhs.pss) { 11688 return -1; 11689 } 11690 return 0; 11691 } 11692 }); 11693 } 11694 11695 for (int i=0; i<items.size(); i++) { 11696 MemItem mi = items.get(i); 11697 if (!isCompact) { 11698 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11699 } else if (mi.isProc) { 11700 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11701 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11702 pw.println(mi.hasActivities ? ",a" : ",e"); 11703 } else { 11704 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11705 pw.println(mi.pss); 11706 } 11707 if (mi.subitems != null) { 11708 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11709 true, isCompact); 11710 } 11711 } 11712 } 11713 11714 // These are in KB. 11715 static final long[] DUMP_MEM_BUCKETS = new long[] { 11716 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11717 120*1024, 160*1024, 200*1024, 11718 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11719 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11720 }; 11721 11722 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11723 boolean stackLike) { 11724 int start = label.lastIndexOf('.'); 11725 if (start >= 0) start++; 11726 else start = 0; 11727 int end = label.length(); 11728 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11729 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11730 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11731 out.append(bucket); 11732 out.append(stackLike ? "MB." : "MB "); 11733 out.append(label, start, end); 11734 return; 11735 } 11736 } 11737 out.append(memKB/1024); 11738 out.append(stackLike ? "MB." : "MB "); 11739 out.append(label, start, end); 11740 } 11741 11742 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11743 ProcessList.NATIVE_ADJ, 11744 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11745 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11746 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11747 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11748 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11749 }; 11750 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11751 "Native", 11752 "System", "Persistent", "Foreground", 11753 "Visible", "Perceptible", 11754 "Heavy Weight", "Backup", 11755 "A Services", "Home", 11756 "Previous", "B Services", "Cached" 11757 }; 11758 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 11759 "native", 11760 "sys", "pers", "fore", 11761 "vis", "percept", 11762 "heavy", "backup", 11763 "servicea", "home", 11764 "prev", "serviceb", "cached" 11765 }; 11766 11767 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 11768 long realtime, boolean isCheckinRequest, boolean isCompact) { 11769 if (isCheckinRequest || isCompact) { 11770 // short checkin version 11771 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 11772 } else { 11773 pw.println("Applications Memory Usage (kB):"); 11774 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11775 } 11776 } 11777 11778 final void dumpApplicationMemoryUsage(FileDescriptor fd, 11779 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 11780 boolean dumpDetails = false; 11781 boolean dumpFullDetails = false; 11782 boolean dumpDalvik = false; 11783 boolean oomOnly = false; 11784 boolean isCompact = false; 11785 boolean localOnly = false; 11786 11787 int opti = 0; 11788 while (opti < args.length) { 11789 String opt = args[opti]; 11790 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11791 break; 11792 } 11793 opti++; 11794 if ("-a".equals(opt)) { 11795 dumpDetails = true; 11796 dumpFullDetails = true; 11797 dumpDalvik = true; 11798 } else if ("-d".equals(opt)) { 11799 dumpDalvik = true; 11800 } else if ("-c".equals(opt)) { 11801 isCompact = true; 11802 } else if ("--oom".equals(opt)) { 11803 oomOnly = true; 11804 } else if ("--local".equals(opt)) { 11805 localOnly = true; 11806 } else if ("-h".equals(opt)) { 11807 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 11808 pw.println(" -a: include all available information for each process."); 11809 pw.println(" -d: include dalvik details when dumping process details."); 11810 pw.println(" -c: dump in a compact machine-parseable representation."); 11811 pw.println(" --oom: only show processes organized by oom adj."); 11812 pw.println(" --local: only collect details locally, don't call process."); 11813 pw.println("If [process] is specified it can be the name or "); 11814 pw.println("pid of a specific process to dump."); 11815 return; 11816 } else { 11817 pw.println("Unknown argument: " + opt + "; use -h for help"); 11818 } 11819 } 11820 11821 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 11822 long uptime = SystemClock.uptimeMillis(); 11823 long realtime = SystemClock.elapsedRealtime(); 11824 final long[] tmpLong = new long[1]; 11825 11826 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 11827 if (procs == null) { 11828 // No Java processes. Maybe they want to print a native process. 11829 if (args != null && args.length > opti 11830 && args[opti].charAt(0) != '-') { 11831 ArrayList<ProcessCpuTracker.Stats> nativeProcs 11832 = new ArrayList<ProcessCpuTracker.Stats>(); 11833 updateCpuStatsNow(); 11834 int findPid = -1; 11835 try { 11836 findPid = Integer.parseInt(args[opti]); 11837 } catch (NumberFormatException e) { 11838 } 11839 synchronized (mProcessCpuThread) { 11840 final int N = mProcessCpuTracker.countStats(); 11841 for (int i=0; i<N; i++) { 11842 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 11843 if (st.pid == findPid || (st.baseName != null 11844 && st.baseName.equals(args[opti]))) { 11845 nativeProcs.add(st); 11846 } 11847 } 11848 } 11849 if (nativeProcs.size() > 0) { 11850 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 11851 isCompact); 11852 Debug.MemoryInfo mi = null; 11853 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 11854 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 11855 final int pid = r.pid; 11856 if (!isCheckinRequest && dumpDetails) { 11857 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 11858 } 11859 if (mi == null) { 11860 mi = new Debug.MemoryInfo(); 11861 } 11862 if (dumpDetails || (!brief && !oomOnly)) { 11863 Debug.getMemoryInfo(pid, mi); 11864 } else { 11865 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11866 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11867 } 11868 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11869 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 11870 if (isCheckinRequest) { 11871 pw.println(); 11872 } 11873 } 11874 return; 11875 } 11876 } 11877 pw.println("No process found for: " + args[opti]); 11878 return; 11879 } 11880 11881 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 11882 dumpDetails = true; 11883 } 11884 11885 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 11886 11887 String[] innerArgs = new String[args.length-opti]; 11888 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 11889 11890 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 11891 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 11892 long nativePss=0, dalvikPss=0, otherPss=0; 11893 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 11894 11895 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 11896 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 11897 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 11898 11899 long totalPss = 0; 11900 long cachedPss = 0; 11901 11902 Debug.MemoryInfo mi = null; 11903 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11904 final ProcessRecord r = procs.get(i); 11905 final IApplicationThread thread; 11906 final int pid; 11907 final int oomAdj; 11908 final boolean hasActivities; 11909 synchronized (this) { 11910 thread = r.thread; 11911 pid = r.pid; 11912 oomAdj = r.getSetAdjWithServices(); 11913 hasActivities = r.activities.size() > 0; 11914 } 11915 if (thread != null) { 11916 if (!isCheckinRequest && dumpDetails) { 11917 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 11918 } 11919 if (mi == null) { 11920 mi = new Debug.MemoryInfo(); 11921 } 11922 if (dumpDetails || (!brief && !oomOnly)) { 11923 Debug.getMemoryInfo(pid, mi); 11924 } else { 11925 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11926 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11927 } 11928 if (dumpDetails) { 11929 if (localOnly) { 11930 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11931 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 11932 if (isCheckinRequest) { 11933 pw.println(); 11934 } 11935 } else { 11936 try { 11937 pw.flush(); 11938 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 11939 dumpDalvik, innerArgs); 11940 } catch (RemoteException e) { 11941 if (!isCheckinRequest) { 11942 pw.println("Got RemoteException!"); 11943 pw.flush(); 11944 } 11945 } 11946 } 11947 } 11948 11949 final long myTotalPss = mi.getTotalPss(); 11950 final long myTotalUss = mi.getTotalUss(); 11951 11952 synchronized (this) { 11953 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 11954 // Record this for posterity if the process has been stable. 11955 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 11956 } 11957 } 11958 11959 if (!isCheckinRequest && mi != null) { 11960 totalPss += myTotalPss; 11961 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 11962 (hasActivities ? " / activities)" : ")"), 11963 r.processName, myTotalPss, pid, hasActivities); 11964 procMems.add(pssItem); 11965 procMemsMap.put(pid, pssItem); 11966 11967 nativePss += mi.nativePss; 11968 dalvikPss += mi.dalvikPss; 11969 otherPss += mi.otherPss; 11970 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 11971 long mem = mi.getOtherPss(j); 11972 miscPss[j] += mem; 11973 otherPss -= mem; 11974 } 11975 11976 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 11977 cachedPss += myTotalPss; 11978 } 11979 11980 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 11981 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 11982 || oomIndex == (oomPss.length-1)) { 11983 oomPss[oomIndex] += myTotalPss; 11984 if (oomProcs[oomIndex] == null) { 11985 oomProcs[oomIndex] = new ArrayList<MemItem>(); 11986 } 11987 oomProcs[oomIndex].add(pssItem); 11988 break; 11989 } 11990 } 11991 } 11992 } 11993 } 11994 11995 if (!isCheckinRequest && procs.size() > 1) { 11996 // If we are showing aggregations, also look for native processes to 11997 // include so that our aggregations are more accurate. 11998 updateCpuStatsNow(); 11999 synchronized (mProcessCpuThread) { 12000 final int N = mProcessCpuTracker.countStats(); 12001 for (int i=0; i<N; i++) { 12002 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12003 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12004 if (mi == null) { 12005 mi = new Debug.MemoryInfo(); 12006 } 12007 if (!brief && !oomOnly) { 12008 Debug.getMemoryInfo(st.pid, mi); 12009 } else { 12010 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12011 mi.nativePrivateDirty = (int)tmpLong[0]; 12012 } 12013 12014 final long myTotalPss = mi.getTotalPss(); 12015 totalPss += myTotalPss; 12016 12017 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12018 st.name, myTotalPss, st.pid, false); 12019 procMems.add(pssItem); 12020 12021 nativePss += mi.nativePss; 12022 dalvikPss += mi.dalvikPss; 12023 otherPss += mi.otherPss; 12024 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12025 long mem = mi.getOtherPss(j); 12026 miscPss[j] += mem; 12027 otherPss -= mem; 12028 } 12029 oomPss[0] += myTotalPss; 12030 if (oomProcs[0] == null) { 12031 oomProcs[0] = new ArrayList<MemItem>(); 12032 } 12033 oomProcs[0].add(pssItem); 12034 } 12035 } 12036 } 12037 12038 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12039 12040 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12041 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12042 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12043 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12044 String label = Debug.MemoryInfo.getOtherLabel(j); 12045 catMems.add(new MemItem(label, label, miscPss[j], j)); 12046 } 12047 12048 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12049 for (int j=0; j<oomPss.length; j++) { 12050 if (oomPss[j] != 0) { 12051 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12052 : DUMP_MEM_OOM_LABEL[j]; 12053 MemItem item = new MemItem(label, label, oomPss[j], 12054 DUMP_MEM_OOM_ADJ[j]); 12055 item.subitems = oomProcs[j]; 12056 oomMems.add(item); 12057 } 12058 } 12059 12060 if (!brief && !oomOnly && !isCompact) { 12061 pw.println(); 12062 pw.println("Total PSS by process:"); 12063 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12064 pw.println(); 12065 } 12066 if (!isCompact) { 12067 pw.println("Total PSS by OOM adjustment:"); 12068 } 12069 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12070 if (!brief && !oomOnly) { 12071 PrintWriter out = categoryPw != null ? categoryPw : pw; 12072 if (!isCompact) { 12073 out.println(); 12074 out.println("Total PSS by category:"); 12075 } 12076 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12077 } 12078 if (!isCompact) { 12079 pw.println(); 12080 } 12081 MemInfoReader memInfo = new MemInfoReader(); 12082 memInfo.readMemInfo(); 12083 if (!brief) { 12084 if (!isCompact) { 12085 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12086 pw.println(" kB"); 12087 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12088 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12089 pw.print(cachedPss); pw.print(" cached pss + "); 12090 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12091 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12092 } else { 12093 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12094 pw.print(cachedPss + memInfo.getCachedSizeKb() 12095 + memInfo.getFreeSizeKb()); pw.print(","); 12096 pw.println(totalPss - cachedPss); 12097 } 12098 } 12099 if (!isCompact) { 12100 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12101 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12102 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12103 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12104 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12105 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12106 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12107 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12108 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12109 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12110 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12111 } 12112 if (!brief) { 12113 if (memInfo.getZramTotalSizeKb() != 0) { 12114 if (!isCompact) { 12115 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12116 pw.print(" kB physical used for "); 12117 pw.print(memInfo.getSwapTotalSizeKb() 12118 - memInfo.getSwapFreeSizeKb()); 12119 pw.print(" kB in swap ("); 12120 pw.print(memInfo.getSwapTotalSizeKb()); 12121 pw.println(" kB total swap)"); 12122 } else { 12123 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12124 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12125 pw.println(memInfo.getSwapFreeSizeKb()); 12126 } 12127 } 12128 final int[] SINGLE_LONG_FORMAT = new int[] { 12129 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12130 }; 12131 long[] longOut = new long[1]; 12132 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12133 SINGLE_LONG_FORMAT, null, longOut, null); 12134 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12135 longOut[0] = 0; 12136 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12137 SINGLE_LONG_FORMAT, null, longOut, null); 12138 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12139 longOut[0] = 0; 12140 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12141 SINGLE_LONG_FORMAT, null, longOut, null); 12142 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12143 longOut[0] = 0; 12144 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12145 SINGLE_LONG_FORMAT, null, longOut, null); 12146 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12147 if (!isCompact) { 12148 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12149 pw.print(" KSM: "); pw.print(sharing); 12150 pw.print(" kB saved from shared "); 12151 pw.print(shared); pw.println(" kB"); 12152 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12153 pw.print(voltile); pw.println(" kB volatile"); 12154 } 12155 pw.print(" Tuning: "); 12156 pw.print(ActivityManager.staticGetMemoryClass()); 12157 pw.print(" (large "); 12158 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12159 pw.print("), oom "); 12160 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12161 pw.print(" kB"); 12162 pw.print(", restore limit "); 12163 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12164 pw.print(" kB"); 12165 if (ActivityManager.isLowRamDeviceStatic()) { 12166 pw.print(" (low-ram)"); 12167 } 12168 if (ActivityManager.isHighEndGfx()) { 12169 pw.print(" (high-end-gfx)"); 12170 } 12171 pw.println(); 12172 } else { 12173 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12174 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12175 pw.println(voltile); 12176 pw.print("tuning,"); 12177 pw.print(ActivityManager.staticGetMemoryClass()); 12178 pw.print(','); 12179 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12180 pw.print(','); 12181 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12182 if (ActivityManager.isLowRamDeviceStatic()) { 12183 pw.print(",low-ram"); 12184 } 12185 if (ActivityManager.isHighEndGfx()) { 12186 pw.print(",high-end-gfx"); 12187 } 12188 pw.println(); 12189 } 12190 } 12191 } 12192 } 12193 12194 /** 12195 * Searches array of arguments for the specified string 12196 * @param args array of argument strings 12197 * @param value value to search for 12198 * @return true if the value is contained in the array 12199 */ 12200 private static boolean scanArgs(String[] args, String value) { 12201 if (args != null) { 12202 for (String arg : args) { 12203 if (value.equals(arg)) { 12204 return true; 12205 } 12206 } 12207 } 12208 return false; 12209 } 12210 12211 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12212 ContentProviderRecord cpr, boolean always) { 12213 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12214 12215 if (!inLaunching || always) { 12216 synchronized (cpr) { 12217 cpr.launchingApp = null; 12218 cpr.notifyAll(); 12219 } 12220 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12221 String names[] = cpr.info.authority.split(";"); 12222 for (int j = 0; j < names.length; j++) { 12223 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12224 } 12225 } 12226 12227 for (int i=0; i<cpr.connections.size(); i++) { 12228 ContentProviderConnection conn = cpr.connections.get(i); 12229 if (conn.waiting) { 12230 // If this connection is waiting for the provider, then we don't 12231 // need to mess with its process unless we are always removing 12232 // or for some reason the provider is not currently launching. 12233 if (inLaunching && !always) { 12234 continue; 12235 } 12236 } 12237 ProcessRecord capp = conn.client; 12238 conn.dead = true; 12239 if (conn.stableCount > 0) { 12240 if (!capp.persistent && capp.thread != null 12241 && capp.pid != 0 12242 && capp.pid != MY_PID) { 12243 killUnneededProcessLocked(capp, "depends on provider " 12244 + cpr.name.flattenToShortString() 12245 + " in dying proc " + (proc != null ? proc.processName : "??")); 12246 } 12247 } else if (capp.thread != null && conn.provider.provider != null) { 12248 try { 12249 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12250 } catch (RemoteException e) { 12251 } 12252 // In the protocol here, we don't expect the client to correctly 12253 // clean up this connection, we'll just remove it. 12254 cpr.connections.remove(i); 12255 conn.client.conProviders.remove(conn); 12256 } 12257 } 12258 12259 if (inLaunching && always) { 12260 mLaunchingProviders.remove(cpr); 12261 } 12262 return inLaunching; 12263 } 12264 12265 /** 12266 * Main code for cleaning up a process when it has gone away. This is 12267 * called both as a result of the process dying, or directly when stopping 12268 * a process when running in single process mode. 12269 */ 12270 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12271 boolean restarting, boolean allowRestart, int index) { 12272 if (index >= 0) { 12273 removeLruProcessLocked(app); 12274 ProcessList.remove(app.pid); 12275 } 12276 12277 mProcessesToGc.remove(app); 12278 mPendingPssProcesses.remove(app); 12279 12280 // Dismiss any open dialogs. 12281 if (app.crashDialog != null && !app.forceCrashReport) { 12282 app.crashDialog.dismiss(); 12283 app.crashDialog = null; 12284 } 12285 if (app.anrDialog != null) { 12286 app.anrDialog.dismiss(); 12287 app.anrDialog = null; 12288 } 12289 if (app.waitDialog != null) { 12290 app.waitDialog.dismiss(); 12291 app.waitDialog = null; 12292 } 12293 12294 app.crashing = false; 12295 app.notResponding = false; 12296 12297 app.resetPackageList(mProcessStats); 12298 app.unlinkDeathRecipient(); 12299 app.makeInactive(mProcessStats); 12300 app.forcingToForeground = null; 12301 app.foregroundServices = false; 12302 app.foregroundActivities = false; 12303 app.hasShownUi = false; 12304 app.hasAboveClient = false; 12305 12306 mServices.killServicesLocked(app, allowRestart); 12307 12308 boolean restart = false; 12309 12310 // Remove published content providers. 12311 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12312 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12313 final boolean always = app.bad || !allowRestart; 12314 if (removeDyingProviderLocked(app, cpr, always) || always) { 12315 // We left the provider in the launching list, need to 12316 // restart it. 12317 restart = true; 12318 } 12319 12320 cpr.provider = null; 12321 cpr.proc = null; 12322 } 12323 app.pubProviders.clear(); 12324 12325 // Take care of any launching providers waiting for this process. 12326 if (checkAppInLaunchingProvidersLocked(app, false)) { 12327 restart = true; 12328 } 12329 12330 // Unregister from connected content providers. 12331 if (!app.conProviders.isEmpty()) { 12332 for (int i=0; i<app.conProviders.size(); i++) { 12333 ContentProviderConnection conn = app.conProviders.get(i); 12334 conn.provider.connections.remove(conn); 12335 } 12336 app.conProviders.clear(); 12337 } 12338 12339 // At this point there may be remaining entries in mLaunchingProviders 12340 // where we were the only one waiting, so they are no longer of use. 12341 // Look for these and clean up if found. 12342 // XXX Commented out for now. Trying to figure out a way to reproduce 12343 // the actual situation to identify what is actually going on. 12344 if (false) { 12345 for (int i=0; i<mLaunchingProviders.size(); i++) { 12346 ContentProviderRecord cpr = (ContentProviderRecord) 12347 mLaunchingProviders.get(i); 12348 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12349 synchronized (cpr) { 12350 cpr.launchingApp = null; 12351 cpr.notifyAll(); 12352 } 12353 } 12354 } 12355 } 12356 12357 skipCurrentReceiverLocked(app); 12358 12359 // Unregister any receivers. 12360 for (int i=app.receivers.size()-1; i>=0; i--) { 12361 removeReceiverLocked(app.receivers.valueAt(i)); 12362 } 12363 app.receivers.clear(); 12364 12365 // If the app is undergoing backup, tell the backup manager about it 12366 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12367 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12368 + mBackupTarget.appInfo + " died during backup"); 12369 try { 12370 IBackupManager bm = IBackupManager.Stub.asInterface( 12371 ServiceManager.getService(Context.BACKUP_SERVICE)); 12372 bm.agentDisconnected(app.info.packageName); 12373 } catch (RemoteException e) { 12374 // can't happen; backup manager is local 12375 } 12376 } 12377 12378 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12379 ProcessChangeItem item = mPendingProcessChanges.get(i); 12380 if (item.pid == app.pid) { 12381 mPendingProcessChanges.remove(i); 12382 mAvailProcessChanges.add(item); 12383 } 12384 } 12385 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12386 12387 // If the caller is restarting this app, then leave it in its 12388 // current lists and let the caller take care of it. 12389 if (restarting) { 12390 return; 12391 } 12392 12393 if (!app.persistent || app.isolated) { 12394 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12395 "Removing non-persistent process during cleanup: " + app); 12396 mProcessNames.remove(app.processName, app.uid); 12397 mIsolatedProcesses.remove(app.uid); 12398 if (mHeavyWeightProcess == app) { 12399 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12400 mHeavyWeightProcess.userId, 0)); 12401 mHeavyWeightProcess = null; 12402 } 12403 } else if (!app.removed) { 12404 // This app is persistent, so we need to keep its record around. 12405 // If it is not already on the pending app list, add it there 12406 // and start a new process for it. 12407 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12408 mPersistentStartingProcesses.add(app); 12409 restart = true; 12410 } 12411 } 12412 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12413 "Clean-up removing on hold: " + app); 12414 mProcessesOnHold.remove(app); 12415 12416 if (app == mHomeProcess) { 12417 mHomeProcess = null; 12418 } 12419 if (app == mPreviousProcess) { 12420 mPreviousProcess = null; 12421 } 12422 12423 if (restart && !app.isolated) { 12424 // We have components that still need to be running in the 12425 // process, so re-launch it. 12426 mProcessNames.put(app.processName, app.uid, app); 12427 startProcessLocked(app, "restart", app.processName); 12428 } else if (app.pid > 0 && app.pid != MY_PID) { 12429 // Goodbye! 12430 synchronized (mPidsSelfLocked) { 12431 mPidsSelfLocked.remove(app.pid); 12432 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12433 } 12434 app.setPid(0); 12435 } 12436 } 12437 12438 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12439 // Look through the content providers we are waiting to have launched, 12440 // and if any run in this process then either schedule a restart of 12441 // the process or kill the client waiting for it if this process has 12442 // gone bad. 12443 int NL = mLaunchingProviders.size(); 12444 boolean restart = false; 12445 for (int i=0; i<NL; i++) { 12446 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12447 if (cpr.launchingApp == app) { 12448 if (!alwaysBad && !app.bad) { 12449 restart = true; 12450 } else { 12451 removeDyingProviderLocked(app, cpr, true); 12452 // cpr should have been removed from mLaunchingProviders 12453 NL = mLaunchingProviders.size(); 12454 i--; 12455 } 12456 } 12457 } 12458 return restart; 12459 } 12460 12461 // ========================================================= 12462 // SERVICES 12463 // ========================================================= 12464 12465 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12466 int flags) { 12467 enforceNotIsolatedCaller("getServices"); 12468 synchronized (this) { 12469 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12470 } 12471 } 12472 12473 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12474 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12475 synchronized (this) { 12476 return mServices.getRunningServiceControlPanelLocked(name); 12477 } 12478 } 12479 12480 public ComponentName startService(IApplicationThread caller, Intent service, 12481 String resolvedType, int userId) { 12482 enforceNotIsolatedCaller("startService"); 12483 // Refuse possible leaked file descriptors 12484 if (service != null && service.hasFileDescriptors() == true) { 12485 throw new IllegalArgumentException("File descriptors passed in Intent"); 12486 } 12487 12488 if (DEBUG_SERVICE) 12489 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12490 synchronized(this) { 12491 final int callingPid = Binder.getCallingPid(); 12492 final int callingUid = Binder.getCallingUid(); 12493 final long origId = Binder.clearCallingIdentity(); 12494 ComponentName res = mServices.startServiceLocked(caller, service, 12495 resolvedType, callingPid, callingUid, userId); 12496 Binder.restoreCallingIdentity(origId); 12497 return res; 12498 } 12499 } 12500 12501 ComponentName startServiceInPackage(int uid, 12502 Intent service, String resolvedType, int userId) { 12503 synchronized(this) { 12504 if (DEBUG_SERVICE) 12505 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12506 final long origId = Binder.clearCallingIdentity(); 12507 ComponentName res = mServices.startServiceLocked(null, service, 12508 resolvedType, -1, uid, userId); 12509 Binder.restoreCallingIdentity(origId); 12510 return res; 12511 } 12512 } 12513 12514 public int stopService(IApplicationThread caller, Intent service, 12515 String resolvedType, int userId) { 12516 enforceNotIsolatedCaller("stopService"); 12517 // Refuse possible leaked file descriptors 12518 if (service != null && service.hasFileDescriptors() == true) { 12519 throw new IllegalArgumentException("File descriptors passed in Intent"); 12520 } 12521 12522 synchronized(this) { 12523 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12524 } 12525 } 12526 12527 public IBinder peekService(Intent service, String resolvedType) { 12528 enforceNotIsolatedCaller("peekService"); 12529 // Refuse possible leaked file descriptors 12530 if (service != null && service.hasFileDescriptors() == true) { 12531 throw new IllegalArgumentException("File descriptors passed in Intent"); 12532 } 12533 synchronized(this) { 12534 return mServices.peekServiceLocked(service, resolvedType); 12535 } 12536 } 12537 12538 public boolean stopServiceToken(ComponentName className, IBinder token, 12539 int startId) { 12540 synchronized(this) { 12541 return mServices.stopServiceTokenLocked(className, token, startId); 12542 } 12543 } 12544 12545 public void setServiceForeground(ComponentName className, IBinder token, 12546 int id, Notification notification, boolean removeNotification) { 12547 synchronized(this) { 12548 mServices.setServiceForegroundLocked(className, token, id, notification, 12549 removeNotification); 12550 } 12551 } 12552 12553 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12554 boolean requireFull, String name, String callerPackage) { 12555 final int callingUserId = UserHandle.getUserId(callingUid); 12556 if (callingUserId != userId) { 12557 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12558 if ((requireFull || checkComponentPermission( 12559 android.Manifest.permission.INTERACT_ACROSS_USERS, 12560 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12561 && checkComponentPermission( 12562 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12563 callingPid, callingUid, -1, true) 12564 != PackageManager.PERMISSION_GRANTED) { 12565 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12566 // In this case, they would like to just execute as their 12567 // owner user instead of failing. 12568 userId = callingUserId; 12569 } else { 12570 StringBuilder builder = new StringBuilder(128); 12571 builder.append("Permission Denial: "); 12572 builder.append(name); 12573 if (callerPackage != null) { 12574 builder.append(" from "); 12575 builder.append(callerPackage); 12576 } 12577 builder.append(" asks to run as user "); 12578 builder.append(userId); 12579 builder.append(" but is calling from user "); 12580 builder.append(UserHandle.getUserId(callingUid)); 12581 builder.append("; this requires "); 12582 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12583 if (!requireFull) { 12584 builder.append(" or "); 12585 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12586 } 12587 String msg = builder.toString(); 12588 Slog.w(TAG, msg); 12589 throw new SecurityException(msg); 12590 } 12591 } 12592 } 12593 if (userId == UserHandle.USER_CURRENT 12594 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12595 // Note that we may be accessing this outside of a lock... 12596 // shouldn't be a big deal, if this is being called outside 12597 // of a locked context there is intrinsically a race with 12598 // the value the caller will receive and someone else changing it. 12599 userId = mCurrentUserId; 12600 } 12601 if (!allowAll && userId < 0) { 12602 throw new IllegalArgumentException( 12603 "Call does not support special user #" + userId); 12604 } 12605 } 12606 return userId; 12607 } 12608 12609 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12610 String className, int flags) { 12611 boolean result = false; 12612 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12613 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12614 if (ActivityManager.checkUidPermission( 12615 android.Manifest.permission.INTERACT_ACROSS_USERS, 12616 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12617 ComponentName comp = new ComponentName(aInfo.packageName, className); 12618 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12619 + " requests FLAG_SINGLE_USER, but app does not hold " 12620 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12621 Slog.w(TAG, msg); 12622 throw new SecurityException(msg); 12623 } 12624 result = true; 12625 } 12626 } else if (componentProcessName == aInfo.packageName) { 12627 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12628 } else if ("system".equals(componentProcessName)) { 12629 result = true; 12630 } 12631 if (DEBUG_MU) { 12632 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12633 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12634 } 12635 return result; 12636 } 12637 12638 public int bindService(IApplicationThread caller, IBinder token, 12639 Intent service, String resolvedType, 12640 IServiceConnection connection, int flags, int userId) { 12641 enforceNotIsolatedCaller("bindService"); 12642 // Refuse possible leaked file descriptors 12643 if (service != null && service.hasFileDescriptors() == true) { 12644 throw new IllegalArgumentException("File descriptors passed in Intent"); 12645 } 12646 12647 synchronized(this) { 12648 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12649 connection, flags, userId); 12650 } 12651 } 12652 12653 public boolean unbindService(IServiceConnection connection) { 12654 synchronized (this) { 12655 return mServices.unbindServiceLocked(connection); 12656 } 12657 } 12658 12659 public void publishService(IBinder token, Intent intent, IBinder service) { 12660 // Refuse possible leaked file descriptors 12661 if (intent != null && intent.hasFileDescriptors() == true) { 12662 throw new IllegalArgumentException("File descriptors passed in Intent"); 12663 } 12664 12665 synchronized(this) { 12666 if (!(token instanceof ServiceRecord)) { 12667 throw new IllegalArgumentException("Invalid service token"); 12668 } 12669 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12670 } 12671 } 12672 12673 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12674 // Refuse possible leaked file descriptors 12675 if (intent != null && intent.hasFileDescriptors() == true) { 12676 throw new IllegalArgumentException("File descriptors passed in Intent"); 12677 } 12678 12679 synchronized(this) { 12680 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12681 } 12682 } 12683 12684 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12685 synchronized(this) { 12686 if (!(token instanceof ServiceRecord)) { 12687 throw new IllegalArgumentException("Invalid service token"); 12688 } 12689 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12690 } 12691 } 12692 12693 // ========================================================= 12694 // BACKUP AND RESTORE 12695 // ========================================================= 12696 12697 // Cause the target app to be launched if necessary and its backup agent 12698 // instantiated. The backup agent will invoke backupAgentCreated() on the 12699 // activity manager to announce its creation. 12700 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12701 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12702 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12703 12704 synchronized(this) { 12705 // !!! TODO: currently no check here that we're already bound 12706 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12707 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12708 synchronized (stats) { 12709 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12710 } 12711 12712 // Backup agent is now in use, its package can't be stopped. 12713 try { 12714 AppGlobals.getPackageManager().setPackageStoppedState( 12715 app.packageName, false, UserHandle.getUserId(app.uid)); 12716 } catch (RemoteException e) { 12717 } catch (IllegalArgumentException e) { 12718 Slog.w(TAG, "Failed trying to unstop package " 12719 + app.packageName + ": " + e); 12720 } 12721 12722 BackupRecord r = new BackupRecord(ss, app, backupMode); 12723 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12724 ? new ComponentName(app.packageName, app.backupAgentName) 12725 : new ComponentName("android", "FullBackupAgent"); 12726 // startProcessLocked() returns existing proc's record if it's already running 12727 ProcessRecord proc = startProcessLocked(app.processName, app, 12728 false, 0, "backup", hostingName, false, false, false); 12729 if (proc == null) { 12730 Slog.e(TAG, "Unable to start backup agent process " + r); 12731 return false; 12732 } 12733 12734 r.app = proc; 12735 mBackupTarget = r; 12736 mBackupAppName = app.packageName; 12737 12738 // Try not to kill the process during backup 12739 updateOomAdjLocked(proc); 12740 12741 // If the process is already attached, schedule the creation of the backup agent now. 12742 // If it is not yet live, this will be done when it attaches to the framework. 12743 if (proc.thread != null) { 12744 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12745 try { 12746 proc.thread.scheduleCreateBackupAgent(app, 12747 compatibilityInfoForPackageLocked(app), backupMode); 12748 } catch (RemoteException e) { 12749 // Will time out on the backup manager side 12750 } 12751 } else { 12752 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12753 } 12754 // Invariants: at this point, the target app process exists and the application 12755 // is either already running or in the process of coming up. mBackupTarget and 12756 // mBackupAppName describe the app, so that when it binds back to the AM we 12757 // know that it's scheduled for a backup-agent operation. 12758 } 12759 12760 return true; 12761 } 12762 12763 @Override 12764 public void clearPendingBackup() { 12765 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 12766 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 12767 12768 synchronized (this) { 12769 mBackupTarget = null; 12770 mBackupAppName = null; 12771 } 12772 } 12773 12774 // A backup agent has just come up 12775 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12776 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12777 + " = " + agent); 12778 12779 synchronized(this) { 12780 if (!agentPackageName.equals(mBackupAppName)) { 12781 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12782 return; 12783 } 12784 } 12785 12786 long oldIdent = Binder.clearCallingIdentity(); 12787 try { 12788 IBackupManager bm = IBackupManager.Stub.asInterface( 12789 ServiceManager.getService(Context.BACKUP_SERVICE)); 12790 bm.agentConnected(agentPackageName, agent); 12791 } catch (RemoteException e) { 12792 // can't happen; the backup manager service is local 12793 } catch (Exception e) { 12794 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12795 e.printStackTrace(); 12796 } finally { 12797 Binder.restoreCallingIdentity(oldIdent); 12798 } 12799 } 12800 12801 // done with this agent 12802 public void unbindBackupAgent(ApplicationInfo appInfo) { 12803 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12804 if (appInfo == null) { 12805 Slog.w(TAG, "unbind backup agent for null app"); 12806 return; 12807 } 12808 12809 synchronized(this) { 12810 try { 12811 if (mBackupAppName == null) { 12812 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12813 return; 12814 } 12815 12816 if (!mBackupAppName.equals(appInfo.packageName)) { 12817 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12818 return; 12819 } 12820 12821 // Not backing this app up any more; reset its OOM adjustment 12822 final ProcessRecord proc = mBackupTarget.app; 12823 updateOomAdjLocked(proc); 12824 12825 // If the app crashed during backup, 'thread' will be null here 12826 if (proc.thread != null) { 12827 try { 12828 proc.thread.scheduleDestroyBackupAgent(appInfo, 12829 compatibilityInfoForPackageLocked(appInfo)); 12830 } catch (Exception e) { 12831 Slog.e(TAG, "Exception when unbinding backup agent:"); 12832 e.printStackTrace(); 12833 } 12834 } 12835 } finally { 12836 mBackupTarget = null; 12837 mBackupAppName = null; 12838 } 12839 } 12840 } 12841 // ========================================================= 12842 // BROADCASTS 12843 // ========================================================= 12844 12845 private final List getStickiesLocked(String action, IntentFilter filter, 12846 List cur, int userId) { 12847 final ContentResolver resolver = mContext.getContentResolver(); 12848 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12849 if (stickies == null) { 12850 return cur; 12851 } 12852 final ArrayList<Intent> list = stickies.get(action); 12853 if (list == null) { 12854 return cur; 12855 } 12856 int N = list.size(); 12857 for (int i=0; i<N; i++) { 12858 Intent intent = list.get(i); 12859 if (filter.match(resolver, intent, true, TAG) >= 0) { 12860 if (cur == null) { 12861 cur = new ArrayList<Intent>(); 12862 } 12863 cur.add(intent); 12864 } 12865 } 12866 return cur; 12867 } 12868 12869 boolean isPendingBroadcastProcessLocked(int pid) { 12870 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12871 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12872 } 12873 12874 void skipPendingBroadcastLocked(int pid) { 12875 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 12876 for (BroadcastQueue queue : mBroadcastQueues) { 12877 queue.skipPendingBroadcastLocked(pid); 12878 } 12879 } 12880 12881 // The app just attached; send any pending broadcasts that it should receive 12882 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 12883 boolean didSomething = false; 12884 for (BroadcastQueue queue : mBroadcastQueues) { 12885 didSomething |= queue.sendPendingBroadcastsLocked(app); 12886 } 12887 return didSomething; 12888 } 12889 12890 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 12891 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 12892 enforceNotIsolatedCaller("registerReceiver"); 12893 int callingUid; 12894 int callingPid; 12895 synchronized(this) { 12896 ProcessRecord callerApp = null; 12897 if (caller != null) { 12898 callerApp = getRecordForAppLocked(caller); 12899 if (callerApp == null) { 12900 throw new SecurityException( 12901 "Unable to find app for caller " + caller 12902 + " (pid=" + Binder.getCallingPid() 12903 + ") when registering receiver " + receiver); 12904 } 12905 if (callerApp.info.uid != Process.SYSTEM_UID && 12906 !callerApp.pkgList.containsKey(callerPackage) && 12907 !"android".equals(callerPackage)) { 12908 throw new SecurityException("Given caller package " + callerPackage 12909 + " is not running in process " + callerApp); 12910 } 12911 callingUid = callerApp.info.uid; 12912 callingPid = callerApp.pid; 12913 } else { 12914 callerPackage = null; 12915 callingUid = Binder.getCallingUid(); 12916 callingPid = Binder.getCallingPid(); 12917 } 12918 12919 userId = this.handleIncomingUser(callingPid, callingUid, userId, 12920 true, true, "registerReceiver", callerPackage); 12921 12922 List allSticky = null; 12923 12924 // Look for any matching sticky broadcasts... 12925 Iterator actions = filter.actionsIterator(); 12926 if (actions != null) { 12927 while (actions.hasNext()) { 12928 String action = (String)actions.next(); 12929 allSticky = getStickiesLocked(action, filter, allSticky, 12930 UserHandle.USER_ALL); 12931 allSticky = getStickiesLocked(action, filter, allSticky, 12932 UserHandle.getUserId(callingUid)); 12933 } 12934 } else { 12935 allSticky = getStickiesLocked(null, filter, allSticky, 12936 UserHandle.USER_ALL); 12937 allSticky = getStickiesLocked(null, filter, allSticky, 12938 UserHandle.getUserId(callingUid)); 12939 } 12940 12941 // The first sticky in the list is returned directly back to 12942 // the client. 12943 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 12944 12945 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 12946 + ": " + sticky); 12947 12948 if (receiver == null) { 12949 return sticky; 12950 } 12951 12952 ReceiverList rl 12953 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12954 if (rl == null) { 12955 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 12956 userId, receiver); 12957 if (rl.app != null) { 12958 rl.app.receivers.add(rl); 12959 } else { 12960 try { 12961 receiver.asBinder().linkToDeath(rl, 0); 12962 } catch (RemoteException e) { 12963 return sticky; 12964 } 12965 rl.linkedToDeath = true; 12966 } 12967 mRegisteredReceivers.put(receiver.asBinder(), rl); 12968 } else if (rl.uid != callingUid) { 12969 throw new IllegalArgumentException( 12970 "Receiver requested to register for uid " + callingUid 12971 + " was previously registered for uid " + rl.uid); 12972 } else if (rl.pid != callingPid) { 12973 throw new IllegalArgumentException( 12974 "Receiver requested to register for pid " + callingPid 12975 + " was previously registered for pid " + rl.pid); 12976 } else if (rl.userId != userId) { 12977 throw new IllegalArgumentException( 12978 "Receiver requested to register for user " + userId 12979 + " was previously registered for user " + rl.userId); 12980 } 12981 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 12982 permission, callingUid, userId); 12983 rl.add(bf); 12984 if (!bf.debugCheck()) { 12985 Slog.w(TAG, "==> For Dynamic broadast"); 12986 } 12987 mReceiverResolver.addFilter(bf); 12988 12989 // Enqueue broadcasts for all existing stickies that match 12990 // this filter. 12991 if (allSticky != null) { 12992 ArrayList receivers = new ArrayList(); 12993 receivers.add(bf); 12994 12995 int N = allSticky.size(); 12996 for (int i=0; i<N; i++) { 12997 Intent intent = (Intent)allSticky.get(i); 12998 BroadcastQueue queue = broadcastQueueForIntent(intent); 12999 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13000 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13001 null, null, false, true, true, -1); 13002 queue.enqueueParallelBroadcastLocked(r); 13003 queue.scheduleBroadcastsLocked(); 13004 } 13005 } 13006 13007 return sticky; 13008 } 13009 } 13010 13011 public void unregisterReceiver(IIntentReceiver receiver) { 13012 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13013 13014 final long origId = Binder.clearCallingIdentity(); 13015 try { 13016 boolean doTrim = false; 13017 13018 synchronized(this) { 13019 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13020 if (rl != null) { 13021 if (rl.curBroadcast != null) { 13022 BroadcastRecord r = rl.curBroadcast; 13023 final boolean doNext = finishReceiverLocked( 13024 receiver.asBinder(), r.resultCode, r.resultData, 13025 r.resultExtras, r.resultAbort); 13026 if (doNext) { 13027 doTrim = true; 13028 r.queue.processNextBroadcast(false); 13029 } 13030 } 13031 13032 if (rl.app != null) { 13033 rl.app.receivers.remove(rl); 13034 } 13035 removeReceiverLocked(rl); 13036 if (rl.linkedToDeath) { 13037 rl.linkedToDeath = false; 13038 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13039 } 13040 } 13041 } 13042 13043 // If we actually concluded any broadcasts, we might now be able 13044 // to trim the recipients' apps from our working set 13045 if (doTrim) { 13046 trimApplications(); 13047 return; 13048 } 13049 13050 } finally { 13051 Binder.restoreCallingIdentity(origId); 13052 } 13053 } 13054 13055 void removeReceiverLocked(ReceiverList rl) { 13056 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13057 int N = rl.size(); 13058 for (int i=0; i<N; i++) { 13059 mReceiverResolver.removeFilter(rl.get(i)); 13060 } 13061 } 13062 13063 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13064 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13065 ProcessRecord r = mLruProcesses.get(i); 13066 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13067 try { 13068 r.thread.dispatchPackageBroadcast(cmd, packages); 13069 } catch (RemoteException ex) { 13070 } 13071 } 13072 } 13073 } 13074 13075 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13076 int[] users) { 13077 List<ResolveInfo> receivers = null; 13078 try { 13079 HashSet<ComponentName> singleUserReceivers = null; 13080 boolean scannedFirstReceivers = false; 13081 for (int user : users) { 13082 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13083 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13084 if (user != 0 && newReceivers != null) { 13085 // If this is not the primary user, we need to check for 13086 // any receivers that should be filtered out. 13087 for (int i=0; i<newReceivers.size(); i++) { 13088 ResolveInfo ri = newReceivers.get(i); 13089 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13090 newReceivers.remove(i); 13091 i--; 13092 } 13093 } 13094 } 13095 if (newReceivers != null && newReceivers.size() == 0) { 13096 newReceivers = null; 13097 } 13098 if (receivers == null) { 13099 receivers = newReceivers; 13100 } else if (newReceivers != null) { 13101 // We need to concatenate the additional receivers 13102 // found with what we have do far. This would be easy, 13103 // but we also need to de-dup any receivers that are 13104 // singleUser. 13105 if (!scannedFirstReceivers) { 13106 // Collect any single user receivers we had already retrieved. 13107 scannedFirstReceivers = true; 13108 for (int i=0; i<receivers.size(); i++) { 13109 ResolveInfo ri = receivers.get(i); 13110 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13111 ComponentName cn = new ComponentName( 13112 ri.activityInfo.packageName, ri.activityInfo.name); 13113 if (singleUserReceivers == null) { 13114 singleUserReceivers = new HashSet<ComponentName>(); 13115 } 13116 singleUserReceivers.add(cn); 13117 } 13118 } 13119 } 13120 // Add the new results to the existing results, tracking 13121 // and de-dupping single user receivers. 13122 for (int i=0; i<newReceivers.size(); i++) { 13123 ResolveInfo ri = newReceivers.get(i); 13124 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13125 ComponentName cn = new ComponentName( 13126 ri.activityInfo.packageName, ri.activityInfo.name); 13127 if (singleUserReceivers == null) { 13128 singleUserReceivers = new HashSet<ComponentName>(); 13129 } 13130 if (!singleUserReceivers.contains(cn)) { 13131 singleUserReceivers.add(cn); 13132 receivers.add(ri); 13133 } 13134 } else { 13135 receivers.add(ri); 13136 } 13137 } 13138 } 13139 } 13140 } catch (RemoteException ex) { 13141 // pm is in same process, this will never happen. 13142 } 13143 return receivers; 13144 } 13145 13146 private final int broadcastIntentLocked(ProcessRecord callerApp, 13147 String callerPackage, Intent intent, String resolvedType, 13148 IIntentReceiver resultTo, int resultCode, String resultData, 13149 Bundle map, String requiredPermission, int appOp, 13150 boolean ordered, boolean sticky, int callingPid, int callingUid, 13151 int userId) { 13152 intent = new Intent(intent); 13153 13154 // By default broadcasts do not go to stopped apps. 13155 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13156 13157 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13158 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13159 + " ordered=" + ordered + " userid=" + userId); 13160 if ((resultTo != null) && !ordered) { 13161 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13162 } 13163 13164 userId = handleIncomingUser(callingPid, callingUid, userId, 13165 true, false, "broadcast", callerPackage); 13166 13167 // Make sure that the user who is receiving this broadcast is started. 13168 // If not, we will just skip it. 13169 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13170 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13171 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13172 Slog.w(TAG, "Skipping broadcast of " + intent 13173 + ": user " + userId + " is stopped"); 13174 return ActivityManager.BROADCAST_SUCCESS; 13175 } 13176 } 13177 13178 /* 13179 * Prevent non-system code (defined here to be non-persistent 13180 * processes) from sending protected broadcasts. 13181 */ 13182 int callingAppId = UserHandle.getAppId(callingUid); 13183 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13184 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13185 callingUid == 0) { 13186 // Always okay. 13187 } else if (callerApp == null || !callerApp.persistent) { 13188 try { 13189 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13190 intent.getAction())) { 13191 String msg = "Permission Denial: not allowed to send broadcast " 13192 + intent.getAction() + " from pid=" 13193 + callingPid + ", uid=" + callingUid; 13194 Slog.w(TAG, msg); 13195 throw new SecurityException(msg); 13196 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13197 // Special case for compatibility: we don't want apps to send this, 13198 // but historically it has not been protected and apps may be using it 13199 // to poke their own app widget. So, instead of making it protected, 13200 // just limit it to the caller. 13201 if (callerApp == null) { 13202 String msg = "Permission Denial: not allowed to send broadcast " 13203 + intent.getAction() + " from unknown caller."; 13204 Slog.w(TAG, msg); 13205 throw new SecurityException(msg); 13206 } else if (intent.getComponent() != null) { 13207 // They are good enough to send to an explicit component... verify 13208 // it is being sent to the calling app. 13209 if (!intent.getComponent().getPackageName().equals( 13210 callerApp.info.packageName)) { 13211 String msg = "Permission Denial: not allowed to send broadcast " 13212 + intent.getAction() + " to " 13213 + intent.getComponent().getPackageName() + " from " 13214 + callerApp.info.packageName; 13215 Slog.w(TAG, msg); 13216 throw new SecurityException(msg); 13217 } 13218 } else { 13219 // Limit broadcast to their own package. 13220 intent.setPackage(callerApp.info.packageName); 13221 } 13222 } 13223 } catch (RemoteException e) { 13224 Slog.w(TAG, "Remote exception", e); 13225 return ActivityManager.BROADCAST_SUCCESS; 13226 } 13227 } 13228 13229 // Handle special intents: if this broadcast is from the package 13230 // manager about a package being removed, we need to remove all of 13231 // its activities from the history stack. 13232 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13233 intent.getAction()); 13234 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13235 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13236 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13237 || uidRemoved) { 13238 if (checkComponentPermission( 13239 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13240 callingPid, callingUid, -1, true) 13241 == PackageManager.PERMISSION_GRANTED) { 13242 if (uidRemoved) { 13243 final Bundle intentExtras = intent.getExtras(); 13244 final int uid = intentExtras != null 13245 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13246 if (uid >= 0) { 13247 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13248 synchronized (bs) { 13249 bs.removeUidStatsLocked(uid); 13250 } 13251 mAppOpsService.uidRemoved(uid); 13252 } 13253 } else { 13254 // If resources are unavailable just force stop all 13255 // those packages and flush the attribute cache as well. 13256 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13257 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13258 if (list != null && (list.length > 0)) { 13259 for (String pkg : list) { 13260 forceStopPackageLocked(pkg, -1, false, true, true, false, userId, 13261 "storage unmount"); 13262 } 13263 sendPackageBroadcastLocked( 13264 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13265 } 13266 } else { 13267 Uri data = intent.getData(); 13268 String ssp; 13269 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13270 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13271 intent.getAction()); 13272 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13273 forceStopPackageLocked(ssp, UserHandle.getAppId( 13274 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13275 false, userId, removed ? "pkg removed" : "pkg changed"); 13276 } 13277 if (removed) { 13278 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13279 new String[] {ssp}, userId); 13280 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13281 mAppOpsService.packageRemoved( 13282 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13283 13284 // Remove all permissions granted from/to this package 13285 removeUriPermissionsForPackageLocked(ssp, userId, true); 13286 } 13287 } 13288 } 13289 } 13290 } 13291 } else { 13292 String msg = "Permission Denial: " + intent.getAction() 13293 + " broadcast from " + callerPackage + " (pid=" + callingPid 13294 + ", uid=" + callingUid + ")" 13295 + " requires " 13296 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13297 Slog.w(TAG, msg); 13298 throw new SecurityException(msg); 13299 } 13300 13301 // Special case for adding a package: by default turn on compatibility 13302 // mode. 13303 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13304 Uri data = intent.getData(); 13305 String ssp; 13306 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13307 mCompatModePackages.handlePackageAddedLocked(ssp, 13308 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13309 } 13310 } 13311 13312 /* 13313 * If this is the time zone changed action, queue up a message that will reset the timezone 13314 * of all currently running processes. This message will get queued up before the broadcast 13315 * happens. 13316 */ 13317 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13318 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13319 } 13320 13321 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13322 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13323 } 13324 13325 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13326 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13327 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13328 } 13329 13330 // Add to the sticky list if requested. 13331 if (sticky) { 13332 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13333 callingPid, callingUid) 13334 != PackageManager.PERMISSION_GRANTED) { 13335 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13336 + callingPid + ", uid=" + callingUid 13337 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13338 Slog.w(TAG, msg); 13339 throw new SecurityException(msg); 13340 } 13341 if (requiredPermission != null) { 13342 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13343 + " and enforce permission " + requiredPermission); 13344 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13345 } 13346 if (intent.getComponent() != null) { 13347 throw new SecurityException( 13348 "Sticky broadcasts can't target a specific component"); 13349 } 13350 // We use userId directly here, since the "all" target is maintained 13351 // as a separate set of sticky broadcasts. 13352 if (userId != UserHandle.USER_ALL) { 13353 // But first, if this is not a broadcast to all users, then 13354 // make sure it doesn't conflict with an existing broadcast to 13355 // all users. 13356 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13357 UserHandle.USER_ALL); 13358 if (stickies != null) { 13359 ArrayList<Intent> list = stickies.get(intent.getAction()); 13360 if (list != null) { 13361 int N = list.size(); 13362 int i; 13363 for (i=0; i<N; i++) { 13364 if (intent.filterEquals(list.get(i))) { 13365 throw new IllegalArgumentException( 13366 "Sticky broadcast " + intent + " for user " 13367 + userId + " conflicts with existing global broadcast"); 13368 } 13369 } 13370 } 13371 } 13372 } 13373 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13374 if (stickies == null) { 13375 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13376 mStickyBroadcasts.put(userId, stickies); 13377 } 13378 ArrayList<Intent> list = stickies.get(intent.getAction()); 13379 if (list == null) { 13380 list = new ArrayList<Intent>(); 13381 stickies.put(intent.getAction(), list); 13382 } 13383 int N = list.size(); 13384 int i; 13385 for (i=0; i<N; i++) { 13386 if (intent.filterEquals(list.get(i))) { 13387 // This sticky already exists, replace it. 13388 list.set(i, new Intent(intent)); 13389 break; 13390 } 13391 } 13392 if (i >= N) { 13393 list.add(new Intent(intent)); 13394 } 13395 } 13396 13397 int[] users; 13398 if (userId == UserHandle.USER_ALL) { 13399 // Caller wants broadcast to go to all started users. 13400 users = mStartedUserArray; 13401 } else { 13402 // Caller wants broadcast to go to one specific user. 13403 users = new int[] {userId}; 13404 } 13405 13406 // Figure out who all will receive this broadcast. 13407 List receivers = null; 13408 List<BroadcastFilter> registeredReceivers = null; 13409 // Need to resolve the intent to interested receivers... 13410 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13411 == 0) { 13412 receivers = collectReceiverComponents(intent, resolvedType, users); 13413 } 13414 if (intent.getComponent() == null) { 13415 registeredReceivers = mReceiverResolver.queryIntent(intent, 13416 resolvedType, false, userId); 13417 } 13418 13419 final boolean replacePending = 13420 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13421 13422 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13423 + " replacePending=" + replacePending); 13424 13425 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13426 if (!ordered && NR > 0) { 13427 // If we are not serializing this broadcast, then send the 13428 // registered receivers separately so they don't wait for the 13429 // components to be launched. 13430 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13431 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13432 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13433 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13434 ordered, sticky, false, userId); 13435 if (DEBUG_BROADCAST) Slog.v( 13436 TAG, "Enqueueing parallel broadcast " + r); 13437 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13438 if (!replaced) { 13439 queue.enqueueParallelBroadcastLocked(r); 13440 queue.scheduleBroadcastsLocked(); 13441 } 13442 registeredReceivers = null; 13443 NR = 0; 13444 } 13445 13446 // Merge into one list. 13447 int ir = 0; 13448 if (receivers != null) { 13449 // A special case for PACKAGE_ADDED: do not allow the package 13450 // being added to see this broadcast. This prevents them from 13451 // using this as a back door to get run as soon as they are 13452 // installed. Maybe in the future we want to have a special install 13453 // broadcast or such for apps, but we'd like to deliberately make 13454 // this decision. 13455 String skipPackages[] = null; 13456 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13457 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13458 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13459 Uri data = intent.getData(); 13460 if (data != null) { 13461 String pkgName = data.getSchemeSpecificPart(); 13462 if (pkgName != null) { 13463 skipPackages = new String[] { pkgName }; 13464 } 13465 } 13466 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13467 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13468 } 13469 if (skipPackages != null && (skipPackages.length > 0)) { 13470 for (String skipPackage : skipPackages) { 13471 if (skipPackage != null) { 13472 int NT = receivers.size(); 13473 for (int it=0; it<NT; it++) { 13474 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13475 if (curt.activityInfo.packageName.equals(skipPackage)) { 13476 receivers.remove(it); 13477 it--; 13478 NT--; 13479 } 13480 } 13481 } 13482 } 13483 } 13484 13485 int NT = receivers != null ? receivers.size() : 0; 13486 int it = 0; 13487 ResolveInfo curt = null; 13488 BroadcastFilter curr = null; 13489 while (it < NT && ir < NR) { 13490 if (curt == null) { 13491 curt = (ResolveInfo)receivers.get(it); 13492 } 13493 if (curr == null) { 13494 curr = registeredReceivers.get(ir); 13495 } 13496 if (curr.getPriority() >= curt.priority) { 13497 // Insert this broadcast record into the final list. 13498 receivers.add(it, curr); 13499 ir++; 13500 curr = null; 13501 it++; 13502 NT++; 13503 } else { 13504 // Skip to the next ResolveInfo in the final list. 13505 it++; 13506 curt = null; 13507 } 13508 } 13509 } 13510 while (ir < NR) { 13511 if (receivers == null) { 13512 receivers = new ArrayList(); 13513 } 13514 receivers.add(registeredReceivers.get(ir)); 13515 ir++; 13516 } 13517 13518 if ((receivers != null && receivers.size() > 0) 13519 || resultTo != null) { 13520 BroadcastQueue queue = broadcastQueueForIntent(intent); 13521 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13522 callerPackage, callingPid, callingUid, resolvedType, 13523 requiredPermission, appOp, receivers, resultTo, resultCode, 13524 resultData, map, ordered, sticky, false, userId); 13525 if (DEBUG_BROADCAST) Slog.v( 13526 TAG, "Enqueueing ordered broadcast " + r 13527 + ": prev had " + queue.mOrderedBroadcasts.size()); 13528 if (DEBUG_BROADCAST) { 13529 int seq = r.intent.getIntExtra("seq", -1); 13530 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13531 } 13532 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13533 if (!replaced) { 13534 queue.enqueueOrderedBroadcastLocked(r); 13535 queue.scheduleBroadcastsLocked(); 13536 } 13537 } 13538 13539 return ActivityManager.BROADCAST_SUCCESS; 13540 } 13541 13542 final Intent verifyBroadcastLocked(Intent intent) { 13543 // Refuse possible leaked file descriptors 13544 if (intent != null && intent.hasFileDescriptors() == true) { 13545 throw new IllegalArgumentException("File descriptors passed in Intent"); 13546 } 13547 13548 int flags = intent.getFlags(); 13549 13550 if (!mProcessesReady) { 13551 // if the caller really truly claims to know what they're doing, go 13552 // ahead and allow the broadcast without launching any receivers 13553 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13554 intent = new Intent(intent); 13555 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13556 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13557 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13558 + " before boot completion"); 13559 throw new IllegalStateException("Cannot broadcast before boot completed"); 13560 } 13561 } 13562 13563 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13564 throw new IllegalArgumentException( 13565 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13566 } 13567 13568 return intent; 13569 } 13570 13571 public final int broadcastIntent(IApplicationThread caller, 13572 Intent intent, String resolvedType, IIntentReceiver resultTo, 13573 int resultCode, String resultData, Bundle map, 13574 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13575 enforceNotIsolatedCaller("broadcastIntent"); 13576 synchronized(this) { 13577 intent = verifyBroadcastLocked(intent); 13578 13579 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13580 final int callingPid = Binder.getCallingPid(); 13581 final int callingUid = Binder.getCallingUid(); 13582 final long origId = Binder.clearCallingIdentity(); 13583 int res = broadcastIntentLocked(callerApp, 13584 callerApp != null ? callerApp.info.packageName : null, 13585 intent, resolvedType, resultTo, 13586 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13587 callingPid, callingUid, userId); 13588 Binder.restoreCallingIdentity(origId); 13589 return res; 13590 } 13591 } 13592 13593 int broadcastIntentInPackage(String packageName, int uid, 13594 Intent intent, String resolvedType, IIntentReceiver resultTo, 13595 int resultCode, String resultData, Bundle map, 13596 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13597 synchronized(this) { 13598 intent = verifyBroadcastLocked(intent); 13599 13600 final long origId = Binder.clearCallingIdentity(); 13601 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13602 resultTo, resultCode, resultData, map, requiredPermission, 13603 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13604 Binder.restoreCallingIdentity(origId); 13605 return res; 13606 } 13607 } 13608 13609 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13610 // Refuse possible leaked file descriptors 13611 if (intent != null && intent.hasFileDescriptors() == true) { 13612 throw new IllegalArgumentException("File descriptors passed in Intent"); 13613 } 13614 13615 userId = handleIncomingUser(Binder.getCallingPid(), 13616 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13617 13618 synchronized(this) { 13619 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13620 != PackageManager.PERMISSION_GRANTED) { 13621 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13622 + Binder.getCallingPid() 13623 + ", uid=" + Binder.getCallingUid() 13624 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13625 Slog.w(TAG, msg); 13626 throw new SecurityException(msg); 13627 } 13628 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13629 if (stickies != null) { 13630 ArrayList<Intent> list = stickies.get(intent.getAction()); 13631 if (list != null) { 13632 int N = list.size(); 13633 int i; 13634 for (i=0; i<N; i++) { 13635 if (intent.filterEquals(list.get(i))) { 13636 list.remove(i); 13637 break; 13638 } 13639 } 13640 if (list.size() <= 0) { 13641 stickies.remove(intent.getAction()); 13642 } 13643 } 13644 if (stickies.size() <= 0) { 13645 mStickyBroadcasts.remove(userId); 13646 } 13647 } 13648 } 13649 } 13650 13651 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13652 String resultData, Bundle resultExtras, boolean resultAbort) { 13653 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13654 if (r == null) { 13655 Slog.w(TAG, "finishReceiver called but not found on queue"); 13656 return false; 13657 } 13658 13659 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13660 } 13661 13662 void backgroundServicesFinishedLocked(int userId) { 13663 for (BroadcastQueue queue : mBroadcastQueues) { 13664 queue.backgroundServicesFinishedLocked(userId); 13665 } 13666 } 13667 13668 public void finishReceiver(IBinder who, int resultCode, String resultData, 13669 Bundle resultExtras, boolean resultAbort) { 13670 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13671 13672 // Refuse possible leaked file descriptors 13673 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13674 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13675 } 13676 13677 final long origId = Binder.clearCallingIdentity(); 13678 try { 13679 boolean doNext = false; 13680 BroadcastRecord r; 13681 13682 synchronized(this) { 13683 r = broadcastRecordForReceiverLocked(who); 13684 if (r != null) { 13685 doNext = r.queue.finishReceiverLocked(r, resultCode, 13686 resultData, resultExtras, resultAbort, true); 13687 } 13688 } 13689 13690 if (doNext) { 13691 r.queue.processNextBroadcast(false); 13692 } 13693 trimApplications(); 13694 } finally { 13695 Binder.restoreCallingIdentity(origId); 13696 } 13697 } 13698 13699 // ========================================================= 13700 // INSTRUMENTATION 13701 // ========================================================= 13702 13703 public boolean startInstrumentation(ComponentName className, 13704 String profileFile, int flags, Bundle arguments, 13705 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13706 int userId) { 13707 enforceNotIsolatedCaller("startInstrumentation"); 13708 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13709 userId, false, true, "startInstrumentation", null); 13710 // Refuse possible leaked file descriptors 13711 if (arguments != null && arguments.hasFileDescriptors()) { 13712 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13713 } 13714 13715 synchronized(this) { 13716 InstrumentationInfo ii = null; 13717 ApplicationInfo ai = null; 13718 try { 13719 ii = mContext.getPackageManager().getInstrumentationInfo( 13720 className, STOCK_PM_FLAGS); 13721 ai = AppGlobals.getPackageManager().getApplicationInfo( 13722 ii.targetPackage, STOCK_PM_FLAGS, userId); 13723 } catch (PackageManager.NameNotFoundException e) { 13724 } catch (RemoteException e) { 13725 } 13726 if (ii == null) { 13727 reportStartInstrumentationFailure(watcher, className, 13728 "Unable to find instrumentation info for: " + className); 13729 return false; 13730 } 13731 if (ai == null) { 13732 reportStartInstrumentationFailure(watcher, className, 13733 "Unable to find instrumentation target package: " + ii.targetPackage); 13734 return false; 13735 } 13736 13737 int match = mContext.getPackageManager().checkSignatures( 13738 ii.targetPackage, ii.packageName); 13739 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13740 String msg = "Permission Denial: starting instrumentation " 13741 + className + " from pid=" 13742 + Binder.getCallingPid() 13743 + ", uid=" + Binder.getCallingPid() 13744 + " not allowed because package " + ii.packageName 13745 + " does not have a signature matching the target " 13746 + ii.targetPackage; 13747 reportStartInstrumentationFailure(watcher, className, msg); 13748 throw new SecurityException(msg); 13749 } 13750 13751 final long origId = Binder.clearCallingIdentity(); 13752 // Instrumentation can kill and relaunch even persistent processes 13753 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId, 13754 "start instr"); 13755 ProcessRecord app = addAppLocked(ai, false); 13756 app.instrumentationClass = className; 13757 app.instrumentationInfo = ai; 13758 app.instrumentationProfileFile = profileFile; 13759 app.instrumentationArguments = arguments; 13760 app.instrumentationWatcher = watcher; 13761 app.instrumentationUiAutomationConnection = uiAutomationConnection; 13762 app.instrumentationResultClass = className; 13763 Binder.restoreCallingIdentity(origId); 13764 } 13765 13766 return true; 13767 } 13768 13769 /** 13770 * Report errors that occur while attempting to start Instrumentation. Always writes the 13771 * error to the logs, but if somebody is watching, send the report there too. This enables 13772 * the "am" command to report errors with more information. 13773 * 13774 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13775 * @param cn The component name of the instrumentation. 13776 * @param report The error report. 13777 */ 13778 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13779 ComponentName cn, String report) { 13780 Slog.w(TAG, report); 13781 try { 13782 if (watcher != null) { 13783 Bundle results = new Bundle(); 13784 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13785 results.putString("Error", report); 13786 watcher.instrumentationStatus(cn, -1, results); 13787 } 13788 } catch (RemoteException e) { 13789 Slog.w(TAG, e); 13790 } 13791 } 13792 13793 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13794 if (app.instrumentationWatcher != null) { 13795 try { 13796 // NOTE: IInstrumentationWatcher *must* be oneway here 13797 app.instrumentationWatcher.instrumentationFinished( 13798 app.instrumentationClass, 13799 resultCode, 13800 results); 13801 } catch (RemoteException e) { 13802 } 13803 } 13804 if (app.instrumentationUiAutomationConnection != null) { 13805 try { 13806 app.instrumentationUiAutomationConnection.shutdown(); 13807 } catch (RemoteException re) { 13808 /* ignore */ 13809 } 13810 // Only a UiAutomation can set this flag and now that 13811 // it is finished we make sure it is reset to its default. 13812 mUserIsMonkey = false; 13813 } 13814 app.instrumentationWatcher = null; 13815 app.instrumentationUiAutomationConnection = null; 13816 app.instrumentationClass = null; 13817 app.instrumentationInfo = null; 13818 app.instrumentationProfileFile = null; 13819 app.instrumentationArguments = null; 13820 13821 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId, 13822 "finished inst"); 13823 } 13824 13825 public void finishInstrumentation(IApplicationThread target, 13826 int resultCode, Bundle results) { 13827 int userId = UserHandle.getCallingUserId(); 13828 // Refuse possible leaked file descriptors 13829 if (results != null && results.hasFileDescriptors()) { 13830 throw new IllegalArgumentException("File descriptors passed in Intent"); 13831 } 13832 13833 synchronized(this) { 13834 ProcessRecord app = getRecordForAppLocked(target); 13835 if (app == null) { 13836 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13837 return; 13838 } 13839 final long origId = Binder.clearCallingIdentity(); 13840 finishInstrumentationLocked(app, resultCode, results); 13841 Binder.restoreCallingIdentity(origId); 13842 } 13843 } 13844 13845 // ========================================================= 13846 // CONFIGURATION 13847 // ========================================================= 13848 13849 public ConfigurationInfo getDeviceConfigurationInfo() { 13850 ConfigurationInfo config = new ConfigurationInfo(); 13851 synchronized (this) { 13852 config.reqTouchScreen = mConfiguration.touchscreen; 13853 config.reqKeyboardType = mConfiguration.keyboard; 13854 config.reqNavigation = mConfiguration.navigation; 13855 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13856 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13857 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13858 } 13859 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13860 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13861 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13862 } 13863 config.reqGlEsVersion = GL_ES_VERSION; 13864 } 13865 return config; 13866 } 13867 13868 ActivityStack getFocusedStack() { 13869 return mStackSupervisor.getFocusedStack(); 13870 } 13871 13872 public Configuration getConfiguration() { 13873 Configuration ci; 13874 synchronized(this) { 13875 ci = new Configuration(mConfiguration); 13876 } 13877 return ci; 13878 } 13879 13880 public void updatePersistentConfiguration(Configuration values) { 13881 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13882 "updateConfiguration()"); 13883 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 13884 "updateConfiguration()"); 13885 if (values == null) { 13886 throw new NullPointerException("Configuration must not be null"); 13887 } 13888 13889 synchronized(this) { 13890 final long origId = Binder.clearCallingIdentity(); 13891 updateConfigurationLocked(values, null, true, false); 13892 Binder.restoreCallingIdentity(origId); 13893 } 13894 } 13895 13896 public void updateConfiguration(Configuration values) { 13897 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13898 "updateConfiguration()"); 13899 13900 synchronized(this) { 13901 if (values == null && mWindowManager != null) { 13902 // sentinel: fetch the current configuration from the window manager 13903 values = mWindowManager.computeNewConfiguration(); 13904 } 13905 13906 if (mWindowManager != null) { 13907 mProcessList.applyDisplaySize(mWindowManager); 13908 } 13909 13910 final long origId = Binder.clearCallingIdentity(); 13911 if (values != null) { 13912 Settings.System.clearConfiguration(values); 13913 } 13914 updateConfigurationLocked(values, null, false, false); 13915 Binder.restoreCallingIdentity(origId); 13916 } 13917 } 13918 13919 /** 13920 * Do either or both things: (1) change the current configuration, and (2) 13921 * make sure the given activity is running with the (now) current 13922 * configuration. Returns true if the activity has been left running, or 13923 * false if <var>starting</var> is being destroyed to match the new 13924 * configuration. 13925 * @param persistent TODO 13926 */ 13927 boolean updateConfigurationLocked(Configuration values, 13928 ActivityRecord starting, boolean persistent, boolean initLocale) { 13929 int changes = 0; 13930 13931 if (values != null) { 13932 Configuration newConfig = new Configuration(mConfiguration); 13933 changes = newConfig.updateFrom(values); 13934 if (changes != 0) { 13935 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13936 Slog.i(TAG, "Updating configuration to: " + values); 13937 } 13938 13939 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 13940 13941 if (values.locale != null && !initLocale) { 13942 saveLocaleLocked(values.locale, 13943 !values.locale.equals(mConfiguration.locale), 13944 values.userSetLocale); 13945 } 13946 13947 mConfigurationSeq++; 13948 if (mConfigurationSeq <= 0) { 13949 mConfigurationSeq = 1; 13950 } 13951 newConfig.seq = mConfigurationSeq; 13952 mConfiguration = newConfig; 13953 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 13954 13955 final Configuration configCopy = new Configuration(mConfiguration); 13956 13957 // TODO: If our config changes, should we auto dismiss any currently 13958 // showing dialogs? 13959 mShowDialogs = shouldShowDialogs(newConfig); 13960 13961 AttributeCache ac = AttributeCache.instance(); 13962 if (ac != null) { 13963 ac.updateConfiguration(configCopy); 13964 } 13965 13966 // Make sure all resources in our process are updated 13967 // right now, so that anyone who is going to retrieve 13968 // resource values after we return will be sure to get 13969 // the new ones. This is especially important during 13970 // boot, where the first config change needs to guarantee 13971 // all resources have that config before following boot 13972 // code is executed. 13973 mSystemThread.applyConfigurationToResources(configCopy); 13974 13975 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 13976 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 13977 msg.obj = new Configuration(configCopy); 13978 mHandler.sendMessage(msg); 13979 } 13980 13981 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13982 ProcessRecord app = mLruProcesses.get(i); 13983 try { 13984 if (app.thread != null) { 13985 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 13986 + app.processName + " new config " + mConfiguration); 13987 app.thread.scheduleConfigurationChanged(configCopy); 13988 } 13989 } catch (Exception e) { 13990 } 13991 } 13992 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 13993 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 13994 | Intent.FLAG_RECEIVER_REPLACE_PENDING 13995 | Intent.FLAG_RECEIVER_FOREGROUND); 13996 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 13997 null, AppOpsManager.OP_NONE, false, false, MY_PID, 13998 Process.SYSTEM_UID, UserHandle.USER_ALL); 13999 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14000 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14001 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14002 broadcastIntentLocked(null, null, intent, 14003 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14004 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14005 } 14006 } 14007 } 14008 14009 boolean kept = true; 14010 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14011 // mainStack is null during startup. 14012 if (mainStack != null) { 14013 if (changes != 0 && starting == null) { 14014 // If the configuration changed, and the caller is not already 14015 // in the process of starting an activity, then find the top 14016 // activity to check if its configuration needs to change. 14017 starting = mainStack.topRunningActivityLocked(null); 14018 } 14019 14020 if (starting != null) { 14021 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14022 // And we need to make sure at this point that all other activities 14023 // are made visible with the correct configuration. 14024 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14025 } 14026 } 14027 14028 if (values != null && mWindowManager != null) { 14029 mWindowManager.setNewConfiguration(mConfiguration); 14030 } 14031 14032 return kept; 14033 } 14034 14035 /** 14036 * Decide based on the configuration whether we should shouw the ANR, 14037 * crash, etc dialogs. The idea is that if there is no affordnace to 14038 * press the on-screen buttons, we shouldn't show the dialog. 14039 * 14040 * A thought: SystemUI might also want to get told about this, the Power 14041 * dialog / global actions also might want different behaviors. 14042 */ 14043 private static final boolean shouldShowDialogs(Configuration config) { 14044 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14045 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14046 } 14047 14048 /** 14049 * Save the locale. You must be inside a synchronized (this) block. 14050 */ 14051 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14052 if(isDiff) { 14053 SystemProperties.set("user.language", l.getLanguage()); 14054 SystemProperties.set("user.region", l.getCountry()); 14055 } 14056 14057 if(isPersist) { 14058 SystemProperties.set("persist.sys.language", l.getLanguage()); 14059 SystemProperties.set("persist.sys.country", l.getCountry()); 14060 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14061 } 14062 } 14063 14064 @Override 14065 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14066 ActivityRecord srec = ActivityRecord.forToken(token); 14067 return srec != null && srec.task.affinity != null && 14068 srec.task.affinity.equals(destAffinity); 14069 } 14070 14071 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14072 Intent resultData) { 14073 14074 synchronized (this) { 14075 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14076 if (stack != null) { 14077 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14078 } 14079 return false; 14080 } 14081 } 14082 14083 public int getLaunchedFromUid(IBinder activityToken) { 14084 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14085 if (srec == null) { 14086 return -1; 14087 } 14088 return srec.launchedFromUid; 14089 } 14090 14091 public String getLaunchedFromPackage(IBinder activityToken) { 14092 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14093 if (srec == null) { 14094 return null; 14095 } 14096 return srec.launchedFromPackage; 14097 } 14098 14099 // ========================================================= 14100 // LIFETIME MANAGEMENT 14101 // ========================================================= 14102 14103 // Returns which broadcast queue the app is the current [or imminent] receiver 14104 // on, or 'null' if the app is not an active broadcast recipient. 14105 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14106 BroadcastRecord r = app.curReceiver; 14107 if (r != null) { 14108 return r.queue; 14109 } 14110 14111 // It's not the current receiver, but it might be starting up to become one 14112 synchronized (this) { 14113 for (BroadcastQueue queue : mBroadcastQueues) { 14114 r = queue.mPendingBroadcast; 14115 if (r != null && r.curApp == app) { 14116 // found it; report which queue it's in 14117 return queue; 14118 } 14119 } 14120 } 14121 14122 return null; 14123 } 14124 14125 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14126 boolean doingAll, long now) { 14127 if (mAdjSeq == app.adjSeq) { 14128 // This adjustment has already been computed. 14129 return app.curRawAdj; 14130 } 14131 14132 if (app.thread == null) { 14133 app.adjSeq = mAdjSeq; 14134 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14135 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14136 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14137 } 14138 14139 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14140 app.adjSource = null; 14141 app.adjTarget = null; 14142 app.empty = false; 14143 app.cached = false; 14144 14145 final int activitiesSize = app.activities.size(); 14146 14147 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14148 // The max adjustment doesn't allow this app to be anything 14149 // below foreground, so it is not worth doing work for it. 14150 app.adjType = "fixed"; 14151 app.adjSeq = mAdjSeq; 14152 app.curRawAdj = app.maxAdj; 14153 app.foregroundActivities = false; 14154 app.keeping = true; 14155 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14156 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14157 // System process can do UI, and when they do we want to have 14158 // them trim their memory after the user leaves the UI. To 14159 // facilitate this, here we need to determine whether or not it 14160 // is currently showing UI. 14161 app.systemNoUi = true; 14162 if (app == TOP_APP) { 14163 app.systemNoUi = false; 14164 } else if (activitiesSize > 0) { 14165 for (int j = 0; j < activitiesSize; j++) { 14166 final ActivityRecord r = app.activities.get(j); 14167 if (r.visible) { 14168 app.systemNoUi = false; 14169 } 14170 } 14171 } 14172 if (!app.systemNoUi) { 14173 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14174 } 14175 return (app.curAdj=app.maxAdj); 14176 } 14177 14178 app.keeping = false; 14179 app.systemNoUi = false; 14180 14181 // Determine the importance of the process, starting with most 14182 // important to least, and assign an appropriate OOM adjustment. 14183 int adj; 14184 int schedGroup; 14185 int procState; 14186 boolean foregroundActivities = false; 14187 boolean interesting = false; 14188 BroadcastQueue queue; 14189 if (app == TOP_APP) { 14190 // The last app on the list is the foreground app. 14191 adj = ProcessList.FOREGROUND_APP_ADJ; 14192 schedGroup = Process.THREAD_GROUP_DEFAULT; 14193 app.adjType = "top-activity"; 14194 foregroundActivities = true; 14195 interesting = true; 14196 procState = ActivityManager.PROCESS_STATE_TOP; 14197 } else if (app.instrumentationClass != null) { 14198 // Don't want to kill running instrumentation. 14199 adj = ProcessList.FOREGROUND_APP_ADJ; 14200 schedGroup = Process.THREAD_GROUP_DEFAULT; 14201 app.adjType = "instrumentation"; 14202 interesting = true; 14203 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14204 } else if ((queue = isReceivingBroadcast(app)) != null) { 14205 // An app that is currently receiving a broadcast also 14206 // counts as being in the foreground for OOM killer purposes. 14207 // It's placed in a sched group based on the nature of the 14208 // broadcast as reflected by which queue it's active in. 14209 adj = ProcessList.FOREGROUND_APP_ADJ; 14210 schedGroup = (queue == mFgBroadcastQueue) 14211 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14212 app.adjType = "broadcast"; 14213 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14214 } else if (app.executingServices.size() > 0) { 14215 // An app that is currently executing a service callback also 14216 // counts as being in the foreground. 14217 adj = ProcessList.FOREGROUND_APP_ADJ; 14218 schedGroup = app.execServicesFg ? 14219 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14220 app.adjType = "exec-service"; 14221 procState = ActivityManager.PROCESS_STATE_SERVICE; 14222 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14223 } else { 14224 // As far as we know the process is empty. We may change our mind later. 14225 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14226 // At this point we don't actually know the adjustment. Use the cached adj 14227 // value that the caller wants us to. 14228 adj = cachedAdj; 14229 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14230 app.cached = true; 14231 app.empty = true; 14232 app.adjType = "cch-empty"; 14233 } 14234 14235 // Examine all activities if not already foreground. 14236 if (!foregroundActivities && activitiesSize > 0) { 14237 for (int j = 0; j < activitiesSize; j++) { 14238 final ActivityRecord r = app.activities.get(j); 14239 if (r.app != app) { 14240 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14241 + app + "?!?"); 14242 continue; 14243 } 14244 if (r.visible) { 14245 // App has a visible activity; only upgrade adjustment. 14246 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14247 adj = ProcessList.VISIBLE_APP_ADJ; 14248 app.adjType = "visible"; 14249 } 14250 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14251 procState = ActivityManager.PROCESS_STATE_TOP; 14252 } 14253 schedGroup = Process.THREAD_GROUP_DEFAULT; 14254 app.cached = false; 14255 app.empty = false; 14256 foregroundActivities = true; 14257 break; 14258 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14259 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14260 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14261 app.adjType = "pausing"; 14262 } 14263 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14264 procState = ActivityManager.PROCESS_STATE_TOP; 14265 } 14266 schedGroup = Process.THREAD_GROUP_DEFAULT; 14267 app.cached = false; 14268 app.empty = false; 14269 foregroundActivities = true; 14270 } else if (r.state == ActivityState.STOPPING) { 14271 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14272 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14273 app.adjType = "stopping"; 14274 } 14275 // For the process state, we will at this point consider the 14276 // process to be cached. It will be cached either as an activity 14277 // or empty depending on whether the activity is finishing. We do 14278 // this so that we can treat the process as cached for purposes of 14279 // memory trimming (determing current memory level, trim command to 14280 // send to process) since there can be an arbitrary number of stopping 14281 // processes and they should soon all go into the cached state. 14282 if (!r.finishing) { 14283 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14284 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14285 } 14286 } 14287 app.cached = false; 14288 app.empty = false; 14289 foregroundActivities = true; 14290 } else { 14291 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14292 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14293 app.adjType = "cch-act"; 14294 } 14295 } 14296 } 14297 } 14298 14299 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14300 if (app.foregroundServices) { 14301 // The user is aware of this app, so make it visible. 14302 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14303 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14304 app.cached = false; 14305 app.adjType = "fg-service"; 14306 schedGroup = Process.THREAD_GROUP_DEFAULT; 14307 } else if (app.forcingToForeground != null) { 14308 // The user is aware of this app, so make it visible. 14309 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14310 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14311 app.cached = false; 14312 app.adjType = "force-fg"; 14313 app.adjSource = app.forcingToForeground; 14314 schedGroup = Process.THREAD_GROUP_DEFAULT; 14315 } 14316 } 14317 14318 if (app.foregroundServices) { 14319 interesting = true; 14320 } 14321 14322 if (app == mHeavyWeightProcess) { 14323 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14324 // We don't want to kill the current heavy-weight process. 14325 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14326 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14327 app.cached = false; 14328 app.adjType = "heavy"; 14329 } 14330 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14331 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14332 } 14333 } 14334 14335 if (app == mHomeProcess) { 14336 if (adj > ProcessList.HOME_APP_ADJ) { 14337 // This process is hosting what we currently consider to be the 14338 // home app, so we don't want to let it go into the background. 14339 adj = ProcessList.HOME_APP_ADJ; 14340 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14341 app.cached = false; 14342 app.adjType = "home"; 14343 } 14344 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14345 procState = ActivityManager.PROCESS_STATE_HOME; 14346 } 14347 } 14348 14349 if (app == mPreviousProcess && app.activities.size() > 0) { 14350 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14351 // This was the previous process that showed UI to the user. 14352 // We want to try to keep it around more aggressively, to give 14353 // a good experience around switching between two apps. 14354 adj = ProcessList.PREVIOUS_APP_ADJ; 14355 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14356 app.cached = false; 14357 app.adjType = "previous"; 14358 } 14359 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14360 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14361 } 14362 } 14363 14364 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14365 + " reason=" + app.adjType); 14366 14367 // By default, we use the computed adjustment. It may be changed if 14368 // there are applications dependent on our services or providers, but 14369 // this gives us a baseline and makes sure we don't get into an 14370 // infinite recursion. 14371 app.adjSeq = mAdjSeq; 14372 app.curRawAdj = adj; 14373 app.hasStartedServices = false; 14374 14375 if (mBackupTarget != null && app == mBackupTarget.app) { 14376 // If possible we want to avoid killing apps while they're being backed up 14377 if (adj > ProcessList.BACKUP_APP_ADJ) { 14378 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14379 adj = ProcessList.BACKUP_APP_ADJ; 14380 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14381 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14382 } 14383 app.adjType = "backup"; 14384 app.cached = false; 14385 } 14386 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14387 procState = ActivityManager.PROCESS_STATE_BACKUP; 14388 } 14389 } 14390 14391 boolean mayBeTop = false; 14392 14393 for (int is = app.services.size()-1; 14394 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14395 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14396 || procState > ActivityManager.PROCESS_STATE_TOP); 14397 is--) { 14398 ServiceRecord s = app.services.valueAt(is); 14399 if (s.startRequested) { 14400 app.hasStartedServices = true; 14401 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14402 procState = ActivityManager.PROCESS_STATE_SERVICE; 14403 } 14404 if (app.hasShownUi && app != mHomeProcess) { 14405 // If this process has shown some UI, let it immediately 14406 // go to the LRU list because it may be pretty heavy with 14407 // UI stuff. We'll tag it with a label just to help 14408 // debug and understand what is going on. 14409 if (adj > ProcessList.SERVICE_ADJ) { 14410 app.adjType = "cch-started-ui-services"; 14411 } 14412 } else { 14413 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14414 // This service has seen some activity within 14415 // recent memory, so we will keep its process ahead 14416 // of the background processes. 14417 if (adj > ProcessList.SERVICE_ADJ) { 14418 adj = ProcessList.SERVICE_ADJ; 14419 app.adjType = "started-services"; 14420 app.cached = false; 14421 } 14422 } 14423 // If we have let the service slide into the background 14424 // state, still have some text describing what it is doing 14425 // even though the service no longer has an impact. 14426 if (adj > ProcessList.SERVICE_ADJ) { 14427 app.adjType = "cch-started-services"; 14428 } 14429 } 14430 // Don't kill this process because it is doing work; it 14431 // has said it is doing work. 14432 app.keeping = true; 14433 } 14434 for (int conni = s.connections.size()-1; 14435 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14436 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14437 || procState > ActivityManager.PROCESS_STATE_TOP); 14438 conni--) { 14439 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14440 for (int i = 0; 14441 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14442 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14443 || procState > ActivityManager.PROCESS_STATE_TOP); 14444 i++) { 14445 // XXX should compute this based on the max of 14446 // all connected clients. 14447 ConnectionRecord cr = clist.get(i); 14448 if (cr.binding.client == app) { 14449 // Binding to ourself is not interesting. 14450 continue; 14451 } 14452 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14453 ProcessRecord client = cr.binding.client; 14454 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14455 TOP_APP, doingAll, now); 14456 int clientProcState = client.curProcState; 14457 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14458 // If the other app is cached for any reason, for purposes here 14459 // we are going to consider it empty. The specific cached state 14460 // doesn't propagate except under certain conditions. 14461 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14462 } 14463 String adjType = null; 14464 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14465 // Not doing bind OOM management, so treat 14466 // this guy more like a started service. 14467 if (app.hasShownUi && app != mHomeProcess) { 14468 // If this process has shown some UI, let it immediately 14469 // go to the LRU list because it may be pretty heavy with 14470 // UI stuff. We'll tag it with a label just to help 14471 // debug and understand what is going on. 14472 if (adj > clientAdj) { 14473 adjType = "cch-bound-ui-services"; 14474 } 14475 app.cached = false; 14476 clientAdj = adj; 14477 clientProcState = procState; 14478 } else { 14479 if (now >= (s.lastActivity 14480 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14481 // This service has not seen activity within 14482 // recent memory, so allow it to drop to the 14483 // LRU list if there is no other reason to keep 14484 // it around. We'll also tag it with a label just 14485 // to help debug and undertand what is going on. 14486 if (adj > clientAdj) { 14487 adjType = "cch-bound-services"; 14488 } 14489 clientAdj = adj; 14490 } 14491 } 14492 } 14493 if (adj > clientAdj) { 14494 // If this process has recently shown UI, and 14495 // the process that is binding to it is less 14496 // important than being visible, then we don't 14497 // care about the binding as much as we care 14498 // about letting this process get into the LRU 14499 // list to be killed and restarted if needed for 14500 // memory. 14501 if (app.hasShownUi && app != mHomeProcess 14502 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14503 adjType = "cch-bound-ui-services"; 14504 } else { 14505 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14506 |Context.BIND_IMPORTANT)) != 0) { 14507 adj = clientAdj; 14508 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14509 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14510 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14511 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14512 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14513 adj = clientAdj; 14514 } else { 14515 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14516 adj = ProcessList.VISIBLE_APP_ADJ; 14517 } 14518 } 14519 if (!client.cached) { 14520 app.cached = false; 14521 } 14522 if (client.keeping) { 14523 app.keeping = true; 14524 } 14525 adjType = "service"; 14526 } 14527 } 14528 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14529 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14530 schedGroup = Process.THREAD_GROUP_DEFAULT; 14531 } 14532 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14533 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14534 // Special handling of clients who are in the top state. 14535 // We *may* want to consider this process to be in the 14536 // top state as well, but only if there is not another 14537 // reason for it to be running. Being on the top is a 14538 // special state, meaning you are specifically running 14539 // for the current top app. If the process is already 14540 // running in the background for some other reason, it 14541 // is more important to continue considering it to be 14542 // in the background state. 14543 mayBeTop = true; 14544 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14545 } else { 14546 // Special handling for above-top states (persistent 14547 // processes). These should not bring the current process 14548 // into the top state, since they are not on top. Instead 14549 // give them the best state after that. 14550 clientProcState = 14551 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14552 } 14553 } 14554 } else { 14555 if (clientProcState < 14556 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14557 clientProcState = 14558 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14559 } 14560 } 14561 if (procState > clientProcState) { 14562 procState = clientProcState; 14563 } 14564 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14565 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14566 app.pendingUiClean = true; 14567 } 14568 if (adjType != null) { 14569 app.adjType = adjType; 14570 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14571 .REASON_SERVICE_IN_USE; 14572 app.adjSource = cr.binding.client; 14573 app.adjSourceOom = clientAdj; 14574 app.adjTarget = s.name; 14575 } 14576 } 14577 final ActivityRecord a = cr.activity; 14578 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14579 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14580 (a.visible || a.state == ActivityState.RESUMED 14581 || a.state == ActivityState.PAUSING)) { 14582 adj = ProcessList.FOREGROUND_APP_ADJ; 14583 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14584 schedGroup = Process.THREAD_GROUP_DEFAULT; 14585 } 14586 app.cached = false; 14587 app.adjType = "service"; 14588 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14589 .REASON_SERVICE_IN_USE; 14590 app.adjSource = a; 14591 app.adjSourceOom = adj; 14592 app.adjTarget = s.name; 14593 } 14594 } 14595 } 14596 } 14597 } 14598 14599 for (int provi = app.pubProviders.size()-1; 14600 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14601 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14602 || procState > ActivityManager.PROCESS_STATE_TOP); 14603 provi--) { 14604 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14605 for (int i = cpr.connections.size()-1; 14606 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14607 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14608 || procState > ActivityManager.PROCESS_STATE_TOP); 14609 i--) { 14610 ContentProviderConnection conn = cpr.connections.get(i); 14611 ProcessRecord client = conn.client; 14612 if (client == app) { 14613 // Being our own client is not interesting. 14614 continue; 14615 } 14616 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14617 int clientProcState = client.curProcState; 14618 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14619 // If the other app is cached for any reason, for purposes here 14620 // we are going to consider it empty. 14621 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14622 } 14623 if (adj > clientAdj) { 14624 if (app.hasShownUi && app != mHomeProcess 14625 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14626 app.adjType = "cch-ui-provider"; 14627 } else { 14628 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14629 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14630 app.adjType = "provider"; 14631 } 14632 app.cached &= client.cached; 14633 app.keeping |= client.keeping; 14634 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14635 .REASON_PROVIDER_IN_USE; 14636 app.adjSource = client; 14637 app.adjSourceOom = clientAdj; 14638 app.adjTarget = cpr.name; 14639 } 14640 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14641 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14642 // Special handling of clients who are in the top state. 14643 // We *may* want to consider this process to be in the 14644 // top state as well, but only if there is not another 14645 // reason for it to be running. Being on the top is a 14646 // special state, meaning you are specifically running 14647 // for the current top app. If the process is already 14648 // running in the background for some other reason, it 14649 // is more important to continue considering it to be 14650 // in the background state. 14651 mayBeTop = true; 14652 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14653 } else { 14654 // Special handling for above-top states (persistent 14655 // processes). These should not bring the current process 14656 // into the top state, since they are not on top. Instead 14657 // give them the best state after that. 14658 clientProcState = 14659 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14660 } 14661 } 14662 if (procState > clientProcState) { 14663 procState = clientProcState; 14664 } 14665 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14666 schedGroup = Process.THREAD_GROUP_DEFAULT; 14667 } 14668 } 14669 // If the provider has external (non-framework) process 14670 // dependencies, ensure that its adjustment is at least 14671 // FOREGROUND_APP_ADJ. 14672 if (cpr.hasExternalProcessHandles()) { 14673 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14674 adj = ProcessList.FOREGROUND_APP_ADJ; 14675 schedGroup = Process.THREAD_GROUP_DEFAULT; 14676 app.cached = false; 14677 app.keeping = true; 14678 app.adjType = "provider"; 14679 app.adjTarget = cpr.name; 14680 } 14681 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14682 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14683 } 14684 } 14685 } 14686 14687 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14688 // A client of one of our services or providers is in the top state. We 14689 // *may* want to be in the top state, but not if we are already running in 14690 // the background for some other reason. For the decision here, we are going 14691 // to pick out a few specific states that we want to remain in when a client 14692 // is top (states that tend to be longer-term) and otherwise allow it to go 14693 // to the top state. 14694 switch (procState) { 14695 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14696 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14697 case ActivityManager.PROCESS_STATE_SERVICE: 14698 // These all are longer-term states, so pull them up to the top 14699 // of the background states, but not all the way to the top state. 14700 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14701 break; 14702 default: 14703 // Otherwise, top is a better choice, so take it. 14704 procState = ActivityManager.PROCESS_STATE_TOP; 14705 break; 14706 } 14707 } 14708 14709 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14710 // This is a cached process, but with client activities. Mark it so. 14711 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14712 app.adjType = "cch-client-act"; 14713 } 14714 14715 if (adj == ProcessList.SERVICE_ADJ) { 14716 if (doingAll) { 14717 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14718 mNewNumServiceProcs++; 14719 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14720 if (!app.serviceb) { 14721 // This service isn't far enough down on the LRU list to 14722 // normally be a B service, but if we are low on RAM and it 14723 // is large we want to force it down since we would prefer to 14724 // keep launcher over it. 14725 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 14726 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 14727 app.serviceHighRam = true; 14728 app.serviceb = true; 14729 //Slog.i(TAG, "ADJ " + app + " high ram!"); 14730 } else { 14731 mNewNumAServiceProcs++; 14732 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 14733 } 14734 } else { 14735 app.serviceHighRam = false; 14736 } 14737 } 14738 if (app.serviceb) { 14739 adj = ProcessList.SERVICE_B_ADJ; 14740 } 14741 } 14742 14743 app.curRawAdj = adj; 14744 14745 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14746 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14747 if (adj > app.maxAdj) { 14748 adj = app.maxAdj; 14749 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14750 schedGroup = Process.THREAD_GROUP_DEFAULT; 14751 } 14752 } 14753 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 14754 app.keeping = true; 14755 } 14756 14757 // Do final modification to adj. Everything we do between here and applying 14758 // the final setAdj must be done in this function, because we will also use 14759 // it when computing the final cached adj later. Note that we don't need to 14760 // worry about this for max adj above, since max adj will always be used to 14761 // keep it out of the cached vaues. 14762 adj = app.modifyRawOomAdj(adj); 14763 14764 app.curProcState = procState; 14765 14766 int importance = app.memImportance; 14767 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14768 app.curAdj = adj; 14769 app.curSchedGroup = schedGroup; 14770 if (!interesting) { 14771 // For this reporting, if there is not something explicitly 14772 // interesting in this process then we will push it to the 14773 // background importance. 14774 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14775 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 14776 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14777 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14778 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14779 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14780 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14781 } else if (adj >= ProcessList.SERVICE_ADJ) { 14782 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14783 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14784 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14785 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14786 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14787 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14788 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14789 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14790 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14791 } else { 14792 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14793 } 14794 } 14795 14796 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14797 if (foregroundActivities != app.foregroundActivities) { 14798 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14799 } 14800 if (changes != 0) { 14801 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14802 app.memImportance = importance; 14803 app.foregroundActivities = foregroundActivities; 14804 int i = mPendingProcessChanges.size()-1; 14805 ProcessChangeItem item = null; 14806 while (i >= 0) { 14807 item = mPendingProcessChanges.get(i); 14808 if (item.pid == app.pid) { 14809 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14810 break; 14811 } 14812 i--; 14813 } 14814 if (i < 0) { 14815 // No existing item in pending changes; need a new one. 14816 final int NA = mAvailProcessChanges.size(); 14817 if (NA > 0) { 14818 item = mAvailProcessChanges.remove(NA-1); 14819 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14820 } else { 14821 item = new ProcessChangeItem(); 14822 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14823 } 14824 item.changes = 0; 14825 item.pid = app.pid; 14826 item.uid = app.info.uid; 14827 if (mPendingProcessChanges.size() == 0) { 14828 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14829 "*** Enqueueing dispatch processes changed!"); 14830 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14831 } 14832 mPendingProcessChanges.add(item); 14833 } 14834 item.changes |= changes; 14835 item.importance = importance; 14836 item.foregroundActivities = foregroundActivities; 14837 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14838 + Integer.toHexString(System.identityHashCode(item)) 14839 + " " + app.toShortString() + ": changes=" + item.changes 14840 + " importance=" + item.importance 14841 + " foreground=" + item.foregroundActivities 14842 + " type=" + app.adjType + " source=" + app.adjSource 14843 + " target=" + app.adjTarget); 14844 } 14845 14846 return app.curRawAdj; 14847 } 14848 14849 /** 14850 * Schedule PSS collection of a process. 14851 */ 14852 void requestPssLocked(ProcessRecord proc, int procState) { 14853 if (mPendingPssProcesses.contains(proc)) { 14854 return; 14855 } 14856 if (mPendingPssProcesses.size() == 0) { 14857 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14858 } 14859 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 14860 proc.pssProcState = procState; 14861 mPendingPssProcesses.add(proc); 14862 } 14863 14864 /** 14865 * Schedule PSS collection of all processes. 14866 */ 14867 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 14868 if (!always) { 14869 if (now < (mLastFullPssTime + 14870 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 14871 return; 14872 } 14873 } 14874 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 14875 mLastFullPssTime = now; 14876 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 14877 mPendingPssProcesses.clear(); 14878 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14879 ProcessRecord app = mLruProcesses.get(i); 14880 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 14881 app.pssProcState = app.setProcState; 14882 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 14883 mSleeping, now); 14884 mPendingPssProcesses.add(app); 14885 } 14886 } 14887 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14888 } 14889 14890 /** 14891 * Ask a given process to GC right now. 14892 */ 14893 final void performAppGcLocked(ProcessRecord app) { 14894 try { 14895 app.lastRequestedGc = SystemClock.uptimeMillis(); 14896 if (app.thread != null) { 14897 if (app.reportLowMemory) { 14898 app.reportLowMemory = false; 14899 app.thread.scheduleLowMemory(); 14900 } else { 14901 app.thread.processInBackground(); 14902 } 14903 } 14904 } catch (Exception e) { 14905 // whatever. 14906 } 14907 } 14908 14909 /** 14910 * Returns true if things are idle enough to perform GCs. 14911 */ 14912 private final boolean canGcNowLocked() { 14913 boolean processingBroadcasts = false; 14914 for (BroadcastQueue q : mBroadcastQueues) { 14915 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 14916 processingBroadcasts = true; 14917 } 14918 } 14919 return !processingBroadcasts 14920 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 14921 } 14922 14923 /** 14924 * Perform GCs on all processes that are waiting for it, but only 14925 * if things are idle. 14926 */ 14927 final void performAppGcsLocked() { 14928 final int N = mProcessesToGc.size(); 14929 if (N <= 0) { 14930 return; 14931 } 14932 if (canGcNowLocked()) { 14933 while (mProcessesToGc.size() > 0) { 14934 ProcessRecord proc = mProcessesToGc.remove(0); 14935 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 14936 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 14937 <= SystemClock.uptimeMillis()) { 14938 // To avoid spamming the system, we will GC processes one 14939 // at a time, waiting a few seconds between each. 14940 performAppGcLocked(proc); 14941 scheduleAppGcsLocked(); 14942 return; 14943 } else { 14944 // It hasn't been long enough since we last GCed this 14945 // process... put it in the list to wait for its time. 14946 addProcessToGcListLocked(proc); 14947 break; 14948 } 14949 } 14950 } 14951 14952 scheduleAppGcsLocked(); 14953 } 14954 } 14955 14956 /** 14957 * If all looks good, perform GCs on all processes waiting for them. 14958 */ 14959 final void performAppGcsIfAppropriateLocked() { 14960 if (canGcNowLocked()) { 14961 performAppGcsLocked(); 14962 return; 14963 } 14964 // Still not idle, wait some more. 14965 scheduleAppGcsLocked(); 14966 } 14967 14968 /** 14969 * Schedule the execution of all pending app GCs. 14970 */ 14971 final void scheduleAppGcsLocked() { 14972 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 14973 14974 if (mProcessesToGc.size() > 0) { 14975 // Schedule a GC for the time to the next process. 14976 ProcessRecord proc = mProcessesToGc.get(0); 14977 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 14978 14979 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 14980 long now = SystemClock.uptimeMillis(); 14981 if (when < (now+GC_TIMEOUT)) { 14982 when = now + GC_TIMEOUT; 14983 } 14984 mHandler.sendMessageAtTime(msg, when); 14985 } 14986 } 14987 14988 /** 14989 * Add a process to the array of processes waiting to be GCed. Keeps the 14990 * list in sorted order by the last GC time. The process can't already be 14991 * on the list. 14992 */ 14993 final void addProcessToGcListLocked(ProcessRecord proc) { 14994 boolean added = false; 14995 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 14996 if (mProcessesToGc.get(i).lastRequestedGc < 14997 proc.lastRequestedGc) { 14998 added = true; 14999 mProcessesToGc.add(i+1, proc); 15000 break; 15001 } 15002 } 15003 if (!added) { 15004 mProcessesToGc.add(0, proc); 15005 } 15006 } 15007 15008 /** 15009 * Set up to ask a process to GC itself. This will either do it 15010 * immediately, or put it on the list of processes to gc the next 15011 * time things are idle. 15012 */ 15013 final void scheduleAppGcLocked(ProcessRecord app) { 15014 long now = SystemClock.uptimeMillis(); 15015 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15016 return; 15017 } 15018 if (!mProcessesToGc.contains(app)) { 15019 addProcessToGcListLocked(app); 15020 scheduleAppGcsLocked(); 15021 } 15022 } 15023 15024 final void checkExcessivePowerUsageLocked(boolean doKills) { 15025 updateCpuStatsNow(); 15026 15027 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15028 boolean doWakeKills = doKills; 15029 boolean doCpuKills = doKills; 15030 if (mLastPowerCheckRealtime == 0) { 15031 doWakeKills = false; 15032 } 15033 if (mLastPowerCheckUptime == 0) { 15034 doCpuKills = false; 15035 } 15036 if (stats.isScreenOn()) { 15037 doWakeKills = false; 15038 } 15039 final long curRealtime = SystemClock.elapsedRealtime(); 15040 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15041 final long curUptime = SystemClock.uptimeMillis(); 15042 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15043 mLastPowerCheckRealtime = curRealtime; 15044 mLastPowerCheckUptime = curUptime; 15045 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15046 doWakeKills = false; 15047 } 15048 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15049 doCpuKills = false; 15050 } 15051 int i = mLruProcesses.size(); 15052 while (i > 0) { 15053 i--; 15054 ProcessRecord app = mLruProcesses.get(i); 15055 if (!app.keeping) { 15056 long wtime; 15057 synchronized (stats) { 15058 wtime = stats.getProcessWakeTime(app.info.uid, 15059 app.pid, curRealtime); 15060 } 15061 long wtimeUsed = wtime - app.lastWakeTime; 15062 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15063 if (DEBUG_POWER) { 15064 StringBuilder sb = new StringBuilder(128); 15065 sb.append("Wake for "); 15066 app.toShortString(sb); 15067 sb.append(": over "); 15068 TimeUtils.formatDuration(realtimeSince, sb); 15069 sb.append(" used "); 15070 TimeUtils.formatDuration(wtimeUsed, sb); 15071 sb.append(" ("); 15072 sb.append((wtimeUsed*100)/realtimeSince); 15073 sb.append("%)"); 15074 Slog.i(TAG, sb.toString()); 15075 sb.setLength(0); 15076 sb.append("CPU for "); 15077 app.toShortString(sb); 15078 sb.append(": over "); 15079 TimeUtils.formatDuration(uptimeSince, sb); 15080 sb.append(" used "); 15081 TimeUtils.formatDuration(cputimeUsed, sb); 15082 sb.append(" ("); 15083 sb.append((cputimeUsed*100)/uptimeSince); 15084 sb.append("%)"); 15085 Slog.i(TAG, sb.toString()); 15086 } 15087 // If a process has held a wake lock for more 15088 // than 50% of the time during this period, 15089 // that sounds bad. Kill! 15090 if (doWakeKills && realtimeSince > 0 15091 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15092 synchronized (stats) { 15093 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15094 realtimeSince, wtimeUsed); 15095 } 15096 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15097 + " during " + realtimeSince); 15098 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15099 } else if (doCpuKills && uptimeSince > 0 15100 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15101 synchronized (stats) { 15102 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15103 uptimeSince, cputimeUsed); 15104 } 15105 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15106 + " during " + uptimeSince); 15107 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15108 } else { 15109 app.lastWakeTime = wtime; 15110 app.lastCpuTime = app.curCpuTime; 15111 } 15112 } 15113 } 15114 } 15115 15116 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15117 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15118 boolean success = true; 15119 15120 if (app.curRawAdj != app.setRawAdj) { 15121 if (wasKeeping && !app.keeping) { 15122 // This app is no longer something we want to keep. Note 15123 // its current wake lock time to later know to kill it if 15124 // it is not behaving well. 15125 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15126 synchronized (stats) { 15127 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15128 app.pid, SystemClock.elapsedRealtime()); 15129 } 15130 app.lastCpuTime = app.curCpuTime; 15131 } 15132 15133 app.setRawAdj = app.curRawAdj; 15134 } 15135 15136 if (app.curAdj != app.setAdj) { 15137 ProcessList.setOomAdj(app.pid, app.curAdj); 15138 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15139 TAG, "Set " + app.pid + " " + app.processName + 15140 " adj " + app.curAdj + ": " + app.adjType); 15141 app.setAdj = app.curAdj; 15142 } 15143 15144 if (app.setSchedGroup != app.curSchedGroup) { 15145 app.setSchedGroup = app.curSchedGroup; 15146 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15147 "Setting process group of " + app.processName 15148 + " to " + app.curSchedGroup); 15149 if (app.waitingToKill != null && 15150 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15151 killUnneededProcessLocked(app, app.waitingToKill); 15152 success = false; 15153 } else { 15154 if (true) { 15155 long oldId = Binder.clearCallingIdentity(); 15156 try { 15157 Process.setProcessGroup(app.pid, app.curSchedGroup); 15158 } catch (Exception e) { 15159 Slog.w(TAG, "Failed setting process group of " + app.pid 15160 + " to " + app.curSchedGroup); 15161 e.printStackTrace(); 15162 } finally { 15163 Binder.restoreCallingIdentity(oldId); 15164 } 15165 } else { 15166 if (app.thread != null) { 15167 try { 15168 app.thread.setSchedulingGroup(app.curSchedGroup); 15169 } catch (RemoteException e) { 15170 } 15171 } 15172 } 15173 Process.setSwappiness(app.pid, 15174 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15175 } 15176 } 15177 if (app.repProcState != app.curProcState) { 15178 app.repProcState = app.curProcState; 15179 if (!reportingProcessState && app.thread != null) { 15180 try { 15181 if (false) { 15182 //RuntimeException h = new RuntimeException("here"); 15183 Slog.i(TAG, "Sending new process state " + app.repProcState 15184 + " to " + app /*, h*/); 15185 } 15186 app.thread.setProcessState(app.repProcState); 15187 } catch (RemoteException e) { 15188 } 15189 } 15190 } 15191 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15192 app.setProcState)) { 15193 app.lastStateTime = now; 15194 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15195 mSleeping, now); 15196 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15197 + ProcessList.makeProcStateString(app.setProcState) + " to " 15198 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15199 + (app.nextPssTime-now) + ": " + app); 15200 } else { 15201 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15202 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15203 requestPssLocked(app, app.setProcState); 15204 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15205 mSleeping, now); 15206 } else if (false && DEBUG_PSS) { 15207 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15208 } 15209 } 15210 if (app.setProcState != app.curProcState) { 15211 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15212 "Proc state change of " + app.processName 15213 + " to " + app.curProcState); 15214 app.setProcState = app.curProcState; 15215 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15216 app.notCachedSinceIdle = false; 15217 } 15218 if (!doingAll) { 15219 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15220 } else { 15221 app.procStateChanged = true; 15222 } 15223 } 15224 return success; 15225 } 15226 15227 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15228 if (proc.thread != null && proc.baseProcessTracker != null) { 15229 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15230 } 15231 } 15232 15233 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15234 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15235 if (app.thread == null) { 15236 return false; 15237 } 15238 15239 final boolean wasKeeping = app.keeping; 15240 15241 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15242 15243 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15244 reportingProcessState, now); 15245 } 15246 15247 private final ActivityRecord resumedAppLocked() { 15248 return mStackSupervisor.resumedAppLocked(); 15249 } 15250 15251 final boolean updateOomAdjLocked(ProcessRecord app) { 15252 return updateOomAdjLocked(app, false); 15253 } 15254 15255 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15256 final ActivityRecord TOP_ACT = resumedAppLocked(); 15257 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15258 final boolean wasCached = app.cached; 15259 15260 mAdjSeq++; 15261 15262 // This is the desired cached adjusment we want to tell it to use. 15263 // If our app is currently cached, we know it, and that is it. Otherwise, 15264 // we don't know it yet, and it needs to now be cached we will then 15265 // need to do a complete oom adj. 15266 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15267 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15268 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15269 SystemClock.uptimeMillis()); 15270 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15271 // Changed to/from cached state, so apps after it in the LRU 15272 // list may also be changed. 15273 updateOomAdjLocked(); 15274 } 15275 return success; 15276 } 15277 15278 final void updateOomAdjLocked() { 15279 final ActivityRecord TOP_ACT = resumedAppLocked(); 15280 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15281 final long now = SystemClock.uptimeMillis(); 15282 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15283 final int N = mLruProcesses.size(); 15284 15285 if (false) { 15286 RuntimeException e = new RuntimeException(); 15287 e.fillInStackTrace(); 15288 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15289 } 15290 15291 mAdjSeq++; 15292 mNewNumServiceProcs = 0; 15293 mNewNumAServiceProcs = 0; 15294 15295 final int emptyProcessLimit; 15296 final int cachedProcessLimit; 15297 if (mProcessLimit <= 0) { 15298 emptyProcessLimit = cachedProcessLimit = 0; 15299 } else if (mProcessLimit == 1) { 15300 emptyProcessLimit = 1; 15301 cachedProcessLimit = 0; 15302 } else { 15303 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15304 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15305 } 15306 15307 // Let's determine how many processes we have running vs. 15308 // how many slots we have for background processes; we may want 15309 // to put multiple processes in a slot of there are enough of 15310 // them. 15311 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15312 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15313 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15314 if (numEmptyProcs > cachedProcessLimit) { 15315 // If there are more empty processes than our limit on cached 15316 // processes, then use the cached process limit for the factor. 15317 // This ensures that the really old empty processes get pushed 15318 // down to the bottom, so if we are running low on memory we will 15319 // have a better chance at keeping around more cached processes 15320 // instead of a gazillion empty processes. 15321 numEmptyProcs = cachedProcessLimit; 15322 } 15323 int emptyFactor = numEmptyProcs/numSlots; 15324 if (emptyFactor < 1) emptyFactor = 1; 15325 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15326 if (cachedFactor < 1) cachedFactor = 1; 15327 int stepCached = 0; 15328 int stepEmpty = 0; 15329 int numCached = 0; 15330 int numEmpty = 0; 15331 int numTrimming = 0; 15332 15333 mNumNonCachedProcs = 0; 15334 mNumCachedHiddenProcs = 0; 15335 15336 // First update the OOM adjustment for each of the 15337 // application processes based on their current state. 15338 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15339 int nextCachedAdj = curCachedAdj+1; 15340 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15341 int nextEmptyAdj = curEmptyAdj+2; 15342 for (int i=N-1; i>=0; i--) { 15343 ProcessRecord app = mLruProcesses.get(i); 15344 if (!app.killedByAm && app.thread != null) { 15345 app.procStateChanged = false; 15346 final boolean wasKeeping = app.keeping; 15347 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15348 15349 // If we haven't yet assigned the final cached adj 15350 // to the process, do that now. 15351 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15352 switch (app.curProcState) { 15353 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15354 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15355 // This process is a cached process holding activities... 15356 // assign it the next cached value for that type, and then 15357 // step that cached level. 15358 app.curRawAdj = curCachedAdj; 15359 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15360 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15361 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15362 + ")"); 15363 if (curCachedAdj != nextCachedAdj) { 15364 stepCached++; 15365 if (stepCached >= cachedFactor) { 15366 stepCached = 0; 15367 curCachedAdj = nextCachedAdj; 15368 nextCachedAdj += 2; 15369 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15370 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15371 } 15372 } 15373 } 15374 break; 15375 default: 15376 // For everything else, assign next empty cached process 15377 // level and bump that up. Note that this means that 15378 // long-running services that have dropped down to the 15379 // cached level will be treated as empty (since their process 15380 // state is still as a service), which is what we want. 15381 app.curRawAdj = curEmptyAdj; 15382 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15383 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15384 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15385 + ")"); 15386 if (curEmptyAdj != nextEmptyAdj) { 15387 stepEmpty++; 15388 if (stepEmpty >= emptyFactor) { 15389 stepEmpty = 0; 15390 curEmptyAdj = nextEmptyAdj; 15391 nextEmptyAdj += 2; 15392 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15393 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15394 } 15395 } 15396 } 15397 break; 15398 } 15399 } 15400 15401 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15402 15403 // Count the number of process types. 15404 switch (app.curProcState) { 15405 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15406 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15407 mNumCachedHiddenProcs++; 15408 numCached++; 15409 if (numCached > cachedProcessLimit) { 15410 killUnneededProcessLocked(app, "cached #" + numCached); 15411 } 15412 break; 15413 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15414 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15415 && app.lastActivityTime < oldTime) { 15416 killUnneededProcessLocked(app, "empty for " 15417 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15418 / 1000) + "s"); 15419 } else { 15420 numEmpty++; 15421 if (numEmpty > emptyProcessLimit) { 15422 killUnneededProcessLocked(app, "empty #" + numEmpty); 15423 } 15424 } 15425 break; 15426 default: 15427 mNumNonCachedProcs++; 15428 break; 15429 } 15430 15431 if (app.isolated && app.services.size() <= 0) { 15432 // If this is an isolated process, and there are no 15433 // services running in it, then the process is no longer 15434 // needed. We agressively kill these because we can by 15435 // definition not re-use the same process again, and it is 15436 // good to avoid having whatever code was running in them 15437 // left sitting around after no longer needed. 15438 killUnneededProcessLocked(app, "isolated not needed"); 15439 } 15440 15441 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15442 && !app.killedByAm) { 15443 numTrimming++; 15444 } 15445 } 15446 } 15447 15448 mNumServiceProcs = mNewNumServiceProcs; 15449 15450 // Now determine the memory trimming level of background processes. 15451 // Unfortunately we need to start at the back of the list to do this 15452 // properly. We only do this if the number of background apps we 15453 // are managing to keep around is less than half the maximum we desire; 15454 // if we are keeping a good number around, we'll let them use whatever 15455 // memory they want. 15456 final int numCachedAndEmpty = numCached + numEmpty; 15457 int memFactor; 15458 if (numCached <= ProcessList.TRIM_CACHED_APPS 15459 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15460 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15461 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15462 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15463 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15464 } else { 15465 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15466 } 15467 } else { 15468 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15469 } 15470 // We always allow the memory level to go up (better). We only allow it to go 15471 // down if we are in a state where that is allowed, *and* the total number of processes 15472 // has gone down since last time. 15473 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15474 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15475 + " last=" + mLastNumProcesses); 15476 if (memFactor > mLastMemoryLevel) { 15477 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15478 memFactor = mLastMemoryLevel; 15479 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15480 } 15481 } 15482 mLastMemoryLevel = memFactor; 15483 mLastNumProcesses = mLruProcesses.size(); 15484 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15485 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15486 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15487 if (mLowRamStartTime == 0) { 15488 mLowRamStartTime = now; 15489 } 15490 int step = 0; 15491 int fgTrimLevel; 15492 switch (memFactor) { 15493 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15494 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15495 break; 15496 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15497 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15498 break; 15499 default: 15500 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15501 break; 15502 } 15503 int factor = numTrimming/3; 15504 int minFactor = 2; 15505 if (mHomeProcess != null) minFactor++; 15506 if (mPreviousProcess != null) minFactor++; 15507 if (factor < minFactor) factor = minFactor; 15508 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15509 for (int i=N-1; i>=0; i--) { 15510 ProcessRecord app = mLruProcesses.get(i); 15511 if (allChanged || app.procStateChanged) { 15512 setProcessTrackerState(app, trackerMemFactor, now); 15513 app.procStateChanged = false; 15514 } 15515 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15516 && !app.killedByAm) { 15517 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15518 try { 15519 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15520 "Trimming memory of " + app.processName 15521 + " to " + curLevel); 15522 app.thread.scheduleTrimMemory(curLevel); 15523 } catch (RemoteException e) { 15524 } 15525 if (false) { 15526 // For now we won't do this; our memory trimming seems 15527 // to be good enough at this point that destroying 15528 // activities causes more harm than good. 15529 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15530 && app != mHomeProcess && app != mPreviousProcess) { 15531 // Need to do this on its own message because the stack may not 15532 // be in a consistent state at this point. 15533 // For these apps we will also finish their activities 15534 // to help them free memory. 15535 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15536 } 15537 } 15538 } 15539 app.trimMemoryLevel = curLevel; 15540 step++; 15541 if (step >= factor) { 15542 step = 0; 15543 switch (curLevel) { 15544 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15545 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15546 break; 15547 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15548 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15549 break; 15550 } 15551 } 15552 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15553 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15554 && app.thread != null) { 15555 try { 15556 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15557 "Trimming memory of heavy-weight " + app.processName 15558 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15559 app.thread.scheduleTrimMemory( 15560 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15561 } catch (RemoteException e) { 15562 } 15563 } 15564 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15565 } else { 15566 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15567 || app.systemNoUi) && app.pendingUiClean) { 15568 // If this application is now in the background and it 15569 // had done UI, then give it the special trim level to 15570 // have it free UI resources. 15571 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15572 if (app.trimMemoryLevel < level && app.thread != null) { 15573 try { 15574 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15575 "Trimming memory of bg-ui " + app.processName 15576 + " to " + level); 15577 app.thread.scheduleTrimMemory(level); 15578 } catch (RemoteException e) { 15579 } 15580 } 15581 app.pendingUiClean = false; 15582 } 15583 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15584 try { 15585 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15586 "Trimming memory of fg " + app.processName 15587 + " to " + fgTrimLevel); 15588 app.thread.scheduleTrimMemory(fgTrimLevel); 15589 } catch (RemoteException e) { 15590 } 15591 } 15592 app.trimMemoryLevel = fgTrimLevel; 15593 } 15594 } 15595 } else { 15596 if (mLowRamStartTime != 0) { 15597 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15598 mLowRamStartTime = 0; 15599 } 15600 for (int i=N-1; i>=0; i--) { 15601 ProcessRecord app = mLruProcesses.get(i); 15602 if (allChanged || app.procStateChanged) { 15603 setProcessTrackerState(app, trackerMemFactor, now); 15604 app.procStateChanged = false; 15605 } 15606 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15607 || app.systemNoUi) && app.pendingUiClean) { 15608 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15609 && app.thread != null) { 15610 try { 15611 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15612 "Trimming memory of ui hidden " + app.processName 15613 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15614 app.thread.scheduleTrimMemory( 15615 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15616 } catch (RemoteException e) { 15617 } 15618 } 15619 app.pendingUiClean = false; 15620 } 15621 app.trimMemoryLevel = 0; 15622 } 15623 } 15624 15625 if (mAlwaysFinishActivities) { 15626 // Need to do this on its own message because the stack may not 15627 // be in a consistent state at this point. 15628 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15629 } 15630 15631 if (allChanged) { 15632 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15633 } 15634 15635 if (mProcessStats.shouldWriteNowLocked(now)) { 15636 mHandler.post(new Runnable() { 15637 @Override public void run() { 15638 synchronized (ActivityManagerService.this) { 15639 mProcessStats.writeStateAsyncLocked(); 15640 } 15641 } 15642 }); 15643 } 15644 15645 if (DEBUG_OOM_ADJ) { 15646 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15647 } 15648 } 15649 15650 final void trimApplications() { 15651 synchronized (this) { 15652 int i; 15653 15654 // First remove any unused application processes whose package 15655 // has been removed. 15656 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15657 final ProcessRecord app = mRemovedProcesses.get(i); 15658 if (app.activities.size() == 0 15659 && app.curReceiver == null && app.services.size() == 0) { 15660 Slog.i( 15661 TAG, "Exiting empty application process " 15662 + app.processName + " (" 15663 + (app.thread != null ? app.thread.asBinder() : null) 15664 + ")\n"); 15665 if (app.pid > 0 && app.pid != MY_PID) { 15666 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 15667 app.processName, app.setAdj, "empty"); 15668 app.killedByAm = true; 15669 Process.killProcessQuiet(app.pid); 15670 } else { 15671 try { 15672 app.thread.scheduleExit(); 15673 } catch (Exception e) { 15674 // Ignore exceptions. 15675 } 15676 } 15677 cleanUpApplicationRecordLocked(app, false, true, -1); 15678 mRemovedProcesses.remove(i); 15679 15680 if (app.persistent) { 15681 if (app.persistent) { 15682 addAppLocked(app.info, false); 15683 } 15684 } 15685 } 15686 } 15687 15688 // Now update the oom adj for all processes. 15689 updateOomAdjLocked(); 15690 } 15691 } 15692 15693 /** This method sends the specified signal to each of the persistent apps */ 15694 public void signalPersistentProcesses(int sig) throws RemoteException { 15695 if (sig != Process.SIGNAL_USR1) { 15696 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 15697 } 15698 15699 synchronized (this) { 15700 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 15701 != PackageManager.PERMISSION_GRANTED) { 15702 throw new SecurityException("Requires permission " 15703 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 15704 } 15705 15706 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15707 ProcessRecord r = mLruProcesses.get(i); 15708 if (r.thread != null && r.persistent) { 15709 Process.sendSignal(r.pid, sig); 15710 } 15711 } 15712 } 15713 } 15714 15715 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 15716 if (proc == null || proc == mProfileProc) { 15717 proc = mProfileProc; 15718 path = mProfileFile; 15719 profileType = mProfileType; 15720 clearProfilerLocked(); 15721 } 15722 if (proc == null) { 15723 return; 15724 } 15725 try { 15726 proc.thread.profilerControl(false, path, null, profileType); 15727 } catch (RemoteException e) { 15728 throw new IllegalStateException("Process disappeared"); 15729 } 15730 } 15731 15732 private void clearProfilerLocked() { 15733 if (mProfileFd != null) { 15734 try { 15735 mProfileFd.close(); 15736 } catch (IOException e) { 15737 } 15738 } 15739 mProfileApp = null; 15740 mProfileProc = null; 15741 mProfileFile = null; 15742 mProfileType = 0; 15743 mAutoStopProfiler = false; 15744 } 15745 15746 public boolean profileControl(String process, int userId, boolean start, 15747 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 15748 15749 try { 15750 synchronized (this) { 15751 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15752 // its own permission. 15753 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15754 != PackageManager.PERMISSION_GRANTED) { 15755 throw new SecurityException("Requires permission " 15756 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15757 } 15758 15759 if (start && fd == null) { 15760 throw new IllegalArgumentException("null fd"); 15761 } 15762 15763 ProcessRecord proc = null; 15764 if (process != null) { 15765 proc = findProcessLocked(process, userId, "profileControl"); 15766 } 15767 15768 if (start && (proc == null || proc.thread == null)) { 15769 throw new IllegalArgumentException("Unknown process: " + process); 15770 } 15771 15772 if (start) { 15773 stopProfilerLocked(null, null, 0); 15774 setProfileApp(proc.info, proc.processName, path, fd, false); 15775 mProfileProc = proc; 15776 mProfileType = profileType; 15777 try { 15778 fd = fd.dup(); 15779 } catch (IOException e) { 15780 fd = null; 15781 } 15782 proc.thread.profilerControl(start, path, fd, profileType); 15783 fd = null; 15784 mProfileFd = null; 15785 } else { 15786 stopProfilerLocked(proc, path, profileType); 15787 if (fd != null) { 15788 try { 15789 fd.close(); 15790 } catch (IOException e) { 15791 } 15792 } 15793 } 15794 15795 return true; 15796 } 15797 } catch (RemoteException e) { 15798 throw new IllegalStateException("Process disappeared"); 15799 } finally { 15800 if (fd != null) { 15801 try { 15802 fd.close(); 15803 } catch (IOException e) { 15804 } 15805 } 15806 } 15807 } 15808 15809 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 15810 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15811 userId, true, true, callName, null); 15812 ProcessRecord proc = null; 15813 try { 15814 int pid = Integer.parseInt(process); 15815 synchronized (mPidsSelfLocked) { 15816 proc = mPidsSelfLocked.get(pid); 15817 } 15818 } catch (NumberFormatException e) { 15819 } 15820 15821 if (proc == null) { 15822 ArrayMap<String, SparseArray<ProcessRecord>> all 15823 = mProcessNames.getMap(); 15824 SparseArray<ProcessRecord> procs = all.get(process); 15825 if (procs != null && procs.size() > 0) { 15826 proc = procs.valueAt(0); 15827 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 15828 for (int i=1; i<procs.size(); i++) { 15829 ProcessRecord thisProc = procs.valueAt(i); 15830 if (thisProc.userId == userId) { 15831 proc = thisProc; 15832 break; 15833 } 15834 } 15835 } 15836 } 15837 } 15838 15839 return proc; 15840 } 15841 15842 public boolean dumpHeap(String process, int userId, boolean managed, 15843 String path, ParcelFileDescriptor fd) throws RemoteException { 15844 15845 try { 15846 synchronized (this) { 15847 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15848 // its own permission (same as profileControl). 15849 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15850 != PackageManager.PERMISSION_GRANTED) { 15851 throw new SecurityException("Requires permission " 15852 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15853 } 15854 15855 if (fd == null) { 15856 throw new IllegalArgumentException("null fd"); 15857 } 15858 15859 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 15860 if (proc == null || proc.thread == null) { 15861 throw new IllegalArgumentException("Unknown process: " + process); 15862 } 15863 15864 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 15865 if (!isDebuggable) { 15866 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 15867 throw new SecurityException("Process not debuggable: " + proc); 15868 } 15869 } 15870 15871 proc.thread.dumpHeap(managed, path, fd); 15872 fd = null; 15873 return true; 15874 } 15875 } catch (RemoteException e) { 15876 throw new IllegalStateException("Process disappeared"); 15877 } finally { 15878 if (fd != null) { 15879 try { 15880 fd.close(); 15881 } catch (IOException e) { 15882 } 15883 } 15884 } 15885 } 15886 15887 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 15888 public void monitor() { 15889 synchronized (this) { } 15890 } 15891 15892 void onCoreSettingsChange(Bundle settings) { 15893 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 15894 ProcessRecord processRecord = mLruProcesses.get(i); 15895 try { 15896 if (processRecord.thread != null) { 15897 processRecord.thread.setCoreSettings(settings); 15898 } 15899 } catch (RemoteException re) { 15900 /* ignore */ 15901 } 15902 } 15903 } 15904 15905 // Multi-user methods 15906 15907 @Override 15908 public boolean switchUser(final int userId) { 15909 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 15910 != PackageManager.PERMISSION_GRANTED) { 15911 String msg = "Permission Denial: switchUser() from pid=" 15912 + Binder.getCallingPid() 15913 + ", uid=" + Binder.getCallingUid() 15914 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 15915 Slog.w(TAG, msg); 15916 throw new SecurityException(msg); 15917 } 15918 15919 final long ident = Binder.clearCallingIdentity(); 15920 try { 15921 synchronized (this) { 15922 final int oldUserId = mCurrentUserId; 15923 if (oldUserId == userId) { 15924 return true; 15925 } 15926 15927 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 15928 if (userInfo == null) { 15929 Slog.w(TAG, "No user info for user #" + userId); 15930 return false; 15931 } 15932 15933 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 15934 R.anim.screen_user_enter); 15935 15936 boolean needStart = false; 15937 15938 // If the user we are switching to is not currently started, then 15939 // we need to start it now. 15940 if (mStartedUsers.get(userId) == null) { 15941 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 15942 updateStartedUserArrayLocked(); 15943 needStart = true; 15944 } 15945 15946 mCurrentUserId = userId; 15947 final Integer userIdInt = Integer.valueOf(userId); 15948 mUserLru.remove(userIdInt); 15949 mUserLru.add(userIdInt); 15950 15951 mWindowManager.setCurrentUser(userId); 15952 15953 // Once the internal notion of the active user has switched, we lock the device 15954 // with the option to show the user switcher on the keyguard. 15955 mWindowManager.lockNow(null); 15956 15957 final UserStartedState uss = mStartedUsers.get(userId); 15958 15959 // Make sure user is in the started state. If it is currently 15960 // stopping, we need to knock that off. 15961 if (uss.mState == UserStartedState.STATE_STOPPING) { 15962 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 15963 // so we can just fairly silently bring the user back from 15964 // the almost-dead. 15965 uss.mState = UserStartedState.STATE_RUNNING; 15966 updateStartedUserArrayLocked(); 15967 needStart = true; 15968 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 15969 // This means ACTION_SHUTDOWN has been sent, so we will 15970 // need to treat this as a new boot of the user. 15971 uss.mState = UserStartedState.STATE_BOOTING; 15972 updateStartedUserArrayLocked(); 15973 needStart = true; 15974 } 15975 15976 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 15977 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 15978 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 15979 oldUserId, userId, uss)); 15980 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 15981 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 15982 if (needStart) { 15983 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 15984 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15985 | Intent.FLAG_RECEIVER_FOREGROUND); 15986 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 15987 broadcastIntentLocked(null, null, intent, 15988 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15989 false, false, MY_PID, Process.SYSTEM_UID, userId); 15990 } 15991 15992 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 15993 if (userId != 0) { 15994 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 15995 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 15996 broadcastIntentLocked(null, null, intent, null, 15997 new IIntentReceiver.Stub() { 15998 public void performReceive(Intent intent, int resultCode, 15999 String data, Bundle extras, boolean ordered, 16000 boolean sticky, int sendingUser) { 16001 userInitialized(uss, userId); 16002 } 16003 }, 0, null, null, null, AppOpsManager.OP_NONE, 16004 true, false, MY_PID, Process.SYSTEM_UID, 16005 userId); 16006 uss.initializing = true; 16007 } else { 16008 getUserManagerLocked().makeInitialized(userInfo.id); 16009 } 16010 } 16011 16012 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16013 if (homeInFront) { 16014 startHomeActivityLocked(userId); 16015 } else { 16016 mStackSupervisor.resumeTopActivitiesLocked(); 16017 } 16018 16019 EventLogTags.writeAmSwitchUser(userId); 16020 getUserManagerLocked().userForeground(userId); 16021 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16022 if (needStart) { 16023 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16024 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16025 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16026 broadcastIntentLocked(null, null, intent, 16027 null, new IIntentReceiver.Stub() { 16028 @Override 16029 public void performReceive(Intent intent, int resultCode, String data, 16030 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16031 throws RemoteException { 16032 } 16033 }, 0, null, null, 16034 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16035 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16036 } 16037 } 16038 } finally { 16039 Binder.restoreCallingIdentity(ident); 16040 } 16041 16042 return true; 16043 } 16044 16045 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16046 long ident = Binder.clearCallingIdentity(); 16047 try { 16048 Intent intent; 16049 if (oldUserId >= 0) { 16050 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16051 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16052 | Intent.FLAG_RECEIVER_FOREGROUND); 16053 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16054 broadcastIntentLocked(null, null, intent, 16055 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16056 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16057 } 16058 if (newUserId >= 0) { 16059 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16060 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16061 | Intent.FLAG_RECEIVER_FOREGROUND); 16062 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16063 broadcastIntentLocked(null, null, intent, 16064 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16065 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16066 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16067 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16068 | Intent.FLAG_RECEIVER_FOREGROUND); 16069 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16070 broadcastIntentLocked(null, null, intent, 16071 null, null, 0, null, null, 16072 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16073 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16074 } 16075 } finally { 16076 Binder.restoreCallingIdentity(ident); 16077 } 16078 } 16079 16080 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16081 final int newUserId) { 16082 final int N = mUserSwitchObservers.beginBroadcast(); 16083 if (N > 0) { 16084 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16085 int mCount = 0; 16086 @Override 16087 public void sendResult(Bundle data) throws RemoteException { 16088 synchronized (ActivityManagerService.this) { 16089 if (mCurUserSwitchCallback == this) { 16090 mCount++; 16091 if (mCount == N) { 16092 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16093 } 16094 } 16095 } 16096 } 16097 }; 16098 synchronized (this) { 16099 uss.switching = true; 16100 mCurUserSwitchCallback = callback; 16101 } 16102 for (int i=0; i<N; i++) { 16103 try { 16104 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16105 newUserId, callback); 16106 } catch (RemoteException e) { 16107 } 16108 } 16109 } else { 16110 synchronized (this) { 16111 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16112 } 16113 } 16114 mUserSwitchObservers.finishBroadcast(); 16115 } 16116 16117 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16118 synchronized (this) { 16119 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16120 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16121 } 16122 } 16123 16124 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16125 mCurUserSwitchCallback = null; 16126 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16127 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16128 oldUserId, newUserId, uss)); 16129 } 16130 16131 void userInitialized(UserStartedState uss, int newUserId) { 16132 completeSwitchAndInitalize(uss, newUserId, true, false); 16133 } 16134 16135 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16136 completeSwitchAndInitalize(uss, newUserId, false, true); 16137 } 16138 16139 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16140 boolean clearInitializing, boolean clearSwitching) { 16141 boolean unfrozen = false; 16142 synchronized (this) { 16143 if (clearInitializing) { 16144 uss.initializing = false; 16145 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16146 } 16147 if (clearSwitching) { 16148 uss.switching = false; 16149 } 16150 if (!uss.switching && !uss.initializing) { 16151 mWindowManager.stopFreezingScreen(); 16152 unfrozen = true; 16153 } 16154 } 16155 if (unfrozen) { 16156 final int N = mUserSwitchObservers.beginBroadcast(); 16157 for (int i=0; i<N; i++) { 16158 try { 16159 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16160 } catch (RemoteException e) { 16161 } 16162 } 16163 mUserSwitchObservers.finishBroadcast(); 16164 } 16165 } 16166 16167 void finishUserSwitch(UserStartedState uss) { 16168 synchronized (this) { 16169 if (uss.mState == UserStartedState.STATE_BOOTING 16170 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16171 uss.mState = UserStartedState.STATE_RUNNING; 16172 final int userId = uss.mHandle.getIdentifier(); 16173 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16174 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16175 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16176 broadcastIntentLocked(null, null, intent, 16177 null, null, 0, null, null, 16178 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16179 true, false, MY_PID, Process.SYSTEM_UID, userId); 16180 } 16181 int num = mUserLru.size(); 16182 int i = 0; 16183 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16184 Integer oldUserId = mUserLru.get(i); 16185 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16186 if (oldUss == null) { 16187 // Shouldn't happen, but be sane if it does. 16188 mUserLru.remove(i); 16189 num--; 16190 continue; 16191 } 16192 if (oldUss.mState == UserStartedState.STATE_STOPPING 16193 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16194 // This user is already stopping, doesn't count. 16195 num--; 16196 i++; 16197 continue; 16198 } 16199 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16200 // Owner and current can't be stopped, but count as running. 16201 i++; 16202 continue; 16203 } 16204 // This is a user to be stopped. 16205 stopUserLocked(oldUserId, null); 16206 num--; 16207 i++; 16208 } 16209 } 16210 } 16211 16212 @Override 16213 public int stopUser(final int userId, final IStopUserCallback callback) { 16214 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16215 != PackageManager.PERMISSION_GRANTED) { 16216 String msg = "Permission Denial: switchUser() from pid=" 16217 + Binder.getCallingPid() 16218 + ", uid=" + Binder.getCallingUid() 16219 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16220 Slog.w(TAG, msg); 16221 throw new SecurityException(msg); 16222 } 16223 if (userId <= 0) { 16224 throw new IllegalArgumentException("Can't stop primary user " + userId); 16225 } 16226 synchronized (this) { 16227 return stopUserLocked(userId, callback); 16228 } 16229 } 16230 16231 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16232 if (mCurrentUserId == userId) { 16233 return ActivityManager.USER_OP_IS_CURRENT; 16234 } 16235 16236 final UserStartedState uss = mStartedUsers.get(userId); 16237 if (uss == null) { 16238 // User is not started, nothing to do... but we do need to 16239 // callback if requested. 16240 if (callback != null) { 16241 mHandler.post(new Runnable() { 16242 @Override 16243 public void run() { 16244 try { 16245 callback.userStopped(userId); 16246 } catch (RemoteException e) { 16247 } 16248 } 16249 }); 16250 } 16251 return ActivityManager.USER_OP_SUCCESS; 16252 } 16253 16254 if (callback != null) { 16255 uss.mStopCallbacks.add(callback); 16256 } 16257 16258 if (uss.mState != UserStartedState.STATE_STOPPING 16259 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16260 uss.mState = UserStartedState.STATE_STOPPING; 16261 updateStartedUserArrayLocked(); 16262 16263 long ident = Binder.clearCallingIdentity(); 16264 try { 16265 // We are going to broadcast ACTION_USER_STOPPING and then 16266 // once that is done send a final ACTION_SHUTDOWN and then 16267 // stop the user. 16268 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16269 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16270 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16271 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16272 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16273 // This is the result receiver for the final shutdown broadcast. 16274 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16275 @Override 16276 public void performReceive(Intent intent, int resultCode, String data, 16277 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16278 finishUserStop(uss); 16279 } 16280 }; 16281 // This is the result receiver for the initial stopping broadcast. 16282 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16283 @Override 16284 public void performReceive(Intent intent, int resultCode, String data, 16285 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16286 // On to the next. 16287 synchronized (ActivityManagerService.this) { 16288 if (uss.mState != UserStartedState.STATE_STOPPING) { 16289 // Whoops, we are being started back up. Abort, abort! 16290 return; 16291 } 16292 uss.mState = UserStartedState.STATE_SHUTDOWN; 16293 } 16294 broadcastIntentLocked(null, null, shutdownIntent, 16295 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16296 true, false, MY_PID, Process.SYSTEM_UID, userId); 16297 } 16298 }; 16299 // Kick things off. 16300 broadcastIntentLocked(null, null, stoppingIntent, 16301 null, stoppingReceiver, 0, null, null, 16302 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16303 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16304 } finally { 16305 Binder.restoreCallingIdentity(ident); 16306 } 16307 } 16308 16309 return ActivityManager.USER_OP_SUCCESS; 16310 } 16311 16312 void finishUserStop(UserStartedState uss) { 16313 final int userId = uss.mHandle.getIdentifier(); 16314 boolean stopped; 16315 ArrayList<IStopUserCallback> callbacks; 16316 synchronized (this) { 16317 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16318 if (mStartedUsers.get(userId) != uss) { 16319 stopped = false; 16320 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16321 stopped = false; 16322 } else { 16323 stopped = true; 16324 // User can no longer run. 16325 mStartedUsers.remove(userId); 16326 mUserLru.remove(Integer.valueOf(userId)); 16327 updateStartedUserArrayLocked(); 16328 16329 // Clean up all state and processes associated with the user. 16330 // Kill all the processes for the user. 16331 forceStopUserLocked(userId, "finish user"); 16332 } 16333 } 16334 16335 for (int i=0; i<callbacks.size(); i++) { 16336 try { 16337 if (stopped) callbacks.get(i).userStopped(userId); 16338 else callbacks.get(i).userStopAborted(userId); 16339 } catch (RemoteException e) { 16340 } 16341 } 16342 16343 mStackSupervisor.removeUserLocked(userId); 16344 } 16345 16346 @Override 16347 public UserInfo getCurrentUser() { 16348 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16349 != PackageManager.PERMISSION_GRANTED) && ( 16350 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16351 != PackageManager.PERMISSION_GRANTED)) { 16352 String msg = "Permission Denial: getCurrentUser() from pid=" 16353 + Binder.getCallingPid() 16354 + ", uid=" + Binder.getCallingUid() 16355 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16356 Slog.w(TAG, msg); 16357 throw new SecurityException(msg); 16358 } 16359 synchronized (this) { 16360 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16361 } 16362 } 16363 16364 int getCurrentUserIdLocked() { 16365 return mCurrentUserId; 16366 } 16367 16368 @Override 16369 public boolean isUserRunning(int userId, boolean orStopped) { 16370 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16371 != PackageManager.PERMISSION_GRANTED) { 16372 String msg = "Permission Denial: isUserRunning() from pid=" 16373 + Binder.getCallingPid() 16374 + ", uid=" + Binder.getCallingUid() 16375 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16376 Slog.w(TAG, msg); 16377 throw new SecurityException(msg); 16378 } 16379 synchronized (this) { 16380 return isUserRunningLocked(userId, orStopped); 16381 } 16382 } 16383 16384 boolean isUserRunningLocked(int userId, boolean orStopped) { 16385 UserStartedState state = mStartedUsers.get(userId); 16386 if (state == null) { 16387 return false; 16388 } 16389 if (orStopped) { 16390 return true; 16391 } 16392 return state.mState != UserStartedState.STATE_STOPPING 16393 && state.mState != UserStartedState.STATE_SHUTDOWN; 16394 } 16395 16396 @Override 16397 public int[] getRunningUserIds() { 16398 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16399 != PackageManager.PERMISSION_GRANTED) { 16400 String msg = "Permission Denial: isUserRunning() 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 mStartedUserArray; 16409 } 16410 } 16411 16412 private void updateStartedUserArrayLocked() { 16413 int num = 0; 16414 for (int i=0; i<mStartedUsers.size(); i++) { 16415 UserStartedState uss = mStartedUsers.valueAt(i); 16416 // This list does not include stopping users. 16417 if (uss.mState != UserStartedState.STATE_STOPPING 16418 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16419 num++; 16420 } 16421 } 16422 mStartedUserArray = new int[num]; 16423 num = 0; 16424 for (int i=0; i<mStartedUsers.size(); i++) { 16425 UserStartedState uss = mStartedUsers.valueAt(i); 16426 if (uss.mState != UserStartedState.STATE_STOPPING 16427 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16428 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16429 num++; 16430 } 16431 } 16432 } 16433 16434 @Override 16435 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16436 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16437 != PackageManager.PERMISSION_GRANTED) { 16438 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16439 + Binder.getCallingPid() 16440 + ", uid=" + Binder.getCallingUid() 16441 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16442 Slog.w(TAG, msg); 16443 throw new SecurityException(msg); 16444 } 16445 16446 mUserSwitchObservers.register(observer); 16447 } 16448 16449 @Override 16450 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16451 mUserSwitchObservers.unregister(observer); 16452 } 16453 16454 private boolean userExists(int userId) { 16455 if (userId == 0) { 16456 return true; 16457 } 16458 UserManagerService ums = getUserManagerLocked(); 16459 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16460 } 16461 16462 int[] getUsersLocked() { 16463 UserManagerService ums = getUserManagerLocked(); 16464 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16465 } 16466 16467 UserManagerService getUserManagerLocked() { 16468 if (mUserManager == null) { 16469 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16470 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16471 } 16472 return mUserManager; 16473 } 16474 16475 private int applyUserId(int uid, int userId) { 16476 return UserHandle.getUid(userId, uid); 16477 } 16478 16479 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16480 if (info == null) return null; 16481 ApplicationInfo newInfo = new ApplicationInfo(info); 16482 newInfo.uid = applyUserId(info.uid, userId); 16483 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16484 + info.packageName; 16485 return newInfo; 16486 } 16487 16488 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16489 if (aInfo == null 16490 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16491 return aInfo; 16492 } 16493 16494 ActivityInfo info = new ActivityInfo(aInfo); 16495 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16496 return info; 16497 } 16498 16499 private final class LocalService extends ActivityManagerInternal { 16500 @Override 16501 public void goingToSleep() { 16502 ActivityManagerService.this.goingToSleep(); 16503 } 16504 16505 @Override 16506 public void wakingUp() { 16507 ActivityManagerService.this.wakingUp(); 16508 } 16509 } 16510} 16511