ActivityManagerService.java revision f4c909bcb87d6f103c9f9e8255fa61bd86f4de67
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 if (callback == null) { 7082 throw new IllegalArgumentException("callback must not be null"); 7083 } 7084 return mStackSupervisor.createActivityContainer(r, callback); 7085 } 7086 } 7087 7088 @Override 7089 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7090 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7091 "deleteActivityContainer()"); 7092 synchronized (this) { 7093 mStackSupervisor.deleteActivityContainer(container); 7094 } 7095 } 7096 7097 @Override 7098 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7099 throws RemoteException { 7100 synchronized (this) { 7101 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7102 if (stack != null) { 7103 return stack.mActivityContainer; 7104 } 7105 return null; 7106 } 7107 } 7108 7109 @Override 7110 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7111 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7112 "moveTaskToStack()"); 7113 if (stackId == HOME_STACK_ID) { 7114 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7115 new RuntimeException("here").fillInStackTrace()); 7116 } 7117 synchronized (this) { 7118 long ident = Binder.clearCallingIdentity(); 7119 try { 7120 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7121 + stackId + " toTop=" + toTop); 7122 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7123 } finally { 7124 Binder.restoreCallingIdentity(ident); 7125 } 7126 } 7127 } 7128 7129 @Override 7130 public void resizeStack(int stackBoxId, Rect bounds) { 7131 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7132 "resizeStackBox()"); 7133 long ident = Binder.clearCallingIdentity(); 7134 try { 7135 mWindowManager.resizeStack(stackBoxId, bounds); 7136 } finally { 7137 Binder.restoreCallingIdentity(ident); 7138 } 7139 } 7140 7141 @Override 7142 public List<StackInfo> getAllStackInfos() { 7143 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7144 "getAllStackInfos()"); 7145 long ident = Binder.clearCallingIdentity(); 7146 try { 7147 synchronized (this) { 7148 return mStackSupervisor.getAllStackInfosLocked(); 7149 } 7150 } finally { 7151 Binder.restoreCallingIdentity(ident); 7152 } 7153 } 7154 7155 @Override 7156 public StackInfo getStackInfo(int stackId) { 7157 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7158 "getStackInfo()"); 7159 long ident = Binder.clearCallingIdentity(); 7160 try { 7161 synchronized (this) { 7162 return mStackSupervisor.getStackInfoLocked(stackId); 7163 } 7164 } finally { 7165 Binder.restoreCallingIdentity(ident); 7166 } 7167 } 7168 7169 @Override 7170 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7171 synchronized(this) { 7172 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7173 } 7174 } 7175 7176 // ========================================================= 7177 // THUMBNAILS 7178 // ========================================================= 7179 7180 public void reportThumbnail(IBinder token, 7181 Bitmap thumbnail, CharSequence description) { 7182 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7183 final long origId = Binder.clearCallingIdentity(); 7184 sendPendingThumbnail(null, token, thumbnail, description, true); 7185 Binder.restoreCallingIdentity(origId); 7186 } 7187 7188 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7189 Bitmap thumbnail, CharSequence description, boolean always) { 7190 TaskRecord task; 7191 ArrayList<PendingThumbnailsRecord> receivers = null; 7192 7193 //System.out.println("Send pending thumbnail: " + r); 7194 7195 synchronized(this) { 7196 if (r == null) { 7197 r = ActivityRecord.isInStackLocked(token); 7198 if (r == null) { 7199 return; 7200 } 7201 } 7202 if (thumbnail == null && r.thumbHolder != null) { 7203 thumbnail = r.thumbHolder.lastThumbnail; 7204 description = r.thumbHolder.lastDescription; 7205 } 7206 if (thumbnail == null && !always) { 7207 // If there is no thumbnail, and this entry is not actually 7208 // going away, then abort for now and pick up the next 7209 // thumbnail we get. 7210 return; 7211 } 7212 task = r.task; 7213 7214 int N = mPendingThumbnails.size(); 7215 int i=0; 7216 while (i<N) { 7217 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7218 //System.out.println("Looking in " + pr.pendingRecords); 7219 if (pr.pendingRecords.remove(r)) { 7220 if (receivers == null) { 7221 receivers = new ArrayList<PendingThumbnailsRecord>(); 7222 } 7223 receivers.add(pr); 7224 if (pr.pendingRecords.size() == 0) { 7225 pr.finished = true; 7226 mPendingThumbnails.remove(i); 7227 N--; 7228 continue; 7229 } 7230 } 7231 i++; 7232 } 7233 } 7234 7235 if (receivers != null) { 7236 final int N = receivers.size(); 7237 for (int i=0; i<N; i++) { 7238 try { 7239 PendingThumbnailsRecord pr = receivers.get(i); 7240 pr.receiver.newThumbnail( 7241 task != null ? task.taskId : -1, thumbnail, description); 7242 if (pr.finished) { 7243 pr.receiver.finished(); 7244 } 7245 } catch (Exception e) { 7246 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7247 } 7248 } 7249 } 7250 } 7251 7252 // ========================================================= 7253 // CONTENT PROVIDERS 7254 // ========================================================= 7255 7256 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7257 List<ProviderInfo> providers = null; 7258 try { 7259 providers = AppGlobals.getPackageManager(). 7260 queryContentProviders(app.processName, app.uid, 7261 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7262 } catch (RemoteException ex) { 7263 } 7264 if (DEBUG_MU) 7265 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7266 int userId = app.userId; 7267 if (providers != null) { 7268 int N = providers.size(); 7269 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7270 for (int i=0; i<N; i++) { 7271 ProviderInfo cpi = 7272 (ProviderInfo)providers.get(i); 7273 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7274 cpi.name, cpi.flags); 7275 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7276 // This is a singleton provider, but a user besides the 7277 // default user is asking to initialize a process it runs 7278 // in... well, no, it doesn't actually run in this process, 7279 // it runs in the process of the default user. Get rid of it. 7280 providers.remove(i); 7281 N--; 7282 i--; 7283 continue; 7284 } 7285 7286 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7287 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7288 if (cpr == null) { 7289 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7290 mProviderMap.putProviderByClass(comp, cpr); 7291 } 7292 if (DEBUG_MU) 7293 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7294 app.pubProviders.put(cpi.name, cpr); 7295 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7296 // Don't add this if it is a platform component that is marked 7297 // to run in multiple processes, because this is actually 7298 // part of the framework so doesn't make sense to track as a 7299 // separate apk in the process. 7300 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7301 } 7302 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7303 } 7304 } 7305 return providers; 7306 } 7307 7308 /** 7309 * Check if {@link ProcessRecord} has a possible chance at accessing the 7310 * given {@link ProviderInfo}. Final permission checking is always done 7311 * in {@link ContentProvider}. 7312 */ 7313 private final String checkContentProviderPermissionLocked( 7314 ProviderInfo cpi, ProcessRecord r) { 7315 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7316 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7317 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7318 cpi.applicationInfo.uid, cpi.exported) 7319 == PackageManager.PERMISSION_GRANTED) { 7320 return null; 7321 } 7322 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7323 cpi.applicationInfo.uid, cpi.exported) 7324 == PackageManager.PERMISSION_GRANTED) { 7325 return null; 7326 } 7327 7328 PathPermission[] pps = cpi.pathPermissions; 7329 if (pps != null) { 7330 int i = pps.length; 7331 while (i > 0) { 7332 i--; 7333 PathPermission pp = pps[i]; 7334 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7335 cpi.applicationInfo.uid, cpi.exported) 7336 == PackageManager.PERMISSION_GRANTED) { 7337 return null; 7338 } 7339 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7340 cpi.applicationInfo.uid, cpi.exported) 7341 == PackageManager.PERMISSION_GRANTED) { 7342 return null; 7343 } 7344 } 7345 } 7346 7347 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7348 if (perms != null) { 7349 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7350 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7351 return null; 7352 } 7353 } 7354 } 7355 7356 String msg; 7357 if (!cpi.exported) { 7358 msg = "Permission Denial: opening provider " + cpi.name 7359 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7360 + ", uid=" + callingUid + ") that is not exported from uid " 7361 + cpi.applicationInfo.uid; 7362 } else { 7363 msg = "Permission Denial: opening provider " + cpi.name 7364 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7365 + ", uid=" + callingUid + ") requires " 7366 + cpi.readPermission + " or " + cpi.writePermission; 7367 } 7368 Slog.w(TAG, msg); 7369 return msg; 7370 } 7371 7372 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7373 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7374 if (r != null) { 7375 for (int i=0; i<r.conProviders.size(); i++) { 7376 ContentProviderConnection conn = r.conProviders.get(i); 7377 if (conn.provider == cpr) { 7378 if (DEBUG_PROVIDER) Slog.v(TAG, 7379 "Adding provider requested by " 7380 + r.processName + " from process " 7381 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7382 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7383 if (stable) { 7384 conn.stableCount++; 7385 conn.numStableIncs++; 7386 } else { 7387 conn.unstableCount++; 7388 conn.numUnstableIncs++; 7389 } 7390 return conn; 7391 } 7392 } 7393 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7394 if (stable) { 7395 conn.stableCount = 1; 7396 conn.numStableIncs = 1; 7397 } else { 7398 conn.unstableCount = 1; 7399 conn.numUnstableIncs = 1; 7400 } 7401 cpr.connections.add(conn); 7402 r.conProviders.add(conn); 7403 return conn; 7404 } 7405 cpr.addExternalProcessHandleLocked(externalProcessToken); 7406 return null; 7407 } 7408 7409 boolean decProviderCountLocked(ContentProviderConnection conn, 7410 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7411 if (conn != null) { 7412 cpr = conn.provider; 7413 if (DEBUG_PROVIDER) Slog.v(TAG, 7414 "Removing provider requested by " 7415 + conn.client.processName + " from process " 7416 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7417 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7418 if (stable) { 7419 conn.stableCount--; 7420 } else { 7421 conn.unstableCount--; 7422 } 7423 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7424 cpr.connections.remove(conn); 7425 conn.client.conProviders.remove(conn); 7426 return true; 7427 } 7428 return false; 7429 } 7430 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7431 return false; 7432 } 7433 7434 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7435 String name, IBinder token, boolean stable, int userId) { 7436 ContentProviderRecord cpr; 7437 ContentProviderConnection conn = null; 7438 ProviderInfo cpi = null; 7439 7440 synchronized(this) { 7441 ProcessRecord r = null; 7442 if (caller != null) { 7443 r = getRecordForAppLocked(caller); 7444 if (r == null) { 7445 throw new SecurityException( 7446 "Unable to find app for caller " + caller 7447 + " (pid=" + Binder.getCallingPid() 7448 + ") when getting content provider " + name); 7449 } 7450 } 7451 7452 // First check if this content provider has been published... 7453 cpr = mProviderMap.getProviderByName(name, userId); 7454 boolean providerRunning = cpr != null; 7455 if (providerRunning) { 7456 cpi = cpr.info; 7457 String msg; 7458 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7459 throw new SecurityException(msg); 7460 } 7461 7462 if (r != null && cpr.canRunHere(r)) { 7463 // This provider has been published or is in the process 7464 // of being published... but it is also allowed to run 7465 // in the caller's process, so don't make a connection 7466 // and just let the caller instantiate its own instance. 7467 ContentProviderHolder holder = cpr.newHolder(null); 7468 // don't give caller the provider object, it needs 7469 // to make its own. 7470 holder.provider = null; 7471 return holder; 7472 } 7473 7474 final long origId = Binder.clearCallingIdentity(); 7475 7476 // In this case the provider instance already exists, so we can 7477 // return it right away. 7478 conn = incProviderCountLocked(r, cpr, token, stable); 7479 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7480 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7481 // If this is a perceptible app accessing the provider, 7482 // make sure to count it as being accessed and thus 7483 // back up on the LRU list. This is good because 7484 // content providers are often expensive to start. 7485 updateLruProcessLocked(cpr.proc, false, null); 7486 } 7487 } 7488 7489 if (cpr.proc != null) { 7490 if (false) { 7491 if (cpr.name.flattenToShortString().equals( 7492 "com.android.providers.calendar/.CalendarProvider2")) { 7493 Slog.v(TAG, "****************** KILLING " 7494 + cpr.name.flattenToShortString()); 7495 Process.killProcess(cpr.proc.pid); 7496 } 7497 } 7498 boolean success = updateOomAdjLocked(cpr.proc); 7499 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7500 // NOTE: there is still a race here where a signal could be 7501 // pending on the process even though we managed to update its 7502 // adj level. Not sure what to do about this, but at least 7503 // the race is now smaller. 7504 if (!success) { 7505 // Uh oh... it looks like the provider's process 7506 // has been killed on us. We need to wait for a new 7507 // process to be started, and make sure its death 7508 // doesn't kill our process. 7509 Slog.i(TAG, 7510 "Existing provider " + cpr.name.flattenToShortString() 7511 + " is crashing; detaching " + r); 7512 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7513 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7514 if (!lastRef) { 7515 // This wasn't the last ref our process had on 7516 // the provider... we have now been killed, bail. 7517 return null; 7518 } 7519 providerRunning = false; 7520 conn = null; 7521 } 7522 } 7523 7524 Binder.restoreCallingIdentity(origId); 7525 } 7526 7527 boolean singleton; 7528 if (!providerRunning) { 7529 try { 7530 cpi = AppGlobals.getPackageManager(). 7531 resolveContentProvider(name, 7532 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7533 } catch (RemoteException ex) { 7534 } 7535 if (cpi == null) { 7536 return null; 7537 } 7538 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7539 cpi.name, cpi.flags); 7540 if (singleton) { 7541 userId = 0; 7542 } 7543 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7544 7545 String msg; 7546 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7547 throw new SecurityException(msg); 7548 } 7549 7550 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7551 && !cpi.processName.equals("system")) { 7552 // If this content provider does not run in the system 7553 // process, and the system is not yet ready to run other 7554 // processes, then fail fast instead of hanging. 7555 throw new IllegalArgumentException( 7556 "Attempt to launch content provider before system ready"); 7557 } 7558 7559 // Make sure that the user who owns this provider is started. If not, 7560 // we don't want to allow it to run. 7561 if (mStartedUsers.get(userId) == null) { 7562 Slog.w(TAG, "Unable to launch app " 7563 + cpi.applicationInfo.packageName + "/" 7564 + cpi.applicationInfo.uid + " for provider " 7565 + name + ": user " + userId + " is stopped"); 7566 return null; 7567 } 7568 7569 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7570 cpr = mProviderMap.getProviderByClass(comp, userId); 7571 final boolean firstClass = cpr == null; 7572 if (firstClass) { 7573 try { 7574 ApplicationInfo ai = 7575 AppGlobals.getPackageManager(). 7576 getApplicationInfo( 7577 cpi.applicationInfo.packageName, 7578 STOCK_PM_FLAGS, userId); 7579 if (ai == null) { 7580 Slog.w(TAG, "No package info for content provider " 7581 + cpi.name); 7582 return null; 7583 } 7584 ai = getAppInfoForUser(ai, userId); 7585 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7586 } catch (RemoteException ex) { 7587 // pm is in same process, this will never happen. 7588 } 7589 } 7590 7591 if (r != null && cpr.canRunHere(r)) { 7592 // If this is a multiprocess provider, then just return its 7593 // info and allow the caller to instantiate it. Only do 7594 // this if the provider is the same user as the caller's 7595 // process, or can run as root (so can be in any process). 7596 return cpr.newHolder(null); 7597 } 7598 7599 if (DEBUG_PROVIDER) { 7600 RuntimeException e = new RuntimeException("here"); 7601 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7602 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7603 } 7604 7605 // This is single process, and our app is now connecting to it. 7606 // See if we are already in the process of launching this 7607 // provider. 7608 final int N = mLaunchingProviders.size(); 7609 int i; 7610 for (i=0; i<N; i++) { 7611 if (mLaunchingProviders.get(i) == cpr) { 7612 break; 7613 } 7614 } 7615 7616 // If the provider is not already being launched, then get it 7617 // started. 7618 if (i >= N) { 7619 final long origId = Binder.clearCallingIdentity(); 7620 7621 try { 7622 // Content provider is now in use, its package can't be stopped. 7623 try { 7624 AppGlobals.getPackageManager().setPackageStoppedState( 7625 cpr.appInfo.packageName, false, userId); 7626 } catch (RemoteException e) { 7627 } catch (IllegalArgumentException e) { 7628 Slog.w(TAG, "Failed trying to unstop package " 7629 + cpr.appInfo.packageName + ": " + e); 7630 } 7631 7632 // Use existing process if already started 7633 ProcessRecord proc = getProcessRecordLocked( 7634 cpi.processName, cpr.appInfo.uid, false); 7635 if (proc != null && proc.thread != null) { 7636 if (DEBUG_PROVIDER) { 7637 Slog.d(TAG, "Installing in existing process " + proc); 7638 } 7639 proc.pubProviders.put(cpi.name, cpr); 7640 try { 7641 proc.thread.scheduleInstallProvider(cpi); 7642 } catch (RemoteException e) { 7643 } 7644 } else { 7645 proc = startProcessLocked(cpi.processName, 7646 cpr.appInfo, false, 0, "content provider", 7647 new ComponentName(cpi.applicationInfo.packageName, 7648 cpi.name), false, false, false); 7649 if (proc == null) { 7650 Slog.w(TAG, "Unable to launch app " 7651 + cpi.applicationInfo.packageName + "/" 7652 + cpi.applicationInfo.uid + " for provider " 7653 + name + ": process is bad"); 7654 return null; 7655 } 7656 } 7657 cpr.launchingApp = proc; 7658 mLaunchingProviders.add(cpr); 7659 } finally { 7660 Binder.restoreCallingIdentity(origId); 7661 } 7662 } 7663 7664 // Make sure the provider is published (the same provider class 7665 // may be published under multiple names). 7666 if (firstClass) { 7667 mProviderMap.putProviderByClass(comp, cpr); 7668 } 7669 7670 mProviderMap.putProviderByName(name, cpr); 7671 conn = incProviderCountLocked(r, cpr, token, stable); 7672 if (conn != null) { 7673 conn.waiting = true; 7674 } 7675 } 7676 } 7677 7678 // Wait for the provider to be published... 7679 synchronized (cpr) { 7680 while (cpr.provider == null) { 7681 if (cpr.launchingApp == null) { 7682 Slog.w(TAG, "Unable to launch app " 7683 + cpi.applicationInfo.packageName + "/" 7684 + cpi.applicationInfo.uid + " for provider " 7685 + name + ": launching app became null"); 7686 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7687 UserHandle.getUserId(cpi.applicationInfo.uid), 7688 cpi.applicationInfo.packageName, 7689 cpi.applicationInfo.uid, name); 7690 return null; 7691 } 7692 try { 7693 if (DEBUG_MU) { 7694 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7695 + cpr.launchingApp); 7696 } 7697 if (conn != null) { 7698 conn.waiting = true; 7699 } 7700 cpr.wait(); 7701 } catch (InterruptedException ex) { 7702 } finally { 7703 if (conn != null) { 7704 conn.waiting = false; 7705 } 7706 } 7707 } 7708 } 7709 return cpr != null ? cpr.newHolder(conn) : null; 7710 } 7711 7712 public final ContentProviderHolder getContentProvider( 7713 IApplicationThread caller, String name, int userId, boolean stable) { 7714 enforceNotIsolatedCaller("getContentProvider"); 7715 if (caller == null) { 7716 String msg = "null IApplicationThread when getting content provider " 7717 + name; 7718 Slog.w(TAG, msg); 7719 throw new SecurityException(msg); 7720 } 7721 7722 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7723 false, true, "getContentProvider", null); 7724 return getContentProviderImpl(caller, name, null, stable, userId); 7725 } 7726 7727 public ContentProviderHolder getContentProviderExternal( 7728 String name, int userId, IBinder token) { 7729 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7730 "Do not have permission in call getContentProviderExternal()"); 7731 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7732 false, true, "getContentProvider", null); 7733 return getContentProviderExternalUnchecked(name, token, userId); 7734 } 7735 7736 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7737 IBinder token, int userId) { 7738 return getContentProviderImpl(null, name, token, true, userId); 7739 } 7740 7741 /** 7742 * Drop a content provider from a ProcessRecord's bookkeeping 7743 */ 7744 public void removeContentProvider(IBinder connection, boolean stable) { 7745 enforceNotIsolatedCaller("removeContentProvider"); 7746 synchronized (this) { 7747 ContentProviderConnection conn; 7748 try { 7749 conn = (ContentProviderConnection)connection; 7750 } catch (ClassCastException e) { 7751 String msg ="removeContentProvider: " + connection 7752 + " not a ContentProviderConnection"; 7753 Slog.w(TAG, msg); 7754 throw new IllegalArgumentException(msg); 7755 } 7756 if (conn == null) { 7757 throw new NullPointerException("connection is null"); 7758 } 7759 if (decProviderCountLocked(conn, null, null, stable)) { 7760 updateOomAdjLocked(); 7761 } 7762 } 7763 } 7764 7765 public void removeContentProviderExternal(String name, IBinder token) { 7766 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7767 "Do not have permission in call removeContentProviderExternal()"); 7768 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7769 } 7770 7771 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7772 synchronized (this) { 7773 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7774 if(cpr == null) { 7775 //remove from mProvidersByClass 7776 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7777 return; 7778 } 7779 7780 //update content provider record entry info 7781 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7782 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7783 if (localCpr.hasExternalProcessHandles()) { 7784 if (localCpr.removeExternalProcessHandleLocked(token)) { 7785 updateOomAdjLocked(); 7786 } else { 7787 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7788 + " with no external reference for token: " 7789 + token + "."); 7790 } 7791 } else { 7792 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7793 + " with no external references."); 7794 } 7795 } 7796 } 7797 7798 public final void publishContentProviders(IApplicationThread caller, 7799 List<ContentProviderHolder> providers) { 7800 if (providers == null) { 7801 return; 7802 } 7803 7804 enforceNotIsolatedCaller("publishContentProviders"); 7805 synchronized (this) { 7806 final ProcessRecord r = getRecordForAppLocked(caller); 7807 if (DEBUG_MU) 7808 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 7809 if (r == null) { 7810 throw new SecurityException( 7811 "Unable to find app for caller " + caller 7812 + " (pid=" + Binder.getCallingPid() 7813 + ") when publishing content providers"); 7814 } 7815 7816 final long origId = Binder.clearCallingIdentity(); 7817 7818 final int N = providers.size(); 7819 for (int i=0; i<N; i++) { 7820 ContentProviderHolder src = providers.get(i); 7821 if (src == null || src.info == null || src.provider == null) { 7822 continue; 7823 } 7824 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 7825 if (DEBUG_MU) 7826 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 7827 if (dst != null) { 7828 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 7829 mProviderMap.putProviderByClass(comp, dst); 7830 String names[] = dst.info.authority.split(";"); 7831 for (int j = 0; j < names.length; j++) { 7832 mProviderMap.putProviderByName(names[j], dst); 7833 } 7834 7835 int NL = mLaunchingProviders.size(); 7836 int j; 7837 for (j=0; j<NL; j++) { 7838 if (mLaunchingProviders.get(j) == dst) { 7839 mLaunchingProviders.remove(j); 7840 j--; 7841 NL--; 7842 } 7843 } 7844 synchronized (dst) { 7845 dst.provider = src.provider; 7846 dst.proc = r; 7847 dst.notifyAll(); 7848 } 7849 updateOomAdjLocked(r); 7850 } 7851 } 7852 7853 Binder.restoreCallingIdentity(origId); 7854 } 7855 } 7856 7857 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 7858 ContentProviderConnection conn; 7859 try { 7860 conn = (ContentProviderConnection)connection; 7861 } catch (ClassCastException e) { 7862 String msg ="refContentProvider: " + connection 7863 + " not a ContentProviderConnection"; 7864 Slog.w(TAG, msg); 7865 throw new IllegalArgumentException(msg); 7866 } 7867 if (conn == null) { 7868 throw new NullPointerException("connection is null"); 7869 } 7870 7871 synchronized (this) { 7872 if (stable > 0) { 7873 conn.numStableIncs += stable; 7874 } 7875 stable = conn.stableCount + stable; 7876 if (stable < 0) { 7877 throw new IllegalStateException("stableCount < 0: " + stable); 7878 } 7879 7880 if (unstable > 0) { 7881 conn.numUnstableIncs += unstable; 7882 } 7883 unstable = conn.unstableCount + unstable; 7884 if (unstable < 0) { 7885 throw new IllegalStateException("unstableCount < 0: " + unstable); 7886 } 7887 7888 if ((stable+unstable) <= 0) { 7889 throw new IllegalStateException("ref counts can't go to zero here: stable=" 7890 + stable + " unstable=" + unstable); 7891 } 7892 conn.stableCount = stable; 7893 conn.unstableCount = unstable; 7894 return !conn.dead; 7895 } 7896 } 7897 7898 public void unstableProviderDied(IBinder connection) { 7899 ContentProviderConnection conn; 7900 try { 7901 conn = (ContentProviderConnection)connection; 7902 } catch (ClassCastException e) { 7903 String msg ="refContentProvider: " + connection 7904 + " not a ContentProviderConnection"; 7905 Slog.w(TAG, msg); 7906 throw new IllegalArgumentException(msg); 7907 } 7908 if (conn == null) { 7909 throw new NullPointerException("connection is null"); 7910 } 7911 7912 // Safely retrieve the content provider associated with the connection. 7913 IContentProvider provider; 7914 synchronized (this) { 7915 provider = conn.provider.provider; 7916 } 7917 7918 if (provider == null) { 7919 // Um, yeah, we're way ahead of you. 7920 return; 7921 } 7922 7923 // Make sure the caller is being honest with us. 7924 if (provider.asBinder().pingBinder()) { 7925 // Er, no, still looks good to us. 7926 synchronized (this) { 7927 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 7928 + " says " + conn + " died, but we don't agree"); 7929 return; 7930 } 7931 } 7932 7933 // Well look at that! It's dead! 7934 synchronized (this) { 7935 if (conn.provider.provider != provider) { 7936 // But something changed... good enough. 7937 return; 7938 } 7939 7940 ProcessRecord proc = conn.provider.proc; 7941 if (proc == null || proc.thread == null) { 7942 // Seems like the process is already cleaned up. 7943 return; 7944 } 7945 7946 // As far as we're concerned, this is just like receiving a 7947 // death notification... just a bit prematurely. 7948 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 7949 + ") early provider death"); 7950 final long ident = Binder.clearCallingIdentity(); 7951 try { 7952 appDiedLocked(proc, proc.pid, proc.thread); 7953 } finally { 7954 Binder.restoreCallingIdentity(ident); 7955 } 7956 } 7957 } 7958 7959 @Override 7960 public void appNotRespondingViaProvider(IBinder connection) { 7961 enforceCallingPermission( 7962 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 7963 7964 final ContentProviderConnection conn = (ContentProviderConnection) connection; 7965 if (conn == null) { 7966 Slog.w(TAG, "ContentProviderConnection is null"); 7967 return; 7968 } 7969 7970 final ProcessRecord host = conn.provider.proc; 7971 if (host == null) { 7972 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 7973 return; 7974 } 7975 7976 final long token = Binder.clearCallingIdentity(); 7977 try { 7978 appNotResponding(host, null, null, false, "ContentProvider not responding"); 7979 } finally { 7980 Binder.restoreCallingIdentity(token); 7981 } 7982 } 7983 7984 public final void installSystemProviders() { 7985 List<ProviderInfo> providers; 7986 synchronized (this) { 7987 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 7988 providers = generateApplicationProvidersLocked(app); 7989 if (providers != null) { 7990 for (int i=providers.size()-1; i>=0; i--) { 7991 ProviderInfo pi = (ProviderInfo)providers.get(i); 7992 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 7993 Slog.w(TAG, "Not installing system proc provider " + pi.name 7994 + ": not system .apk"); 7995 providers.remove(i); 7996 } 7997 } 7998 } 7999 } 8000 if (providers != null) { 8001 mSystemThread.installSystemProviders(providers); 8002 } 8003 8004 mCoreSettingsObserver = new CoreSettingsObserver(this); 8005 8006 mUsageStatsService.monitorPackages(); 8007 } 8008 8009 /** 8010 * Allows app to retrieve the MIME type of a URI without having permission 8011 * to access its content provider. 8012 * 8013 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8014 * 8015 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8016 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8017 */ 8018 public String getProviderMimeType(Uri uri, int userId) { 8019 enforceNotIsolatedCaller("getProviderMimeType"); 8020 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8021 userId, false, true, "getProviderMimeType", null); 8022 final String name = uri.getAuthority(); 8023 final long ident = Binder.clearCallingIdentity(); 8024 ContentProviderHolder holder = null; 8025 8026 try { 8027 holder = getContentProviderExternalUnchecked(name, null, userId); 8028 if (holder != null) { 8029 return holder.provider.getType(uri); 8030 } 8031 } catch (RemoteException e) { 8032 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8033 return null; 8034 } finally { 8035 if (holder != null) { 8036 removeContentProviderExternalUnchecked(name, null, userId); 8037 } 8038 Binder.restoreCallingIdentity(ident); 8039 } 8040 8041 return null; 8042 } 8043 8044 // ========================================================= 8045 // GLOBAL MANAGEMENT 8046 // ========================================================= 8047 8048 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8049 boolean isolated) { 8050 String proc = customProcess != null ? customProcess : info.processName; 8051 BatteryStatsImpl.Uid.Proc ps = null; 8052 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8053 int uid = info.uid; 8054 if (isolated) { 8055 int userId = UserHandle.getUserId(uid); 8056 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8057 while (true) { 8058 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8059 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8060 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8061 } 8062 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8063 mNextIsolatedProcessUid++; 8064 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8065 // No process for this uid, use it. 8066 break; 8067 } 8068 stepsLeft--; 8069 if (stepsLeft <= 0) { 8070 return null; 8071 } 8072 } 8073 } 8074 return new ProcessRecord(stats, info, proc, uid); 8075 } 8076 8077 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8078 ProcessRecord app; 8079 if (!isolated) { 8080 app = getProcessRecordLocked(info.processName, info.uid, true); 8081 } else { 8082 app = null; 8083 } 8084 8085 if (app == null) { 8086 app = newProcessRecordLocked(info, null, isolated); 8087 mProcessNames.put(info.processName, app.uid, app); 8088 if (isolated) { 8089 mIsolatedProcesses.put(app.uid, app); 8090 } 8091 updateLruProcessLocked(app, false, null); 8092 updateOomAdjLocked(); 8093 } 8094 8095 // This package really, really can not be stopped. 8096 try { 8097 AppGlobals.getPackageManager().setPackageStoppedState( 8098 info.packageName, false, UserHandle.getUserId(app.uid)); 8099 } catch (RemoteException e) { 8100 } catch (IllegalArgumentException e) { 8101 Slog.w(TAG, "Failed trying to unstop package " 8102 + info.packageName + ": " + e); 8103 } 8104 8105 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8106 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8107 app.persistent = true; 8108 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8109 } 8110 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8111 mPersistentStartingProcesses.add(app); 8112 startProcessLocked(app, "added application", app.processName); 8113 } 8114 8115 return app; 8116 } 8117 8118 public void unhandledBack() { 8119 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8120 "unhandledBack()"); 8121 8122 synchronized(this) { 8123 final long origId = Binder.clearCallingIdentity(); 8124 try { 8125 getFocusedStack().unhandledBackLocked(); 8126 } finally { 8127 Binder.restoreCallingIdentity(origId); 8128 } 8129 } 8130 } 8131 8132 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8133 enforceNotIsolatedCaller("openContentUri"); 8134 final int userId = UserHandle.getCallingUserId(); 8135 String name = uri.getAuthority(); 8136 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8137 ParcelFileDescriptor pfd = null; 8138 if (cph != null) { 8139 // We record the binder invoker's uid in thread-local storage before 8140 // going to the content provider to open the file. Later, in the code 8141 // that handles all permissions checks, we look for this uid and use 8142 // that rather than the Activity Manager's own uid. The effect is that 8143 // we do the check against the caller's permissions even though it looks 8144 // to the content provider like the Activity Manager itself is making 8145 // the request. 8146 sCallerIdentity.set(new Identity( 8147 Binder.getCallingPid(), Binder.getCallingUid())); 8148 try { 8149 pfd = cph.provider.openFile(null, uri, "r", null); 8150 } catch (FileNotFoundException e) { 8151 // do nothing; pfd will be returned null 8152 } finally { 8153 // Ensure that whatever happens, we clean up the identity state 8154 sCallerIdentity.remove(); 8155 } 8156 8157 // We've got the fd now, so we're done with the provider. 8158 removeContentProviderExternalUnchecked(name, null, userId); 8159 } else { 8160 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8161 } 8162 return pfd; 8163 } 8164 8165 // Actually is sleeping or shutting down or whatever else in the future 8166 // is an inactive state. 8167 public boolean isSleepingOrShuttingDown() { 8168 return mSleeping || mShuttingDown; 8169 } 8170 8171 void goingToSleep() { 8172 synchronized(this) { 8173 mWentToSleep = true; 8174 updateEventDispatchingLocked(); 8175 8176 if (!mSleeping) { 8177 mSleeping = true; 8178 mStackSupervisor.goingToSleepLocked(); 8179 8180 // Initialize the wake times of all processes. 8181 checkExcessivePowerUsageLocked(false); 8182 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8183 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8184 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8185 } 8186 } 8187 } 8188 8189 @Override 8190 public boolean shutdown(int timeout) { 8191 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8192 != PackageManager.PERMISSION_GRANTED) { 8193 throw new SecurityException("Requires permission " 8194 + android.Manifest.permission.SHUTDOWN); 8195 } 8196 8197 boolean timedout = false; 8198 8199 synchronized(this) { 8200 mShuttingDown = true; 8201 updateEventDispatchingLocked(); 8202 timedout = mStackSupervisor.shutdownLocked(timeout); 8203 } 8204 8205 mAppOpsService.shutdown(); 8206 mUsageStatsService.shutdown(); 8207 mBatteryStatsService.shutdown(); 8208 synchronized (this) { 8209 mProcessStats.shutdownLocked(); 8210 } 8211 8212 return timedout; 8213 } 8214 8215 public final void activitySlept(IBinder token) { 8216 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8217 8218 final long origId = Binder.clearCallingIdentity(); 8219 8220 synchronized (this) { 8221 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8222 if (r != null) { 8223 mStackSupervisor.activitySleptLocked(r); 8224 } 8225 } 8226 8227 Binder.restoreCallingIdentity(origId); 8228 } 8229 8230 void logLockScreen(String msg) { 8231 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8232 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8233 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8234 mStackSupervisor.mDismissKeyguardOnNextActivity); 8235 } 8236 8237 private void comeOutOfSleepIfNeededLocked() { 8238 if (!mWentToSleep && !mLockScreenShown) { 8239 if (mSleeping) { 8240 mSleeping = false; 8241 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8242 } 8243 } 8244 } 8245 8246 void wakingUp() { 8247 synchronized(this) { 8248 mWentToSleep = false; 8249 updateEventDispatchingLocked(); 8250 comeOutOfSleepIfNeededLocked(); 8251 } 8252 } 8253 8254 private void updateEventDispatchingLocked() { 8255 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8256 } 8257 8258 public void setLockScreenShown(boolean shown) { 8259 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8260 != PackageManager.PERMISSION_GRANTED) { 8261 throw new SecurityException("Requires permission " 8262 + android.Manifest.permission.DEVICE_POWER); 8263 } 8264 8265 synchronized(this) { 8266 long ident = Binder.clearCallingIdentity(); 8267 try { 8268 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8269 mLockScreenShown = shown; 8270 comeOutOfSleepIfNeededLocked(); 8271 } finally { 8272 Binder.restoreCallingIdentity(ident); 8273 } 8274 } 8275 } 8276 8277 public void stopAppSwitches() { 8278 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8279 != PackageManager.PERMISSION_GRANTED) { 8280 throw new SecurityException("Requires permission " 8281 + android.Manifest.permission.STOP_APP_SWITCHES); 8282 } 8283 8284 synchronized(this) { 8285 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8286 + APP_SWITCH_DELAY_TIME; 8287 mDidAppSwitch = false; 8288 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8289 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8290 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8291 } 8292 } 8293 8294 public void resumeAppSwitches() { 8295 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8296 != PackageManager.PERMISSION_GRANTED) { 8297 throw new SecurityException("Requires permission " 8298 + android.Manifest.permission.STOP_APP_SWITCHES); 8299 } 8300 8301 synchronized(this) { 8302 // Note that we don't execute any pending app switches... we will 8303 // let those wait until either the timeout, or the next start 8304 // activity request. 8305 mAppSwitchesAllowedTime = 0; 8306 } 8307 } 8308 8309 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8310 String name) { 8311 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8312 return true; 8313 } 8314 8315 final int perm = checkComponentPermission( 8316 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8317 callingUid, -1, true); 8318 if (perm == PackageManager.PERMISSION_GRANTED) { 8319 return true; 8320 } 8321 8322 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8323 return false; 8324 } 8325 8326 public void setDebugApp(String packageName, boolean waitForDebugger, 8327 boolean persistent) { 8328 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8329 "setDebugApp()"); 8330 8331 long ident = Binder.clearCallingIdentity(); 8332 try { 8333 // Note that this is not really thread safe if there are multiple 8334 // callers into it at the same time, but that's not a situation we 8335 // care about. 8336 if (persistent) { 8337 final ContentResolver resolver = mContext.getContentResolver(); 8338 Settings.Global.putString( 8339 resolver, Settings.Global.DEBUG_APP, 8340 packageName); 8341 Settings.Global.putInt( 8342 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8343 waitForDebugger ? 1 : 0); 8344 } 8345 8346 synchronized (this) { 8347 if (!persistent) { 8348 mOrigDebugApp = mDebugApp; 8349 mOrigWaitForDebugger = mWaitForDebugger; 8350 } 8351 mDebugApp = packageName; 8352 mWaitForDebugger = waitForDebugger; 8353 mDebugTransient = !persistent; 8354 if (packageName != null) { 8355 forceStopPackageLocked(packageName, -1, false, false, true, true, 8356 UserHandle.USER_ALL, "set debug app"); 8357 } 8358 } 8359 } finally { 8360 Binder.restoreCallingIdentity(ident); 8361 } 8362 } 8363 8364 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8365 synchronized (this) { 8366 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8367 if (!isDebuggable) { 8368 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8369 throw new SecurityException("Process not debuggable: " + app.packageName); 8370 } 8371 } 8372 8373 mOpenGlTraceApp = processName; 8374 } 8375 } 8376 8377 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8378 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8379 synchronized (this) { 8380 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8381 if (!isDebuggable) { 8382 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8383 throw new SecurityException("Process not debuggable: " + app.packageName); 8384 } 8385 } 8386 mProfileApp = processName; 8387 mProfileFile = profileFile; 8388 if (mProfileFd != null) { 8389 try { 8390 mProfileFd.close(); 8391 } catch (IOException e) { 8392 } 8393 mProfileFd = null; 8394 } 8395 mProfileFd = profileFd; 8396 mProfileType = 0; 8397 mAutoStopProfiler = autoStopProfiler; 8398 } 8399 } 8400 8401 @Override 8402 public void setAlwaysFinish(boolean enabled) { 8403 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8404 "setAlwaysFinish()"); 8405 8406 Settings.Global.putInt( 8407 mContext.getContentResolver(), 8408 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8409 8410 synchronized (this) { 8411 mAlwaysFinishActivities = enabled; 8412 } 8413 } 8414 8415 @Override 8416 public void setActivityController(IActivityController controller) { 8417 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8418 "setActivityController()"); 8419 synchronized (this) { 8420 mController = controller; 8421 Watchdog.getInstance().setActivityController(controller); 8422 } 8423 } 8424 8425 @Override 8426 public void setUserIsMonkey(boolean userIsMonkey) { 8427 synchronized (this) { 8428 synchronized (mPidsSelfLocked) { 8429 final int callingPid = Binder.getCallingPid(); 8430 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8431 if (precessRecord == null) { 8432 throw new SecurityException("Unknown process: " + callingPid); 8433 } 8434 if (precessRecord.instrumentationUiAutomationConnection == null) { 8435 throw new SecurityException("Only an instrumentation process " 8436 + "with a UiAutomation can call setUserIsMonkey"); 8437 } 8438 } 8439 mUserIsMonkey = userIsMonkey; 8440 } 8441 } 8442 8443 @Override 8444 public boolean isUserAMonkey() { 8445 synchronized (this) { 8446 // If there is a controller also implies the user is a monkey. 8447 return (mUserIsMonkey || mController != null); 8448 } 8449 } 8450 8451 public void requestBugReport() { 8452 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8453 SystemProperties.set("ctl.start", "bugreport"); 8454 } 8455 8456 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8457 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8458 } 8459 8460 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8461 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8462 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8463 } 8464 return KEY_DISPATCHING_TIMEOUT; 8465 } 8466 8467 @Override 8468 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8469 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8470 != PackageManager.PERMISSION_GRANTED) { 8471 throw new SecurityException("Requires permission " 8472 + android.Manifest.permission.FILTER_EVENTS); 8473 } 8474 ProcessRecord proc; 8475 long timeout; 8476 synchronized (this) { 8477 synchronized (mPidsSelfLocked) { 8478 proc = mPidsSelfLocked.get(pid); 8479 } 8480 timeout = getInputDispatchingTimeoutLocked(proc); 8481 } 8482 8483 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8484 return -1; 8485 } 8486 8487 return timeout; 8488 } 8489 8490 /** 8491 * Handle input dispatching timeouts. 8492 * Returns whether input dispatching should be aborted or not. 8493 */ 8494 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8495 final ActivityRecord activity, final ActivityRecord parent, 8496 final boolean aboveSystem, String reason) { 8497 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8498 != PackageManager.PERMISSION_GRANTED) { 8499 throw new SecurityException("Requires permission " 8500 + android.Manifest.permission.FILTER_EVENTS); 8501 } 8502 8503 final String annotation; 8504 if (reason == null) { 8505 annotation = "Input dispatching timed out"; 8506 } else { 8507 annotation = "Input dispatching timed out (" + reason + ")"; 8508 } 8509 8510 if (proc != null) { 8511 synchronized (this) { 8512 if (proc.debugging) { 8513 return false; 8514 } 8515 8516 if (mDidDexOpt) { 8517 // Give more time since we were dexopting. 8518 mDidDexOpt = false; 8519 return false; 8520 } 8521 8522 if (proc.instrumentationClass != null) { 8523 Bundle info = new Bundle(); 8524 info.putString("shortMsg", "keyDispatchingTimedOut"); 8525 info.putString("longMsg", annotation); 8526 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8527 return true; 8528 } 8529 } 8530 mHandler.post(new Runnable() { 8531 @Override 8532 public void run() { 8533 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8534 } 8535 }); 8536 } 8537 8538 return true; 8539 } 8540 8541 public Bundle getAssistContextExtras(int requestType) { 8542 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8543 "getAssistContextExtras()"); 8544 PendingAssistExtras pae; 8545 Bundle extras = new Bundle(); 8546 synchronized (this) { 8547 ActivityRecord activity = getFocusedStack().mResumedActivity; 8548 if (activity == null) { 8549 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8550 return null; 8551 } 8552 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8553 if (activity.app == null || activity.app.thread == null) { 8554 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8555 return extras; 8556 } 8557 if (activity.app.pid == Binder.getCallingPid()) { 8558 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8559 return extras; 8560 } 8561 pae = new PendingAssistExtras(activity); 8562 try { 8563 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8564 requestType); 8565 mPendingAssistExtras.add(pae); 8566 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8567 } catch (RemoteException e) { 8568 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8569 return extras; 8570 } 8571 } 8572 synchronized (pae) { 8573 while (!pae.haveResult) { 8574 try { 8575 pae.wait(); 8576 } catch (InterruptedException e) { 8577 } 8578 } 8579 if (pae.result != null) { 8580 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8581 } 8582 } 8583 synchronized (this) { 8584 mPendingAssistExtras.remove(pae); 8585 mHandler.removeCallbacks(pae); 8586 } 8587 return extras; 8588 } 8589 8590 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8591 PendingAssistExtras pae = (PendingAssistExtras)token; 8592 synchronized (pae) { 8593 pae.result = extras; 8594 pae.haveResult = true; 8595 pae.notifyAll(); 8596 } 8597 } 8598 8599 public void registerProcessObserver(IProcessObserver observer) { 8600 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8601 "registerProcessObserver()"); 8602 synchronized (this) { 8603 mProcessObservers.register(observer); 8604 } 8605 } 8606 8607 @Override 8608 public void unregisterProcessObserver(IProcessObserver observer) { 8609 synchronized (this) { 8610 mProcessObservers.unregister(observer); 8611 } 8612 } 8613 8614 @Override 8615 public boolean convertFromTranslucent(IBinder token) { 8616 final long origId = Binder.clearCallingIdentity(); 8617 try { 8618 synchronized (this) { 8619 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8620 if (r == null) { 8621 return false; 8622 } 8623 if (r.changeWindowTranslucency(true)) { 8624 mWindowManager.setAppFullscreen(token, true); 8625 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8626 return true; 8627 } 8628 return false; 8629 } 8630 } finally { 8631 Binder.restoreCallingIdentity(origId); 8632 } 8633 } 8634 8635 @Override 8636 public boolean convertToTranslucent(IBinder token) { 8637 final long origId = Binder.clearCallingIdentity(); 8638 try { 8639 synchronized (this) { 8640 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8641 if (r == null) { 8642 return false; 8643 } 8644 if (r.changeWindowTranslucency(false)) { 8645 r.task.stack.convertToTranslucent(r); 8646 mWindowManager.setAppFullscreen(token, false); 8647 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8648 return true; 8649 } 8650 return false; 8651 } 8652 } finally { 8653 Binder.restoreCallingIdentity(origId); 8654 } 8655 } 8656 8657 @Override 8658 public void setImmersive(IBinder token, boolean immersive) { 8659 synchronized(this) { 8660 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8661 if (r == null) { 8662 throw new IllegalArgumentException(); 8663 } 8664 r.immersive = immersive; 8665 8666 // update associated state if we're frontmost 8667 if (r == mFocusedActivity) { 8668 if (DEBUG_IMMERSIVE) { 8669 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8670 } 8671 applyUpdateLockStateLocked(r); 8672 } 8673 } 8674 } 8675 8676 @Override 8677 public boolean isImmersive(IBinder token) { 8678 synchronized (this) { 8679 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8680 if (r == null) { 8681 throw new IllegalArgumentException(); 8682 } 8683 return r.immersive; 8684 } 8685 } 8686 8687 public boolean isTopActivityImmersive() { 8688 enforceNotIsolatedCaller("startActivity"); 8689 synchronized (this) { 8690 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8691 return (r != null) ? r.immersive : false; 8692 } 8693 } 8694 8695 public final void enterSafeMode() { 8696 synchronized(this) { 8697 // It only makes sense to do this before the system is ready 8698 // and started launching other packages. 8699 if (!mSystemReady) { 8700 try { 8701 AppGlobals.getPackageManager().enterSafeMode(); 8702 } catch (RemoteException e) { 8703 } 8704 } 8705 } 8706 } 8707 8708 public final void showSafeModeOverlay() { 8709 View v = LayoutInflater.from(mContext).inflate( 8710 com.android.internal.R.layout.safe_mode, null); 8711 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8712 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8713 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8714 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8715 lp.gravity = Gravity.BOTTOM | Gravity.START; 8716 lp.format = v.getBackground().getOpacity(); 8717 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8718 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8719 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8720 ((WindowManager)mContext.getSystemService( 8721 Context.WINDOW_SERVICE)).addView(v, lp); 8722 } 8723 8724 public void noteWakeupAlarm(IIntentSender sender) { 8725 if (!(sender instanceof PendingIntentRecord)) { 8726 return; 8727 } 8728 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8729 synchronized (stats) { 8730 if (mBatteryStatsService.isOnBattery()) { 8731 mBatteryStatsService.enforceCallingPermission(); 8732 PendingIntentRecord rec = (PendingIntentRecord)sender; 8733 int MY_UID = Binder.getCallingUid(); 8734 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8735 BatteryStatsImpl.Uid.Pkg pkg = 8736 stats.getPackageStatsLocked(uid, rec.key.packageName); 8737 pkg.incWakeupsLocked(); 8738 } 8739 } 8740 } 8741 8742 public boolean killPids(int[] pids, String pReason, boolean secure) { 8743 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8744 throw new SecurityException("killPids only available to the system"); 8745 } 8746 String reason = (pReason == null) ? "Unknown" : pReason; 8747 // XXX Note: don't acquire main activity lock here, because the window 8748 // manager calls in with its locks held. 8749 8750 boolean killed = false; 8751 synchronized (mPidsSelfLocked) { 8752 int[] types = new int[pids.length]; 8753 int worstType = 0; 8754 for (int i=0; i<pids.length; i++) { 8755 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8756 if (proc != null) { 8757 int type = proc.setAdj; 8758 types[i] = type; 8759 if (type > worstType) { 8760 worstType = type; 8761 } 8762 } 8763 } 8764 8765 // If the worst oom_adj is somewhere in the cached proc LRU range, 8766 // then constrain it so we will kill all cached procs. 8767 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8768 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8769 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8770 } 8771 8772 // If this is not a secure call, don't let it kill processes that 8773 // are important. 8774 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8775 worstType = ProcessList.SERVICE_ADJ; 8776 } 8777 8778 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8779 for (int i=0; i<pids.length; i++) { 8780 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8781 if (proc == null) { 8782 continue; 8783 } 8784 int adj = proc.setAdj; 8785 if (adj >= worstType && !proc.killedByAm) { 8786 killUnneededProcessLocked(proc, reason); 8787 killed = true; 8788 } 8789 } 8790 } 8791 return killed; 8792 } 8793 8794 @Override 8795 public void killUid(int uid, String reason) { 8796 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8797 throw new SecurityException("killUid only available to the system"); 8798 } 8799 synchronized (this) { 8800 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 8801 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 8802 reason != null ? reason : "kill uid"); 8803 } 8804 } 8805 8806 @Override 8807 public boolean killProcessesBelowForeground(String reason) { 8808 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8809 throw new SecurityException("killProcessesBelowForeground() only available to system"); 8810 } 8811 8812 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 8813 } 8814 8815 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 8816 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8817 throw new SecurityException("killProcessesBelowAdj() only available to system"); 8818 } 8819 8820 boolean killed = false; 8821 synchronized (mPidsSelfLocked) { 8822 final int size = mPidsSelfLocked.size(); 8823 for (int i = 0; i < size; i++) { 8824 final int pid = mPidsSelfLocked.keyAt(i); 8825 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8826 if (proc == null) continue; 8827 8828 final int adj = proc.setAdj; 8829 if (adj > belowAdj && !proc.killedByAm) { 8830 killUnneededProcessLocked(proc, reason); 8831 killed = true; 8832 } 8833 } 8834 } 8835 return killed; 8836 } 8837 8838 @Override 8839 public void hang(final IBinder who, boolean allowRestart) { 8840 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8841 != PackageManager.PERMISSION_GRANTED) { 8842 throw new SecurityException("Requires permission " 8843 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8844 } 8845 8846 final IBinder.DeathRecipient death = new DeathRecipient() { 8847 @Override 8848 public void binderDied() { 8849 synchronized (this) { 8850 notifyAll(); 8851 } 8852 } 8853 }; 8854 8855 try { 8856 who.linkToDeath(death, 0); 8857 } catch (RemoteException e) { 8858 Slog.w(TAG, "hang: given caller IBinder is already dead."); 8859 return; 8860 } 8861 8862 synchronized (this) { 8863 Watchdog.getInstance().setAllowRestart(allowRestart); 8864 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 8865 synchronized (death) { 8866 while (who.isBinderAlive()) { 8867 try { 8868 death.wait(); 8869 } catch (InterruptedException e) { 8870 } 8871 } 8872 } 8873 Watchdog.getInstance().setAllowRestart(true); 8874 } 8875 } 8876 8877 @Override 8878 public void restart() { 8879 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8880 != PackageManager.PERMISSION_GRANTED) { 8881 throw new SecurityException("Requires permission " 8882 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8883 } 8884 8885 Log.i(TAG, "Sending shutdown broadcast..."); 8886 8887 BroadcastReceiver br = new BroadcastReceiver() { 8888 @Override public void onReceive(Context context, Intent intent) { 8889 // Now the broadcast is done, finish up the low-level shutdown. 8890 Log.i(TAG, "Shutting down activity manager..."); 8891 shutdown(10000); 8892 Log.i(TAG, "Shutdown complete, restarting!"); 8893 Process.killProcess(Process.myPid()); 8894 System.exit(10); 8895 } 8896 }; 8897 8898 // First send the high-level shut down broadcast. 8899 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 8900 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 8901 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 8902 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 8903 mContext.sendOrderedBroadcastAsUser(intent, 8904 UserHandle.ALL, null, br, mHandler, 0, null, null); 8905 */ 8906 br.onReceive(mContext, intent); 8907 } 8908 8909 private long getLowRamTimeSinceIdle(long now) { 8910 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 8911 } 8912 8913 @Override 8914 public void performIdleMaintenance() { 8915 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8916 != PackageManager.PERMISSION_GRANTED) { 8917 throw new SecurityException("Requires permission " 8918 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8919 } 8920 8921 synchronized (this) { 8922 final long now = SystemClock.uptimeMillis(); 8923 final long timeSinceLastIdle = now - mLastIdleTime; 8924 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 8925 mLastIdleTime = now; 8926 mLowRamTimeSinceLastIdle = 0; 8927 if (mLowRamStartTime != 0) { 8928 mLowRamStartTime = now; 8929 } 8930 8931 StringBuilder sb = new StringBuilder(128); 8932 sb.append("Idle maintenance over "); 8933 TimeUtils.formatDuration(timeSinceLastIdle, sb); 8934 sb.append(" low RAM for "); 8935 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 8936 Slog.i(TAG, sb.toString()); 8937 8938 // If at least 1/3 of our time since the last idle period has been spent 8939 // with RAM low, then we want to kill processes. 8940 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 8941 8942 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 8943 ProcessRecord proc = mLruProcesses.get(i); 8944 if (proc.notCachedSinceIdle) { 8945 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 8946 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 8947 if (doKilling && proc.initialIdlePss != 0 8948 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 8949 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 8950 + " from " + proc.initialIdlePss + ")"); 8951 } 8952 } 8953 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 8954 proc.notCachedSinceIdle = true; 8955 proc.initialIdlePss = 0; 8956 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 8957 mSleeping, now); 8958 } 8959 } 8960 8961 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 8962 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 8963 } 8964 } 8965 8966 private void retrieveSettings() { 8967 final ContentResolver resolver = mContext.getContentResolver(); 8968 String debugApp = Settings.Global.getString( 8969 resolver, Settings.Global.DEBUG_APP); 8970 boolean waitForDebugger = Settings.Global.getInt( 8971 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 8972 boolean alwaysFinishActivities = Settings.Global.getInt( 8973 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 8974 boolean forceRtl = Settings.Global.getInt( 8975 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 8976 // Transfer any global setting for forcing RTL layout, into a System Property 8977 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 8978 8979 Configuration configuration = new Configuration(); 8980 Settings.System.getConfiguration(resolver, configuration); 8981 if (forceRtl) { 8982 // This will take care of setting the correct layout direction flags 8983 configuration.setLayoutDirection(configuration.locale); 8984 } 8985 8986 synchronized (this) { 8987 mDebugApp = mOrigDebugApp = debugApp; 8988 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 8989 mAlwaysFinishActivities = alwaysFinishActivities; 8990 // This happens before any activities are started, so we can 8991 // change mConfiguration in-place. 8992 updateConfigurationLocked(configuration, null, false, true); 8993 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 8994 } 8995 } 8996 8997 public boolean testIsSystemReady() { 8998 // no need to synchronize(this) just to read & return the value 8999 return mSystemReady; 9000 } 9001 9002 private static File getCalledPreBootReceiversFile() { 9003 File dataDir = Environment.getDataDirectory(); 9004 File systemDir = new File(dataDir, "system"); 9005 File fname = new File(systemDir, "called_pre_boots.dat"); 9006 return fname; 9007 } 9008 9009 static final int LAST_DONE_VERSION = 10000; 9010 9011 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9012 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9013 File file = getCalledPreBootReceiversFile(); 9014 FileInputStream fis = null; 9015 try { 9016 fis = new FileInputStream(file); 9017 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9018 int fvers = dis.readInt(); 9019 if (fvers == LAST_DONE_VERSION) { 9020 String vers = dis.readUTF(); 9021 String codename = dis.readUTF(); 9022 String build = dis.readUTF(); 9023 if (android.os.Build.VERSION.RELEASE.equals(vers) 9024 && android.os.Build.VERSION.CODENAME.equals(codename) 9025 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9026 int num = dis.readInt(); 9027 while (num > 0) { 9028 num--; 9029 String pkg = dis.readUTF(); 9030 String cls = dis.readUTF(); 9031 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9032 } 9033 } 9034 } 9035 } catch (FileNotFoundException e) { 9036 } catch (IOException e) { 9037 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9038 } finally { 9039 if (fis != null) { 9040 try { 9041 fis.close(); 9042 } catch (IOException e) { 9043 } 9044 } 9045 } 9046 return lastDoneReceivers; 9047 } 9048 9049 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9050 File file = getCalledPreBootReceiversFile(); 9051 FileOutputStream fos = null; 9052 DataOutputStream dos = null; 9053 try { 9054 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9055 fos = new FileOutputStream(file); 9056 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9057 dos.writeInt(LAST_DONE_VERSION); 9058 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9059 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9060 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9061 dos.writeInt(list.size()); 9062 for (int i=0; i<list.size(); i++) { 9063 dos.writeUTF(list.get(i).getPackageName()); 9064 dos.writeUTF(list.get(i).getClassName()); 9065 } 9066 } catch (IOException e) { 9067 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9068 file.delete(); 9069 } finally { 9070 FileUtils.sync(fos); 9071 if (dos != null) { 9072 try { 9073 dos.close(); 9074 } catch (IOException e) { 9075 // TODO Auto-generated catch block 9076 e.printStackTrace(); 9077 } 9078 } 9079 } 9080 } 9081 9082 public void systemReady(final Runnable goingCallback) { 9083 synchronized(this) { 9084 if (mSystemReady) { 9085 if (goingCallback != null) goingCallback.run(); 9086 return; 9087 } 9088 9089 // Check to see if there are any update receivers to run. 9090 if (!mDidUpdate) { 9091 if (mWaitingUpdate) { 9092 return; 9093 } 9094 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9095 List<ResolveInfo> ris = null; 9096 try { 9097 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9098 intent, null, 0, 0); 9099 } catch (RemoteException e) { 9100 } 9101 if (ris != null) { 9102 for (int i=ris.size()-1; i>=0; i--) { 9103 if ((ris.get(i).activityInfo.applicationInfo.flags 9104 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9105 ris.remove(i); 9106 } 9107 } 9108 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9109 9110 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9111 9112 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9113 for (int i=0; i<ris.size(); i++) { 9114 ActivityInfo ai = ris.get(i).activityInfo; 9115 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9116 if (lastDoneReceivers.contains(comp)) { 9117 // We already did the pre boot receiver for this app with the current 9118 // platform version, so don't do it again... 9119 ris.remove(i); 9120 i--; 9121 // ...however, do keep it as one that has been done, so we don't 9122 // forget about it when rewriting the file of last done receivers. 9123 doneReceivers.add(comp); 9124 } 9125 } 9126 9127 final int[] users = getUsersLocked(); 9128 for (int i=0; i<ris.size(); i++) { 9129 ActivityInfo ai = ris.get(i).activityInfo; 9130 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9131 doneReceivers.add(comp); 9132 intent.setComponent(comp); 9133 for (int j=0; j<users.length; j++) { 9134 IIntentReceiver finisher = null; 9135 if (i == ris.size()-1 && j == users.length-1) { 9136 finisher = new IIntentReceiver.Stub() { 9137 public void performReceive(Intent intent, int resultCode, 9138 String data, Bundle extras, boolean ordered, 9139 boolean sticky, int sendingUser) { 9140 // The raw IIntentReceiver interface is called 9141 // with the AM lock held, so redispatch to 9142 // execute our code without the lock. 9143 mHandler.post(new Runnable() { 9144 public void run() { 9145 synchronized (ActivityManagerService.this) { 9146 mDidUpdate = true; 9147 } 9148 writeLastDonePreBootReceivers(doneReceivers); 9149 showBootMessage(mContext.getText( 9150 R.string.android_upgrading_complete), 9151 false); 9152 systemReady(goingCallback); 9153 } 9154 }); 9155 } 9156 }; 9157 } 9158 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9159 + " for user " + users[j]); 9160 broadcastIntentLocked(null, null, intent, null, finisher, 9161 0, null, null, null, AppOpsManager.OP_NONE, 9162 true, false, MY_PID, Process.SYSTEM_UID, 9163 users[j]); 9164 if (finisher != null) { 9165 mWaitingUpdate = true; 9166 } 9167 } 9168 } 9169 } 9170 if (mWaitingUpdate) { 9171 return; 9172 } 9173 mDidUpdate = true; 9174 } 9175 9176 mAppOpsService.systemReady(); 9177 mSystemReady = true; 9178 } 9179 9180 ArrayList<ProcessRecord> procsToKill = null; 9181 synchronized(mPidsSelfLocked) { 9182 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9183 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9184 if (!isAllowedWhileBooting(proc.info)){ 9185 if (procsToKill == null) { 9186 procsToKill = new ArrayList<ProcessRecord>(); 9187 } 9188 procsToKill.add(proc); 9189 } 9190 } 9191 } 9192 9193 synchronized(this) { 9194 if (procsToKill != null) { 9195 for (int i=procsToKill.size()-1; i>=0; i--) { 9196 ProcessRecord proc = procsToKill.get(i); 9197 Slog.i(TAG, "Removing system update proc: " + proc); 9198 removeProcessLocked(proc, true, false, "system update done"); 9199 } 9200 } 9201 9202 // Now that we have cleaned up any update processes, we 9203 // are ready to start launching real processes and know that 9204 // we won't trample on them any more. 9205 mProcessesReady = true; 9206 } 9207 9208 Slog.i(TAG, "System now ready"); 9209 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9210 SystemClock.uptimeMillis()); 9211 9212 synchronized(this) { 9213 // Make sure we have no pre-ready processes sitting around. 9214 9215 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9216 ResolveInfo ri = mContext.getPackageManager() 9217 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9218 STOCK_PM_FLAGS); 9219 CharSequence errorMsg = null; 9220 if (ri != null) { 9221 ActivityInfo ai = ri.activityInfo; 9222 ApplicationInfo app = ai.applicationInfo; 9223 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9224 mTopAction = Intent.ACTION_FACTORY_TEST; 9225 mTopData = null; 9226 mTopComponent = new ComponentName(app.packageName, 9227 ai.name); 9228 } else { 9229 errorMsg = mContext.getResources().getText( 9230 com.android.internal.R.string.factorytest_not_system); 9231 } 9232 } else { 9233 errorMsg = mContext.getResources().getText( 9234 com.android.internal.R.string.factorytest_no_action); 9235 } 9236 if (errorMsg != null) { 9237 mTopAction = null; 9238 mTopData = null; 9239 mTopComponent = null; 9240 Message msg = Message.obtain(); 9241 msg.what = SHOW_FACTORY_ERROR_MSG; 9242 msg.getData().putCharSequence("msg", errorMsg); 9243 mHandler.sendMessage(msg); 9244 } 9245 } 9246 } 9247 9248 retrieveSettings(); 9249 9250 synchronized (this) { 9251 readGrantedUriPermissionsLocked(); 9252 } 9253 9254 if (goingCallback != null) goingCallback.run(); 9255 9256 synchronized (this) { 9257 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9258 try { 9259 List apps = AppGlobals.getPackageManager(). 9260 getPersistentApplications(STOCK_PM_FLAGS); 9261 if (apps != null) { 9262 int N = apps.size(); 9263 int i; 9264 for (i=0; i<N; i++) { 9265 ApplicationInfo info 9266 = (ApplicationInfo)apps.get(i); 9267 if (info != null && 9268 !info.packageName.equals("android")) { 9269 addAppLocked(info, false); 9270 } 9271 } 9272 } 9273 } catch (RemoteException ex) { 9274 // pm is in same process, this will never happen. 9275 } 9276 } 9277 9278 // Start up initial activity. 9279 mBooting = true; 9280 9281 try { 9282 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9283 Message msg = Message.obtain(); 9284 msg.what = SHOW_UID_ERROR_MSG; 9285 mHandler.sendMessage(msg); 9286 } 9287 } catch (RemoteException e) { 9288 } 9289 9290 long ident = Binder.clearCallingIdentity(); 9291 try { 9292 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9293 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9294 | Intent.FLAG_RECEIVER_FOREGROUND); 9295 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9296 broadcastIntentLocked(null, null, intent, 9297 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9298 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9299 intent = new Intent(Intent.ACTION_USER_STARTING); 9300 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9301 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9302 broadcastIntentLocked(null, null, intent, 9303 null, new IIntentReceiver.Stub() { 9304 @Override 9305 public void performReceive(Intent intent, int resultCode, String data, 9306 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9307 throws RemoteException { 9308 } 9309 }, 0, null, null, 9310 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9311 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9312 } finally { 9313 Binder.restoreCallingIdentity(ident); 9314 } 9315 mStackSupervisor.resumeTopActivitiesLocked(); 9316 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9317 } 9318 } 9319 9320 private boolean makeAppCrashingLocked(ProcessRecord app, 9321 String shortMsg, String longMsg, String stackTrace) { 9322 app.crashing = true; 9323 app.crashingReport = generateProcessError(app, 9324 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9325 startAppProblemLocked(app); 9326 app.stopFreezingAllLocked(); 9327 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9328 } 9329 9330 private void makeAppNotRespondingLocked(ProcessRecord app, 9331 String activity, String shortMsg, String longMsg) { 9332 app.notResponding = true; 9333 app.notRespondingReport = generateProcessError(app, 9334 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9335 activity, shortMsg, longMsg, null); 9336 startAppProblemLocked(app); 9337 app.stopFreezingAllLocked(); 9338 } 9339 9340 /** 9341 * Generate a process error record, suitable for attachment to a ProcessRecord. 9342 * 9343 * @param app The ProcessRecord in which the error occurred. 9344 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9345 * ActivityManager.AppErrorStateInfo 9346 * @param activity The activity associated with the crash, if known. 9347 * @param shortMsg Short message describing the crash. 9348 * @param longMsg Long message describing the crash. 9349 * @param stackTrace Full crash stack trace, may be null. 9350 * 9351 * @return Returns a fully-formed AppErrorStateInfo record. 9352 */ 9353 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9354 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9355 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9356 9357 report.condition = condition; 9358 report.processName = app.processName; 9359 report.pid = app.pid; 9360 report.uid = app.info.uid; 9361 report.tag = activity; 9362 report.shortMsg = shortMsg; 9363 report.longMsg = longMsg; 9364 report.stackTrace = stackTrace; 9365 9366 return report; 9367 } 9368 9369 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9370 synchronized (this) { 9371 app.crashing = false; 9372 app.crashingReport = null; 9373 app.notResponding = false; 9374 app.notRespondingReport = null; 9375 if (app.anrDialog == fromDialog) { 9376 app.anrDialog = null; 9377 } 9378 if (app.waitDialog == fromDialog) { 9379 app.waitDialog = null; 9380 } 9381 if (app.pid > 0 && app.pid != MY_PID) { 9382 handleAppCrashLocked(app, null, null, null); 9383 killUnneededProcessLocked(app, "user request after error"); 9384 } 9385 } 9386 } 9387 9388 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9389 String stackTrace) { 9390 long now = SystemClock.uptimeMillis(); 9391 9392 Long crashTime; 9393 if (!app.isolated) { 9394 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9395 } else { 9396 crashTime = null; 9397 } 9398 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9399 // This process loses! 9400 Slog.w(TAG, "Process " + app.info.processName 9401 + " has crashed too many times: killing!"); 9402 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9403 app.userId, app.info.processName, app.uid); 9404 mStackSupervisor.handleAppCrashLocked(app); 9405 if (!app.persistent) { 9406 // We don't want to start this process again until the user 9407 // explicitly does so... but for persistent process, we really 9408 // need to keep it running. If a persistent process is actually 9409 // repeatedly crashing, then badness for everyone. 9410 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9411 app.info.processName); 9412 if (!app.isolated) { 9413 // XXX We don't have a way to mark isolated processes 9414 // as bad, since they don't have a peristent identity. 9415 mBadProcesses.put(app.info.processName, app.uid, 9416 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9417 mProcessCrashTimes.remove(app.info.processName, app.uid); 9418 } 9419 app.bad = true; 9420 app.removed = true; 9421 // Don't let services in this process be restarted and potentially 9422 // annoy the user repeatedly. Unless it is persistent, since those 9423 // processes run critical code. 9424 removeProcessLocked(app, false, false, "crash"); 9425 mStackSupervisor.resumeTopActivitiesLocked(); 9426 return false; 9427 } 9428 mStackSupervisor.resumeTopActivitiesLocked(); 9429 } else { 9430 mStackSupervisor.finishTopRunningActivityLocked(app); 9431 } 9432 9433 // Bump up the crash count of any services currently running in the proc. 9434 for (int i=app.services.size()-1; i>=0; i--) { 9435 // Any services running in the application need to be placed 9436 // back in the pending list. 9437 ServiceRecord sr = app.services.valueAt(i); 9438 sr.crashCount++; 9439 } 9440 9441 // If the crashing process is what we consider to be the "home process" and it has been 9442 // replaced by a third-party app, clear the package preferred activities from packages 9443 // with a home activity running in the process to prevent a repeatedly crashing app 9444 // from blocking the user to manually clear the list. 9445 final ArrayList<ActivityRecord> activities = app.activities; 9446 if (app == mHomeProcess && activities.size() > 0 9447 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9448 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9449 final ActivityRecord r = activities.get(activityNdx); 9450 if (r.isHomeActivity()) { 9451 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9452 try { 9453 ActivityThread.getPackageManager() 9454 .clearPackagePreferredActivities(r.packageName); 9455 } catch (RemoteException c) { 9456 // pm is in same process, this will never happen. 9457 } 9458 } 9459 } 9460 } 9461 9462 if (!app.isolated) { 9463 // XXX Can't keep track of crash times for isolated processes, 9464 // because they don't have a perisistent identity. 9465 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9466 } 9467 9468 return true; 9469 } 9470 9471 void startAppProblemLocked(ProcessRecord app) { 9472 if (app.userId == mCurrentUserId) { 9473 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9474 mContext, app.info.packageName, app.info.flags); 9475 } else { 9476 // If this app is not running under the current user, then we 9477 // can't give it a report button because that would require 9478 // launching the report UI under a different user. 9479 app.errorReportReceiver = null; 9480 } 9481 skipCurrentReceiverLocked(app); 9482 } 9483 9484 void skipCurrentReceiverLocked(ProcessRecord app) { 9485 for (BroadcastQueue queue : mBroadcastQueues) { 9486 queue.skipCurrentReceiverLocked(app); 9487 } 9488 } 9489 9490 /** 9491 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9492 * The application process will exit immediately after this call returns. 9493 * @param app object of the crashing app, null for the system server 9494 * @param crashInfo describing the exception 9495 */ 9496 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9497 ProcessRecord r = findAppProcess(app, "Crash"); 9498 final String processName = app == null ? "system_server" 9499 : (r == null ? "unknown" : r.processName); 9500 9501 handleApplicationCrashInner("crash", r, processName, crashInfo); 9502 } 9503 9504 /* Native crash reporting uses this inner version because it needs to be somewhat 9505 * decoupled from the AM-managed cleanup lifecycle 9506 */ 9507 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9508 ApplicationErrorReport.CrashInfo crashInfo) { 9509 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9510 UserHandle.getUserId(Binder.getCallingUid()), processName, 9511 r == null ? -1 : r.info.flags, 9512 crashInfo.exceptionClassName, 9513 crashInfo.exceptionMessage, 9514 crashInfo.throwFileName, 9515 crashInfo.throwLineNumber); 9516 9517 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9518 9519 crashApplication(r, crashInfo); 9520 } 9521 9522 public void handleApplicationStrictModeViolation( 9523 IBinder app, 9524 int violationMask, 9525 StrictMode.ViolationInfo info) { 9526 ProcessRecord r = findAppProcess(app, "StrictMode"); 9527 if (r == null) { 9528 return; 9529 } 9530 9531 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9532 Integer stackFingerprint = info.hashCode(); 9533 boolean logIt = true; 9534 synchronized (mAlreadyLoggedViolatedStacks) { 9535 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9536 logIt = false; 9537 // TODO: sub-sample into EventLog for these, with 9538 // the info.durationMillis? Then we'd get 9539 // the relative pain numbers, without logging all 9540 // the stack traces repeatedly. We'd want to do 9541 // likewise in the client code, which also does 9542 // dup suppression, before the Binder call. 9543 } else { 9544 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9545 mAlreadyLoggedViolatedStacks.clear(); 9546 } 9547 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9548 } 9549 } 9550 if (logIt) { 9551 logStrictModeViolationToDropBox(r, info); 9552 } 9553 } 9554 9555 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9556 AppErrorResult result = new AppErrorResult(); 9557 synchronized (this) { 9558 final long origId = Binder.clearCallingIdentity(); 9559 9560 Message msg = Message.obtain(); 9561 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9562 HashMap<String, Object> data = new HashMap<String, Object>(); 9563 data.put("result", result); 9564 data.put("app", r); 9565 data.put("violationMask", violationMask); 9566 data.put("info", info); 9567 msg.obj = data; 9568 mHandler.sendMessage(msg); 9569 9570 Binder.restoreCallingIdentity(origId); 9571 } 9572 int res = result.get(); 9573 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9574 } 9575 } 9576 9577 // Depending on the policy in effect, there could be a bunch of 9578 // these in quick succession so we try to batch these together to 9579 // minimize disk writes, number of dropbox entries, and maximize 9580 // compression, by having more fewer, larger records. 9581 private void logStrictModeViolationToDropBox( 9582 ProcessRecord process, 9583 StrictMode.ViolationInfo info) { 9584 if (info == null) { 9585 return; 9586 } 9587 final boolean isSystemApp = process == null || 9588 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9589 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9590 final String processName = process == null ? "unknown" : process.processName; 9591 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9592 final DropBoxManager dbox = (DropBoxManager) 9593 mContext.getSystemService(Context.DROPBOX_SERVICE); 9594 9595 // Exit early if the dropbox isn't configured to accept this report type. 9596 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9597 9598 boolean bufferWasEmpty; 9599 boolean needsFlush; 9600 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9601 synchronized (sb) { 9602 bufferWasEmpty = sb.length() == 0; 9603 appendDropBoxProcessHeaders(process, processName, sb); 9604 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9605 sb.append("System-App: ").append(isSystemApp).append("\n"); 9606 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9607 if (info.violationNumThisLoop != 0) { 9608 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9609 } 9610 if (info.numAnimationsRunning != 0) { 9611 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9612 } 9613 if (info.broadcastIntentAction != null) { 9614 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9615 } 9616 if (info.durationMillis != -1) { 9617 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9618 } 9619 if (info.numInstances != -1) { 9620 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9621 } 9622 if (info.tags != null) { 9623 for (String tag : info.tags) { 9624 sb.append("Span-Tag: ").append(tag).append("\n"); 9625 } 9626 } 9627 sb.append("\n"); 9628 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9629 sb.append(info.crashInfo.stackTrace); 9630 } 9631 sb.append("\n"); 9632 9633 // Only buffer up to ~64k. Various logging bits truncate 9634 // things at 128k. 9635 needsFlush = (sb.length() > 64 * 1024); 9636 } 9637 9638 // Flush immediately if the buffer's grown too large, or this 9639 // is a non-system app. Non-system apps are isolated with a 9640 // different tag & policy and not batched. 9641 // 9642 // Batching is useful during internal testing with 9643 // StrictMode settings turned up high. Without batching, 9644 // thousands of separate files could be created on boot. 9645 if (!isSystemApp || needsFlush) { 9646 new Thread("Error dump: " + dropboxTag) { 9647 @Override 9648 public void run() { 9649 String report; 9650 synchronized (sb) { 9651 report = sb.toString(); 9652 sb.delete(0, sb.length()); 9653 sb.trimToSize(); 9654 } 9655 if (report.length() != 0) { 9656 dbox.addText(dropboxTag, report); 9657 } 9658 } 9659 }.start(); 9660 return; 9661 } 9662 9663 // System app batching: 9664 if (!bufferWasEmpty) { 9665 // An existing dropbox-writing thread is outstanding, so 9666 // we don't need to start it up. The existing thread will 9667 // catch the buffer appends we just did. 9668 return; 9669 } 9670 9671 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9672 // (After this point, we shouldn't access AMS internal data structures.) 9673 new Thread("Error dump: " + dropboxTag) { 9674 @Override 9675 public void run() { 9676 // 5 second sleep to let stacks arrive and be batched together 9677 try { 9678 Thread.sleep(5000); // 5 seconds 9679 } catch (InterruptedException e) {} 9680 9681 String errorReport; 9682 synchronized (mStrictModeBuffer) { 9683 errorReport = mStrictModeBuffer.toString(); 9684 if (errorReport.length() == 0) { 9685 return; 9686 } 9687 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9688 mStrictModeBuffer.trimToSize(); 9689 } 9690 dbox.addText(dropboxTag, errorReport); 9691 } 9692 }.start(); 9693 } 9694 9695 /** 9696 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9697 * @param app object of the crashing app, null for the system server 9698 * @param tag reported by the caller 9699 * @param crashInfo describing the context of the error 9700 * @return true if the process should exit immediately (WTF is fatal) 9701 */ 9702 public boolean handleApplicationWtf(IBinder app, String tag, 9703 ApplicationErrorReport.CrashInfo crashInfo) { 9704 ProcessRecord r = findAppProcess(app, "WTF"); 9705 final String processName = app == null ? "system_server" 9706 : (r == null ? "unknown" : r.processName); 9707 9708 EventLog.writeEvent(EventLogTags.AM_WTF, 9709 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9710 processName, 9711 r == null ? -1 : r.info.flags, 9712 tag, crashInfo.exceptionMessage); 9713 9714 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9715 9716 if (r != null && r.pid != Process.myPid() && 9717 Settings.Global.getInt(mContext.getContentResolver(), 9718 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9719 crashApplication(r, crashInfo); 9720 return true; 9721 } else { 9722 return false; 9723 } 9724 } 9725 9726 /** 9727 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9728 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9729 */ 9730 private ProcessRecord findAppProcess(IBinder app, String reason) { 9731 if (app == null) { 9732 return null; 9733 } 9734 9735 synchronized (this) { 9736 final int NP = mProcessNames.getMap().size(); 9737 for (int ip=0; ip<NP; ip++) { 9738 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9739 final int NA = apps.size(); 9740 for (int ia=0; ia<NA; ia++) { 9741 ProcessRecord p = apps.valueAt(ia); 9742 if (p.thread != null && p.thread.asBinder() == app) { 9743 return p; 9744 } 9745 } 9746 } 9747 9748 Slog.w(TAG, "Can't find mystery application for " + reason 9749 + " from pid=" + Binder.getCallingPid() 9750 + " uid=" + Binder.getCallingUid() + ": " + app); 9751 return null; 9752 } 9753 } 9754 9755 /** 9756 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9757 * to append various headers to the dropbox log text. 9758 */ 9759 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9760 StringBuilder sb) { 9761 // Watchdog thread ends up invoking this function (with 9762 // a null ProcessRecord) to add the stack file to dropbox. 9763 // Do not acquire a lock on this (am) in such cases, as it 9764 // could cause a potential deadlock, if and when watchdog 9765 // is invoked due to unavailability of lock on am and it 9766 // would prevent watchdog from killing system_server. 9767 if (process == null) { 9768 sb.append("Process: ").append(processName).append("\n"); 9769 return; 9770 } 9771 // Note: ProcessRecord 'process' is guarded by the service 9772 // instance. (notably process.pkgList, which could otherwise change 9773 // concurrently during execution of this method) 9774 synchronized (this) { 9775 sb.append("Process: ").append(processName).append("\n"); 9776 int flags = process.info.flags; 9777 IPackageManager pm = AppGlobals.getPackageManager(); 9778 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 9779 for (int ip=0; ip<process.pkgList.size(); ip++) { 9780 String pkg = process.pkgList.keyAt(ip); 9781 sb.append("Package: ").append(pkg); 9782 try { 9783 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 9784 if (pi != null) { 9785 sb.append(" v").append(pi.versionCode); 9786 if (pi.versionName != null) { 9787 sb.append(" (").append(pi.versionName).append(")"); 9788 } 9789 } 9790 } catch (RemoteException e) { 9791 Slog.e(TAG, "Error getting package info: " + pkg, e); 9792 } 9793 sb.append("\n"); 9794 } 9795 } 9796 } 9797 9798 private static String processClass(ProcessRecord process) { 9799 if (process == null || process.pid == MY_PID) { 9800 return "system_server"; 9801 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9802 return "system_app"; 9803 } else { 9804 return "data_app"; 9805 } 9806 } 9807 9808 /** 9809 * Write a description of an error (crash, WTF, ANR) to the drop box. 9810 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 9811 * @param process which caused the error, null means the system server 9812 * @param activity which triggered the error, null if unknown 9813 * @param parent activity related to the error, null if unknown 9814 * @param subject line related to the error, null if absent 9815 * @param report in long form describing the error, null if absent 9816 * @param logFile to include in the report, null if none 9817 * @param crashInfo giving an application stack trace, null if absent 9818 */ 9819 public void addErrorToDropBox(String eventType, 9820 ProcessRecord process, String processName, ActivityRecord activity, 9821 ActivityRecord parent, String subject, 9822 final String report, final File logFile, 9823 final ApplicationErrorReport.CrashInfo crashInfo) { 9824 // NOTE -- this must never acquire the ActivityManagerService lock, 9825 // otherwise the watchdog may be prevented from resetting the system. 9826 9827 final String dropboxTag = processClass(process) + "_" + eventType; 9828 final DropBoxManager dbox = (DropBoxManager) 9829 mContext.getSystemService(Context.DROPBOX_SERVICE); 9830 9831 // Exit early if the dropbox isn't configured to accept this report type. 9832 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9833 9834 final StringBuilder sb = new StringBuilder(1024); 9835 appendDropBoxProcessHeaders(process, processName, sb); 9836 if (activity != null) { 9837 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 9838 } 9839 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 9840 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 9841 } 9842 if (parent != null && parent != activity) { 9843 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 9844 } 9845 if (subject != null) { 9846 sb.append("Subject: ").append(subject).append("\n"); 9847 } 9848 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9849 if (Debug.isDebuggerConnected()) { 9850 sb.append("Debugger: Connected\n"); 9851 } 9852 sb.append("\n"); 9853 9854 // Do the rest in a worker thread to avoid blocking the caller on I/O 9855 // (After this point, we shouldn't access AMS internal data structures.) 9856 Thread worker = new Thread("Error dump: " + dropboxTag) { 9857 @Override 9858 public void run() { 9859 if (report != null) { 9860 sb.append(report); 9861 } 9862 if (logFile != null) { 9863 try { 9864 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 9865 "\n\n[[TRUNCATED]]")); 9866 } catch (IOException e) { 9867 Slog.e(TAG, "Error reading " + logFile, e); 9868 } 9869 } 9870 if (crashInfo != null && crashInfo.stackTrace != null) { 9871 sb.append(crashInfo.stackTrace); 9872 } 9873 9874 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 9875 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 9876 if (lines > 0) { 9877 sb.append("\n"); 9878 9879 // Merge several logcat streams, and take the last N lines 9880 InputStreamReader input = null; 9881 try { 9882 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 9883 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 9884 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 9885 9886 try { logcat.getOutputStream().close(); } catch (IOException e) {} 9887 try { logcat.getErrorStream().close(); } catch (IOException e) {} 9888 input = new InputStreamReader(logcat.getInputStream()); 9889 9890 int num; 9891 char[] buf = new char[8192]; 9892 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 9893 } catch (IOException e) { 9894 Slog.e(TAG, "Error running logcat", e); 9895 } finally { 9896 if (input != null) try { input.close(); } catch (IOException e) {} 9897 } 9898 } 9899 9900 dbox.addText(dropboxTag, sb.toString()); 9901 } 9902 }; 9903 9904 if (process == null) { 9905 // If process is null, we are being called from some internal code 9906 // and may be about to die -- run this synchronously. 9907 worker.run(); 9908 } else { 9909 worker.start(); 9910 } 9911 } 9912 9913 /** 9914 * Bring up the "unexpected error" dialog box for a crashing app. 9915 * Deal with edge cases (intercepts from instrumented applications, 9916 * ActivityController, error intent receivers, that sort of thing). 9917 * @param r the application crashing 9918 * @param crashInfo describing the failure 9919 */ 9920 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 9921 long timeMillis = System.currentTimeMillis(); 9922 String shortMsg = crashInfo.exceptionClassName; 9923 String longMsg = crashInfo.exceptionMessage; 9924 String stackTrace = crashInfo.stackTrace; 9925 if (shortMsg != null && longMsg != null) { 9926 longMsg = shortMsg + ": " + longMsg; 9927 } else if (shortMsg != null) { 9928 longMsg = shortMsg; 9929 } 9930 9931 AppErrorResult result = new AppErrorResult(); 9932 synchronized (this) { 9933 if (mController != null) { 9934 try { 9935 String name = r != null ? r.processName : null; 9936 int pid = r != null ? r.pid : Binder.getCallingPid(); 9937 if (!mController.appCrashed(name, pid, 9938 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 9939 Slog.w(TAG, "Force-killing crashed app " + name 9940 + " at watcher's request"); 9941 Process.killProcess(pid); 9942 return; 9943 } 9944 } catch (RemoteException e) { 9945 mController = null; 9946 Watchdog.getInstance().setActivityController(null); 9947 } 9948 } 9949 9950 final long origId = Binder.clearCallingIdentity(); 9951 9952 // If this process is running instrumentation, finish it. 9953 if (r != null && r.instrumentationClass != null) { 9954 Slog.w(TAG, "Error in app " + r.processName 9955 + " running instrumentation " + r.instrumentationClass + ":"); 9956 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 9957 if (longMsg != null) Slog.w(TAG, " " + longMsg); 9958 Bundle info = new Bundle(); 9959 info.putString("shortMsg", shortMsg); 9960 info.putString("longMsg", longMsg); 9961 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 9962 Binder.restoreCallingIdentity(origId); 9963 return; 9964 } 9965 9966 // If we can't identify the process or it's already exceeded its crash quota, 9967 // quit right away without showing a crash dialog. 9968 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 9969 Binder.restoreCallingIdentity(origId); 9970 return; 9971 } 9972 9973 Message msg = Message.obtain(); 9974 msg.what = SHOW_ERROR_MSG; 9975 HashMap data = new HashMap(); 9976 data.put("result", result); 9977 data.put("app", r); 9978 msg.obj = data; 9979 mHandler.sendMessage(msg); 9980 9981 Binder.restoreCallingIdentity(origId); 9982 } 9983 9984 int res = result.get(); 9985 9986 Intent appErrorIntent = null; 9987 synchronized (this) { 9988 if (r != null && !r.isolated) { 9989 // XXX Can't keep track of crash time for isolated processes, 9990 // since they don't have a persistent identity. 9991 mProcessCrashTimes.put(r.info.processName, r.uid, 9992 SystemClock.uptimeMillis()); 9993 } 9994 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 9995 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 9996 } 9997 } 9998 9999 if (appErrorIntent != null) { 10000 try { 10001 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10002 } catch (ActivityNotFoundException e) { 10003 Slog.w(TAG, "bug report receiver dissappeared", e); 10004 } 10005 } 10006 } 10007 10008 Intent createAppErrorIntentLocked(ProcessRecord r, 10009 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10010 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10011 if (report == null) { 10012 return null; 10013 } 10014 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10015 result.setComponent(r.errorReportReceiver); 10016 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10017 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10018 return result; 10019 } 10020 10021 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10022 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10023 if (r.errorReportReceiver == null) { 10024 return null; 10025 } 10026 10027 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10028 return null; 10029 } 10030 10031 ApplicationErrorReport report = new ApplicationErrorReport(); 10032 report.packageName = r.info.packageName; 10033 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10034 report.processName = r.processName; 10035 report.time = timeMillis; 10036 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10037 10038 if (r.crashing || r.forceCrashReport) { 10039 report.type = ApplicationErrorReport.TYPE_CRASH; 10040 report.crashInfo = crashInfo; 10041 } else if (r.notResponding) { 10042 report.type = ApplicationErrorReport.TYPE_ANR; 10043 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10044 10045 report.anrInfo.activity = r.notRespondingReport.tag; 10046 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10047 report.anrInfo.info = r.notRespondingReport.longMsg; 10048 } 10049 10050 return report; 10051 } 10052 10053 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10054 enforceNotIsolatedCaller("getProcessesInErrorState"); 10055 // assume our apps are happy - lazy create the list 10056 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10057 10058 final boolean allUsers = ActivityManager.checkUidPermission( 10059 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10060 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10061 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10062 10063 synchronized (this) { 10064 10065 // iterate across all processes 10066 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10067 ProcessRecord app = mLruProcesses.get(i); 10068 if (!allUsers && app.userId != userId) { 10069 continue; 10070 } 10071 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10072 // This one's in trouble, so we'll generate a report for it 10073 // crashes are higher priority (in case there's a crash *and* an anr) 10074 ActivityManager.ProcessErrorStateInfo report = null; 10075 if (app.crashing) { 10076 report = app.crashingReport; 10077 } else if (app.notResponding) { 10078 report = app.notRespondingReport; 10079 } 10080 10081 if (report != null) { 10082 if (errList == null) { 10083 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10084 } 10085 errList.add(report); 10086 } else { 10087 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10088 " crashing = " + app.crashing + 10089 " notResponding = " + app.notResponding); 10090 } 10091 } 10092 } 10093 } 10094 10095 return errList; 10096 } 10097 10098 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10099 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10100 if (currApp != null) { 10101 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10102 } 10103 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10104 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10105 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10106 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10107 if (currApp != null) { 10108 currApp.lru = 0; 10109 } 10110 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10111 } else if (adj >= ProcessList.SERVICE_ADJ) { 10112 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10113 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10114 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10115 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10116 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10117 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10118 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10119 } else { 10120 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10121 } 10122 } 10123 10124 private void fillInProcMemInfo(ProcessRecord app, 10125 ActivityManager.RunningAppProcessInfo outInfo) { 10126 outInfo.pid = app.pid; 10127 outInfo.uid = app.info.uid; 10128 if (mHeavyWeightProcess == app) { 10129 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10130 } 10131 if (app.persistent) { 10132 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10133 } 10134 if (app.activities.size() > 0) { 10135 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10136 } 10137 outInfo.lastTrimLevel = app.trimMemoryLevel; 10138 int adj = app.curAdj; 10139 outInfo.importance = oomAdjToImportance(adj, outInfo); 10140 outInfo.importanceReasonCode = app.adjTypeCode; 10141 } 10142 10143 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10144 enforceNotIsolatedCaller("getRunningAppProcesses"); 10145 // Lazy instantiation of list 10146 List<ActivityManager.RunningAppProcessInfo> runList = null; 10147 final boolean allUsers = ActivityManager.checkUidPermission( 10148 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10149 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10150 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10151 synchronized (this) { 10152 // Iterate across all processes 10153 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10154 ProcessRecord app = mLruProcesses.get(i); 10155 if (!allUsers && app.userId != userId) { 10156 continue; 10157 } 10158 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10159 // Generate process state info for running application 10160 ActivityManager.RunningAppProcessInfo currApp = 10161 new ActivityManager.RunningAppProcessInfo(app.processName, 10162 app.pid, app.getPackageList()); 10163 fillInProcMemInfo(app, currApp); 10164 if (app.adjSource instanceof ProcessRecord) { 10165 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10166 currApp.importanceReasonImportance = oomAdjToImportance( 10167 app.adjSourceOom, null); 10168 } else if (app.adjSource instanceof ActivityRecord) { 10169 ActivityRecord r = (ActivityRecord)app.adjSource; 10170 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10171 } 10172 if (app.adjTarget instanceof ComponentName) { 10173 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10174 } 10175 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10176 // + " lru=" + currApp.lru); 10177 if (runList == null) { 10178 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10179 } 10180 runList.add(currApp); 10181 } 10182 } 10183 } 10184 return runList; 10185 } 10186 10187 public List<ApplicationInfo> getRunningExternalApplications() { 10188 enforceNotIsolatedCaller("getRunningExternalApplications"); 10189 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10190 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10191 if (runningApps != null && runningApps.size() > 0) { 10192 Set<String> extList = new HashSet<String>(); 10193 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10194 if (app.pkgList != null) { 10195 for (String pkg : app.pkgList) { 10196 extList.add(pkg); 10197 } 10198 } 10199 } 10200 IPackageManager pm = AppGlobals.getPackageManager(); 10201 for (String pkg : extList) { 10202 try { 10203 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10204 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10205 retList.add(info); 10206 } 10207 } catch (RemoteException e) { 10208 } 10209 } 10210 } 10211 return retList; 10212 } 10213 10214 @Override 10215 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10216 enforceNotIsolatedCaller("getMyMemoryState"); 10217 synchronized (this) { 10218 ProcessRecord proc; 10219 synchronized (mPidsSelfLocked) { 10220 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10221 } 10222 fillInProcMemInfo(proc, outInfo); 10223 } 10224 } 10225 10226 @Override 10227 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10228 if (checkCallingPermission(android.Manifest.permission.DUMP) 10229 != PackageManager.PERMISSION_GRANTED) { 10230 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10231 + Binder.getCallingPid() 10232 + ", uid=" + Binder.getCallingUid() 10233 + " without permission " 10234 + android.Manifest.permission.DUMP); 10235 return; 10236 } 10237 10238 boolean dumpAll = false; 10239 boolean dumpClient = false; 10240 String dumpPackage = null; 10241 10242 int opti = 0; 10243 while (opti < args.length) { 10244 String opt = args[opti]; 10245 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10246 break; 10247 } 10248 opti++; 10249 if ("-a".equals(opt)) { 10250 dumpAll = true; 10251 } else if ("-c".equals(opt)) { 10252 dumpClient = true; 10253 } else if ("-h".equals(opt)) { 10254 pw.println("Activity manager dump options:"); 10255 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10256 pw.println(" cmd may be one of:"); 10257 pw.println(" a[ctivities]: activity stack state"); 10258 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10259 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10260 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10261 pw.println(" o[om]: out of memory management"); 10262 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10263 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10264 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10265 pw.println(" service [COMP_SPEC]: service client-side state"); 10266 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10267 pw.println(" all: dump all activities"); 10268 pw.println(" top: dump the top activity"); 10269 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10270 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10271 pw.println(" a partial substring in a component name, a"); 10272 pw.println(" hex object identifier."); 10273 pw.println(" -a: include all available server state."); 10274 pw.println(" -c: include client state."); 10275 return; 10276 } else { 10277 pw.println("Unknown argument: " + opt + "; use -h for help"); 10278 } 10279 } 10280 10281 long origId = Binder.clearCallingIdentity(); 10282 boolean more = false; 10283 // Is the caller requesting to dump a particular piece of data? 10284 if (opti < args.length) { 10285 String cmd = args[opti]; 10286 opti++; 10287 if ("activities".equals(cmd) || "a".equals(cmd)) { 10288 synchronized (this) { 10289 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10290 } 10291 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10292 String[] newArgs; 10293 String name; 10294 if (opti >= args.length) { 10295 name = null; 10296 newArgs = EMPTY_STRING_ARRAY; 10297 } else { 10298 name = args[opti]; 10299 opti++; 10300 newArgs = new String[args.length - opti]; 10301 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10302 args.length - opti); 10303 } 10304 synchronized (this) { 10305 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10306 } 10307 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10308 String[] newArgs; 10309 String name; 10310 if (opti >= args.length) { 10311 name = null; 10312 newArgs = EMPTY_STRING_ARRAY; 10313 } else { 10314 name = args[opti]; 10315 opti++; 10316 newArgs = new String[args.length - opti]; 10317 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10318 args.length - opti); 10319 } 10320 synchronized (this) { 10321 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10322 } 10323 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10324 String[] newArgs; 10325 String name; 10326 if (opti >= args.length) { 10327 name = null; 10328 newArgs = EMPTY_STRING_ARRAY; 10329 } else { 10330 name = args[opti]; 10331 opti++; 10332 newArgs = new String[args.length - opti]; 10333 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10334 args.length - opti); 10335 } 10336 synchronized (this) { 10337 dumpProcessesLocked(fd, pw, args, opti, true, name); 10338 } 10339 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10340 synchronized (this) { 10341 dumpOomLocked(fd, pw, args, opti, true); 10342 } 10343 } else if ("provider".equals(cmd)) { 10344 String[] newArgs; 10345 String name; 10346 if (opti >= args.length) { 10347 name = null; 10348 newArgs = EMPTY_STRING_ARRAY; 10349 } else { 10350 name = args[opti]; 10351 opti++; 10352 newArgs = new String[args.length - opti]; 10353 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10354 } 10355 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10356 pw.println("No providers match: " + name); 10357 pw.println("Use -h for help."); 10358 } 10359 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10360 synchronized (this) { 10361 dumpProvidersLocked(fd, pw, args, opti, true, null); 10362 } 10363 } else if ("service".equals(cmd)) { 10364 String[] newArgs; 10365 String name; 10366 if (opti >= args.length) { 10367 name = null; 10368 newArgs = EMPTY_STRING_ARRAY; 10369 } else { 10370 name = args[opti]; 10371 opti++; 10372 newArgs = new String[args.length - opti]; 10373 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10374 args.length - opti); 10375 } 10376 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10377 pw.println("No services match: " + name); 10378 pw.println("Use -h for help."); 10379 } 10380 } else if ("package".equals(cmd)) { 10381 String[] newArgs; 10382 if (opti >= args.length) { 10383 pw.println("package: no package name specified"); 10384 pw.println("Use -h for help."); 10385 } else { 10386 dumpPackage = args[opti]; 10387 opti++; 10388 newArgs = new String[args.length - opti]; 10389 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10390 args.length - opti); 10391 args = newArgs; 10392 opti = 0; 10393 more = true; 10394 } 10395 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10396 synchronized (this) { 10397 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10398 } 10399 } else { 10400 // Dumping a single activity? 10401 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10402 pw.println("Bad activity command, or no activities match: " + cmd); 10403 pw.println("Use -h for help."); 10404 } 10405 } 10406 if (!more) { 10407 Binder.restoreCallingIdentity(origId); 10408 return; 10409 } 10410 } 10411 10412 // No piece of data specified, dump everything. 10413 synchronized (this) { 10414 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10415 pw.println(); 10416 if (dumpAll) { 10417 pw.println("-------------------------------------------------------------------------------"); 10418 } 10419 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10420 pw.println(); 10421 if (dumpAll) { 10422 pw.println("-------------------------------------------------------------------------------"); 10423 } 10424 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10425 pw.println(); 10426 if (dumpAll) { 10427 pw.println("-------------------------------------------------------------------------------"); 10428 } 10429 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10430 pw.println(); 10431 if (dumpAll) { 10432 pw.println("-------------------------------------------------------------------------------"); 10433 } 10434 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10435 pw.println(); 10436 if (dumpAll) { 10437 pw.println("-------------------------------------------------------------------------------"); 10438 } 10439 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10440 } 10441 Binder.restoreCallingIdentity(origId); 10442 } 10443 10444 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10445 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10446 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10447 10448 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10449 dumpPackage); 10450 boolean needSep = printedAnything; 10451 10452 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10453 dumpPackage, needSep, " mFocusedActivity: "); 10454 if (printed) { 10455 printedAnything = true; 10456 needSep = false; 10457 } 10458 10459 if (dumpPackage == null) { 10460 if (needSep) { 10461 pw.println(); 10462 } 10463 needSep = true; 10464 printedAnything = true; 10465 mStackSupervisor.dump(pw, " "); 10466 } 10467 10468 if (mRecentTasks.size() > 0) { 10469 boolean printedHeader = false; 10470 10471 final int N = mRecentTasks.size(); 10472 for (int i=0; i<N; i++) { 10473 TaskRecord tr = mRecentTasks.get(i); 10474 if (dumpPackage != null) { 10475 if (tr.realActivity == null || 10476 !dumpPackage.equals(tr.realActivity)) { 10477 continue; 10478 } 10479 } 10480 if (!printedHeader) { 10481 if (needSep) { 10482 pw.println(); 10483 } 10484 pw.println(" Recent tasks:"); 10485 printedHeader = true; 10486 printedAnything = true; 10487 } 10488 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10489 pw.println(tr); 10490 if (dumpAll) { 10491 mRecentTasks.get(i).dump(pw, " "); 10492 } 10493 } 10494 } 10495 10496 if (!printedAnything) { 10497 pw.println(" (nothing)"); 10498 } 10499 } 10500 10501 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10502 int opti, boolean dumpAll, String dumpPackage) { 10503 boolean needSep = false; 10504 boolean printedAnything = false; 10505 int numPers = 0; 10506 10507 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10508 10509 if (dumpAll) { 10510 final int NP = mProcessNames.getMap().size(); 10511 for (int ip=0; ip<NP; ip++) { 10512 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10513 final int NA = procs.size(); 10514 for (int ia=0; ia<NA; ia++) { 10515 ProcessRecord r = procs.valueAt(ia); 10516 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10517 continue; 10518 } 10519 if (!needSep) { 10520 pw.println(" All known processes:"); 10521 needSep = true; 10522 printedAnything = true; 10523 } 10524 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10525 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10526 pw.print(" "); pw.println(r); 10527 r.dump(pw, " "); 10528 if (r.persistent) { 10529 numPers++; 10530 } 10531 } 10532 } 10533 } 10534 10535 if (mIsolatedProcesses.size() > 0) { 10536 boolean printed = false; 10537 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10538 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10539 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10540 continue; 10541 } 10542 if (!printed) { 10543 if (needSep) { 10544 pw.println(); 10545 } 10546 pw.println(" Isolated process list (sorted by uid):"); 10547 printedAnything = true; 10548 printed = true; 10549 needSep = true; 10550 } 10551 pw.println(String.format("%sIsolated #%2d: %s", 10552 " ", i, r.toString())); 10553 } 10554 } 10555 10556 if (mLruProcesses.size() > 0) { 10557 if (needSep) { 10558 pw.println(); 10559 } 10560 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10561 pw.print(" total, non-act at "); 10562 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10563 pw.print(", non-svc at "); 10564 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10565 pw.println("):"); 10566 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10567 needSep = true; 10568 printedAnything = true; 10569 } 10570 10571 if (dumpAll || dumpPackage != null) { 10572 synchronized (mPidsSelfLocked) { 10573 boolean printed = false; 10574 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10575 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10576 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10577 continue; 10578 } 10579 if (!printed) { 10580 if (needSep) pw.println(); 10581 needSep = true; 10582 pw.println(" PID mappings:"); 10583 printed = true; 10584 printedAnything = true; 10585 } 10586 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10587 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10588 } 10589 } 10590 } 10591 10592 if (mForegroundProcesses.size() > 0) { 10593 synchronized (mPidsSelfLocked) { 10594 boolean printed = false; 10595 for (int i=0; i<mForegroundProcesses.size(); i++) { 10596 ProcessRecord r = mPidsSelfLocked.get( 10597 mForegroundProcesses.valueAt(i).pid); 10598 if (dumpPackage != null && (r == null 10599 || !r.pkgList.containsKey(dumpPackage))) { 10600 continue; 10601 } 10602 if (!printed) { 10603 if (needSep) pw.println(); 10604 needSep = true; 10605 pw.println(" Foreground Processes:"); 10606 printed = true; 10607 printedAnything = true; 10608 } 10609 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10610 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10611 } 10612 } 10613 } 10614 10615 if (mPersistentStartingProcesses.size() > 0) { 10616 if (needSep) pw.println(); 10617 needSep = true; 10618 printedAnything = true; 10619 pw.println(" Persisent processes that are starting:"); 10620 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10621 "Starting Norm", "Restarting PERS", dumpPackage); 10622 } 10623 10624 if (mRemovedProcesses.size() > 0) { 10625 if (needSep) pw.println(); 10626 needSep = true; 10627 printedAnything = true; 10628 pw.println(" Processes that are being removed:"); 10629 dumpProcessList(pw, this, mRemovedProcesses, " ", 10630 "Removed Norm", "Removed PERS", dumpPackage); 10631 } 10632 10633 if (mProcessesOnHold.size() > 0) { 10634 if (needSep) pw.println(); 10635 needSep = true; 10636 printedAnything = true; 10637 pw.println(" Processes that are on old until the system is ready:"); 10638 dumpProcessList(pw, this, mProcessesOnHold, " ", 10639 "OnHold Norm", "OnHold PERS", dumpPackage); 10640 } 10641 10642 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10643 10644 if (mProcessCrashTimes.getMap().size() > 0) { 10645 boolean printed = false; 10646 long now = SystemClock.uptimeMillis(); 10647 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10648 final int NP = pmap.size(); 10649 for (int ip=0; ip<NP; ip++) { 10650 String pname = pmap.keyAt(ip); 10651 SparseArray<Long> uids = pmap.valueAt(ip); 10652 final int N = uids.size(); 10653 for (int i=0; i<N; i++) { 10654 int puid = uids.keyAt(i); 10655 ProcessRecord r = mProcessNames.get(pname, puid); 10656 if (dumpPackage != null && (r == null 10657 || !r.pkgList.containsKey(dumpPackage))) { 10658 continue; 10659 } 10660 if (!printed) { 10661 if (needSep) pw.println(); 10662 needSep = true; 10663 pw.println(" Time since processes crashed:"); 10664 printed = true; 10665 printedAnything = true; 10666 } 10667 pw.print(" Process "); pw.print(pname); 10668 pw.print(" uid "); pw.print(puid); 10669 pw.print(": last crashed "); 10670 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10671 pw.println(" ago"); 10672 } 10673 } 10674 } 10675 10676 if (mBadProcesses.getMap().size() > 0) { 10677 boolean printed = false; 10678 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10679 final int NP = pmap.size(); 10680 for (int ip=0; ip<NP; ip++) { 10681 String pname = pmap.keyAt(ip); 10682 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10683 final int N = uids.size(); 10684 for (int i=0; i<N; i++) { 10685 int puid = uids.keyAt(i); 10686 ProcessRecord r = mProcessNames.get(pname, puid); 10687 if (dumpPackage != null && (r == null 10688 || !r.pkgList.containsKey(dumpPackage))) { 10689 continue; 10690 } 10691 if (!printed) { 10692 if (needSep) pw.println(); 10693 needSep = true; 10694 pw.println(" Bad processes:"); 10695 printedAnything = true; 10696 } 10697 BadProcessInfo info = uids.valueAt(i); 10698 pw.print(" Bad process "); pw.print(pname); 10699 pw.print(" uid "); pw.print(puid); 10700 pw.print(": crashed at time "); pw.println(info.time); 10701 if (info.shortMsg != null) { 10702 pw.print(" Short msg: "); pw.println(info.shortMsg); 10703 } 10704 if (info.longMsg != null) { 10705 pw.print(" Long msg: "); pw.println(info.longMsg); 10706 } 10707 if (info.stack != null) { 10708 pw.println(" Stack:"); 10709 int lastPos = 0; 10710 for (int pos=0; pos<info.stack.length(); pos++) { 10711 if (info.stack.charAt(pos) == '\n') { 10712 pw.print(" "); 10713 pw.write(info.stack, lastPos, pos-lastPos); 10714 pw.println(); 10715 lastPos = pos+1; 10716 } 10717 } 10718 if (lastPos < info.stack.length()) { 10719 pw.print(" "); 10720 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10721 pw.println(); 10722 } 10723 } 10724 } 10725 } 10726 } 10727 10728 if (dumpPackage == null) { 10729 pw.println(); 10730 needSep = false; 10731 pw.println(" mStartedUsers:"); 10732 for (int i=0; i<mStartedUsers.size(); i++) { 10733 UserStartedState uss = mStartedUsers.valueAt(i); 10734 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10735 pw.print(": "); uss.dump("", pw); 10736 } 10737 pw.print(" mStartedUserArray: ["); 10738 for (int i=0; i<mStartedUserArray.length; i++) { 10739 if (i > 0) pw.print(", "); 10740 pw.print(mStartedUserArray[i]); 10741 } 10742 pw.println("]"); 10743 pw.print(" mUserLru: ["); 10744 for (int i=0; i<mUserLru.size(); i++) { 10745 if (i > 0) pw.print(", "); 10746 pw.print(mUserLru.get(i)); 10747 } 10748 pw.println("]"); 10749 if (dumpAll) { 10750 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10751 } 10752 } 10753 if (mHomeProcess != null && (dumpPackage == null 10754 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10755 if (needSep) { 10756 pw.println(); 10757 needSep = false; 10758 } 10759 pw.println(" mHomeProcess: " + mHomeProcess); 10760 } 10761 if (mPreviousProcess != null && (dumpPackage == null 10762 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 10763 if (needSep) { 10764 pw.println(); 10765 needSep = false; 10766 } 10767 pw.println(" mPreviousProcess: " + mPreviousProcess); 10768 } 10769 if (dumpAll) { 10770 StringBuilder sb = new StringBuilder(128); 10771 sb.append(" mPreviousProcessVisibleTime: "); 10772 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 10773 pw.println(sb); 10774 } 10775 if (mHeavyWeightProcess != null && (dumpPackage == null 10776 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 10777 if (needSep) { 10778 pw.println(); 10779 needSep = false; 10780 } 10781 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10782 } 10783 if (dumpPackage == null) { 10784 pw.println(" mConfiguration: " + mConfiguration); 10785 } 10786 if (dumpAll) { 10787 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 10788 if (mCompatModePackages.getPackages().size() > 0) { 10789 boolean printed = false; 10790 for (Map.Entry<String, Integer> entry 10791 : mCompatModePackages.getPackages().entrySet()) { 10792 String pkg = entry.getKey(); 10793 int mode = entry.getValue(); 10794 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 10795 continue; 10796 } 10797 if (!printed) { 10798 pw.println(" mScreenCompatPackages:"); 10799 printed = true; 10800 } 10801 pw.print(" "); pw.print(pkg); pw.print(": "); 10802 pw.print(mode); pw.println(); 10803 } 10804 } 10805 } 10806 if (dumpPackage == null) { 10807 if (mSleeping || mWentToSleep || mLockScreenShown) { 10808 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 10809 + " mLockScreenShown " + mLockScreenShown); 10810 } 10811 if (mShuttingDown) { 10812 pw.println(" mShuttingDown=" + mShuttingDown); 10813 } 10814 } 10815 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 10816 || mOrigWaitForDebugger) { 10817 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 10818 || dumpPackage.equals(mOrigDebugApp)) { 10819 if (needSep) { 10820 pw.println(); 10821 needSep = false; 10822 } 10823 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 10824 + " mDebugTransient=" + mDebugTransient 10825 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 10826 } 10827 } 10828 if (mOpenGlTraceApp != null) { 10829 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 10830 if (needSep) { 10831 pw.println(); 10832 needSep = false; 10833 } 10834 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 10835 } 10836 } 10837 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 10838 || mProfileFd != null) { 10839 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 10840 if (needSep) { 10841 pw.println(); 10842 needSep = false; 10843 } 10844 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 10845 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 10846 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 10847 + mAutoStopProfiler); 10848 } 10849 } 10850 if (dumpPackage == null) { 10851 if (mAlwaysFinishActivities || mController != null) { 10852 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 10853 + " mController=" + mController); 10854 } 10855 if (dumpAll) { 10856 pw.println(" Total persistent processes: " + numPers); 10857 pw.println(" mProcessesReady=" + mProcessesReady 10858 + " mSystemReady=" + mSystemReady); 10859 pw.println(" mBooting=" + mBooting 10860 + " mBooted=" + mBooted 10861 + " mFactoryTest=" + mFactoryTest); 10862 pw.print(" mLastPowerCheckRealtime="); 10863 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 10864 pw.println(""); 10865 pw.print(" mLastPowerCheckUptime="); 10866 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 10867 pw.println(""); 10868 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 10869 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 10870 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 10871 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 10872 + " (" + mLruProcesses.size() + " total)" 10873 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 10874 + " mNumServiceProcs=" + mNumServiceProcs 10875 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 10876 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 10877 + " mLastMemoryLevel" + mLastMemoryLevel 10878 + " mLastNumProcesses" + mLastNumProcesses); 10879 long now = SystemClock.uptimeMillis(); 10880 pw.print(" mLastIdleTime="); 10881 TimeUtils.formatDuration(now, mLastIdleTime, pw); 10882 pw.print(" mLowRamSinceLastIdle="); 10883 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 10884 pw.println(); 10885 } 10886 } 10887 10888 if (!printedAnything) { 10889 pw.println(" (nothing)"); 10890 } 10891 } 10892 10893 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 10894 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 10895 if (mProcessesToGc.size() > 0) { 10896 boolean printed = false; 10897 long now = SystemClock.uptimeMillis(); 10898 for (int i=0; i<mProcessesToGc.size(); i++) { 10899 ProcessRecord proc = mProcessesToGc.get(i); 10900 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 10901 continue; 10902 } 10903 if (!printed) { 10904 if (needSep) pw.println(); 10905 needSep = true; 10906 pw.println(" Processes that are waiting to GC:"); 10907 printed = true; 10908 } 10909 pw.print(" Process "); pw.println(proc); 10910 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 10911 pw.print(", last gced="); 10912 pw.print(now-proc.lastRequestedGc); 10913 pw.print(" ms ago, last lowMem="); 10914 pw.print(now-proc.lastLowMemory); 10915 pw.println(" ms ago"); 10916 10917 } 10918 } 10919 return needSep; 10920 } 10921 10922 void printOomLevel(PrintWriter pw, String name, int adj) { 10923 pw.print(" "); 10924 if (adj >= 0) { 10925 pw.print(' '); 10926 if (adj < 10) pw.print(' '); 10927 } else { 10928 if (adj > -10) pw.print(' '); 10929 } 10930 pw.print(adj); 10931 pw.print(": "); 10932 pw.print(name); 10933 pw.print(" ("); 10934 pw.print(mProcessList.getMemLevel(adj)/1024); 10935 pw.println(" kB)"); 10936 } 10937 10938 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10939 int opti, boolean dumpAll) { 10940 boolean needSep = false; 10941 10942 if (mLruProcesses.size() > 0) { 10943 if (needSep) pw.println(); 10944 needSep = true; 10945 pw.println(" OOM levels:"); 10946 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 10947 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 10948 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 10949 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 10950 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 10951 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 10952 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 10953 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 10954 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 10955 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 10956 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 10957 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 10958 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 10959 10960 if (needSep) pw.println(); 10961 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 10962 pw.print(" total, non-act at "); 10963 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10964 pw.print(", non-svc at "); 10965 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10966 pw.println("):"); 10967 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 10968 needSep = true; 10969 } 10970 10971 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 10972 10973 pw.println(); 10974 pw.println(" mHomeProcess: " + mHomeProcess); 10975 pw.println(" mPreviousProcess: " + mPreviousProcess); 10976 if (mHeavyWeightProcess != null) { 10977 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10978 } 10979 10980 return true; 10981 } 10982 10983 /** 10984 * There are three ways to call this: 10985 * - no provider specified: dump all the providers 10986 * - a flattened component name that matched an existing provider was specified as the 10987 * first arg: dump that one provider 10988 * - the first arg isn't the flattened component name of an existing provider: 10989 * dump all providers whose component contains the first arg as a substring 10990 */ 10991 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 10992 int opti, boolean dumpAll) { 10993 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 10994 } 10995 10996 static class ItemMatcher { 10997 ArrayList<ComponentName> components; 10998 ArrayList<String> strings; 10999 ArrayList<Integer> objects; 11000 boolean all; 11001 11002 ItemMatcher() { 11003 all = true; 11004 } 11005 11006 void build(String name) { 11007 ComponentName componentName = ComponentName.unflattenFromString(name); 11008 if (componentName != null) { 11009 if (components == null) { 11010 components = new ArrayList<ComponentName>(); 11011 } 11012 components.add(componentName); 11013 all = false; 11014 } else { 11015 int objectId = 0; 11016 // Not a '/' separated full component name; maybe an object ID? 11017 try { 11018 objectId = Integer.parseInt(name, 16); 11019 if (objects == null) { 11020 objects = new ArrayList<Integer>(); 11021 } 11022 objects.add(objectId); 11023 all = false; 11024 } catch (RuntimeException e) { 11025 // Not an integer; just do string match. 11026 if (strings == null) { 11027 strings = new ArrayList<String>(); 11028 } 11029 strings.add(name); 11030 all = false; 11031 } 11032 } 11033 } 11034 11035 int build(String[] args, int opti) { 11036 for (; opti<args.length; opti++) { 11037 String name = args[opti]; 11038 if ("--".equals(name)) { 11039 return opti+1; 11040 } 11041 build(name); 11042 } 11043 return opti; 11044 } 11045 11046 boolean match(Object object, ComponentName comp) { 11047 if (all) { 11048 return true; 11049 } 11050 if (components != null) { 11051 for (int i=0; i<components.size(); i++) { 11052 if (components.get(i).equals(comp)) { 11053 return true; 11054 } 11055 } 11056 } 11057 if (objects != null) { 11058 for (int i=0; i<objects.size(); i++) { 11059 if (System.identityHashCode(object) == objects.get(i)) { 11060 return true; 11061 } 11062 } 11063 } 11064 if (strings != null) { 11065 String flat = comp.flattenToString(); 11066 for (int i=0; i<strings.size(); i++) { 11067 if (flat.contains(strings.get(i))) { 11068 return true; 11069 } 11070 } 11071 } 11072 return false; 11073 } 11074 } 11075 11076 /** 11077 * There are three things that cmd can be: 11078 * - a flattened component name that matches an existing activity 11079 * - the cmd arg isn't the flattened component name of an existing activity: 11080 * dump all activity whose component contains the cmd as a substring 11081 * - A hex number of the ActivityRecord object instance. 11082 */ 11083 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11084 int opti, boolean dumpAll) { 11085 ArrayList<ActivityRecord> activities; 11086 11087 synchronized (this) { 11088 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11089 } 11090 11091 if (activities.size() <= 0) { 11092 return false; 11093 } 11094 11095 String[] newArgs = new String[args.length - opti]; 11096 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11097 11098 TaskRecord lastTask = null; 11099 boolean needSep = false; 11100 for (int i=activities.size()-1; i>=0; i--) { 11101 ActivityRecord r = activities.get(i); 11102 if (needSep) { 11103 pw.println(); 11104 } 11105 needSep = true; 11106 synchronized (this) { 11107 if (lastTask != r.task) { 11108 lastTask = r.task; 11109 pw.print("TASK "); pw.print(lastTask.affinity); 11110 pw.print(" id="); pw.println(lastTask.taskId); 11111 if (dumpAll) { 11112 lastTask.dump(pw, " "); 11113 } 11114 } 11115 } 11116 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11117 } 11118 return true; 11119 } 11120 11121 /** 11122 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11123 * there is a thread associated with the activity. 11124 */ 11125 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11126 final ActivityRecord r, String[] args, boolean dumpAll) { 11127 String innerPrefix = prefix + " "; 11128 synchronized (this) { 11129 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11130 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11131 pw.print(" pid="); 11132 if (r.app != null) pw.println(r.app.pid); 11133 else pw.println("(not running)"); 11134 if (dumpAll) { 11135 r.dump(pw, innerPrefix); 11136 } 11137 } 11138 if (r.app != null && r.app.thread != null) { 11139 // flush anything that is already in the PrintWriter since the thread is going 11140 // to write to the file descriptor directly 11141 pw.flush(); 11142 try { 11143 TransferPipe tp = new TransferPipe(); 11144 try { 11145 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11146 r.appToken, innerPrefix, args); 11147 tp.go(fd); 11148 } finally { 11149 tp.kill(); 11150 } 11151 } catch (IOException e) { 11152 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11153 } catch (RemoteException e) { 11154 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11155 } 11156 } 11157 } 11158 11159 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11160 int opti, boolean dumpAll, String dumpPackage) { 11161 boolean needSep = false; 11162 boolean onlyHistory = false; 11163 boolean printedAnything = false; 11164 11165 if ("history".equals(dumpPackage)) { 11166 if (opti < args.length && "-s".equals(args[opti])) { 11167 dumpAll = false; 11168 } 11169 onlyHistory = true; 11170 dumpPackage = null; 11171 } 11172 11173 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11174 if (!onlyHistory && dumpAll) { 11175 if (mRegisteredReceivers.size() > 0) { 11176 boolean printed = false; 11177 Iterator it = mRegisteredReceivers.values().iterator(); 11178 while (it.hasNext()) { 11179 ReceiverList r = (ReceiverList)it.next(); 11180 if (dumpPackage != null && (r.app == null || 11181 !dumpPackage.equals(r.app.info.packageName))) { 11182 continue; 11183 } 11184 if (!printed) { 11185 pw.println(" Registered Receivers:"); 11186 needSep = true; 11187 printed = true; 11188 printedAnything = true; 11189 } 11190 pw.print(" * "); pw.println(r); 11191 r.dump(pw, " "); 11192 } 11193 } 11194 11195 if (mReceiverResolver.dump(pw, needSep ? 11196 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11197 " ", dumpPackage, false)) { 11198 needSep = true; 11199 printedAnything = true; 11200 } 11201 } 11202 11203 for (BroadcastQueue q : mBroadcastQueues) { 11204 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11205 printedAnything |= needSep; 11206 } 11207 11208 needSep = true; 11209 11210 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11211 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11212 if (needSep) { 11213 pw.println(); 11214 } 11215 needSep = true; 11216 printedAnything = true; 11217 pw.print(" Sticky broadcasts for user "); 11218 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11219 StringBuilder sb = new StringBuilder(128); 11220 for (Map.Entry<String, ArrayList<Intent>> ent 11221 : mStickyBroadcasts.valueAt(user).entrySet()) { 11222 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11223 if (dumpAll) { 11224 pw.println(":"); 11225 ArrayList<Intent> intents = ent.getValue(); 11226 final int N = intents.size(); 11227 for (int i=0; i<N; i++) { 11228 sb.setLength(0); 11229 sb.append(" Intent: "); 11230 intents.get(i).toShortString(sb, false, true, false, false); 11231 pw.println(sb.toString()); 11232 Bundle bundle = intents.get(i).getExtras(); 11233 if (bundle != null) { 11234 pw.print(" "); 11235 pw.println(bundle.toString()); 11236 } 11237 } 11238 } else { 11239 pw.println(""); 11240 } 11241 } 11242 } 11243 } 11244 11245 if (!onlyHistory && dumpAll) { 11246 pw.println(); 11247 for (BroadcastQueue queue : mBroadcastQueues) { 11248 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11249 + queue.mBroadcastsScheduled); 11250 } 11251 pw.println(" mHandler:"); 11252 mHandler.dump(new PrintWriterPrinter(pw), " "); 11253 needSep = true; 11254 printedAnything = true; 11255 } 11256 11257 if (!printedAnything) { 11258 pw.println(" (nothing)"); 11259 } 11260 } 11261 11262 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11263 int opti, boolean dumpAll, String dumpPackage) { 11264 boolean needSep; 11265 boolean printedAnything = false; 11266 11267 ItemMatcher matcher = new ItemMatcher(); 11268 matcher.build(args, opti); 11269 11270 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11271 11272 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11273 printedAnything |= needSep; 11274 11275 if (mLaunchingProviders.size() > 0) { 11276 boolean printed = false; 11277 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11278 ContentProviderRecord r = mLaunchingProviders.get(i); 11279 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11280 continue; 11281 } 11282 if (!printed) { 11283 if (needSep) pw.println(); 11284 needSep = true; 11285 pw.println(" Launching content providers:"); 11286 printed = true; 11287 printedAnything = true; 11288 } 11289 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11290 pw.println(r); 11291 } 11292 } 11293 11294 if (mGrantedUriPermissions.size() > 0) { 11295 boolean printed = false; 11296 int dumpUid = -2; 11297 if (dumpPackage != null) { 11298 try { 11299 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11300 } catch (NameNotFoundException e) { 11301 dumpUid = -1; 11302 } 11303 } 11304 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11305 int uid = mGrantedUriPermissions.keyAt(i); 11306 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11307 continue; 11308 } 11309 ArrayMap<Uri, UriPermission> perms 11310 = mGrantedUriPermissions.valueAt(i); 11311 if (!printed) { 11312 if (needSep) pw.println(); 11313 needSep = true; 11314 pw.println(" Granted Uri Permissions:"); 11315 printed = true; 11316 printedAnything = true; 11317 } 11318 pw.print(" * UID "); pw.print(uid); 11319 pw.println(" holds:"); 11320 for (UriPermission perm : perms.values()) { 11321 pw.print(" "); pw.println(perm); 11322 if (dumpAll) { 11323 perm.dump(pw, " "); 11324 } 11325 } 11326 } 11327 } 11328 11329 if (!printedAnything) { 11330 pw.println(" (nothing)"); 11331 } 11332 } 11333 11334 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11335 int opti, boolean dumpAll, String dumpPackage) { 11336 boolean printed = false; 11337 11338 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11339 11340 if (mIntentSenderRecords.size() > 0) { 11341 Iterator<WeakReference<PendingIntentRecord>> it 11342 = mIntentSenderRecords.values().iterator(); 11343 while (it.hasNext()) { 11344 WeakReference<PendingIntentRecord> ref = it.next(); 11345 PendingIntentRecord rec = ref != null ? ref.get(): null; 11346 if (dumpPackage != null && (rec == null 11347 || !dumpPackage.equals(rec.key.packageName))) { 11348 continue; 11349 } 11350 printed = true; 11351 if (rec != null) { 11352 pw.print(" * "); pw.println(rec); 11353 if (dumpAll) { 11354 rec.dump(pw, " "); 11355 } 11356 } else { 11357 pw.print(" * "); pw.println(ref); 11358 } 11359 } 11360 } 11361 11362 if (!printed) { 11363 pw.println(" (nothing)"); 11364 } 11365 } 11366 11367 private static final int dumpProcessList(PrintWriter pw, 11368 ActivityManagerService service, List list, 11369 String prefix, String normalLabel, String persistentLabel, 11370 String dumpPackage) { 11371 int numPers = 0; 11372 final int N = list.size()-1; 11373 for (int i=N; i>=0; i--) { 11374 ProcessRecord r = (ProcessRecord)list.get(i); 11375 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11376 continue; 11377 } 11378 pw.println(String.format("%s%s #%2d: %s", 11379 prefix, (r.persistent ? persistentLabel : normalLabel), 11380 i, r.toString())); 11381 if (r.persistent) { 11382 numPers++; 11383 } 11384 } 11385 return numPers; 11386 } 11387 11388 private static final boolean dumpProcessOomList(PrintWriter pw, 11389 ActivityManagerService service, List<ProcessRecord> origList, 11390 String prefix, String normalLabel, String persistentLabel, 11391 boolean inclDetails, String dumpPackage) { 11392 11393 ArrayList<Pair<ProcessRecord, Integer>> list 11394 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11395 for (int i=0; i<origList.size(); i++) { 11396 ProcessRecord r = origList.get(i); 11397 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11398 continue; 11399 } 11400 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11401 } 11402 11403 if (list.size() <= 0) { 11404 return false; 11405 } 11406 11407 Comparator<Pair<ProcessRecord, Integer>> comparator 11408 = new Comparator<Pair<ProcessRecord, Integer>>() { 11409 @Override 11410 public int compare(Pair<ProcessRecord, Integer> object1, 11411 Pair<ProcessRecord, Integer> object2) { 11412 if (object1.first.setAdj != object2.first.setAdj) { 11413 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11414 } 11415 if (object1.second.intValue() != object2.second.intValue()) { 11416 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11417 } 11418 return 0; 11419 } 11420 }; 11421 11422 Collections.sort(list, comparator); 11423 11424 final long curRealtime = SystemClock.elapsedRealtime(); 11425 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11426 final long curUptime = SystemClock.uptimeMillis(); 11427 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11428 11429 for (int i=list.size()-1; i>=0; i--) { 11430 ProcessRecord r = list.get(i).first; 11431 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11432 char schedGroup; 11433 switch (r.setSchedGroup) { 11434 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11435 schedGroup = 'B'; 11436 break; 11437 case Process.THREAD_GROUP_DEFAULT: 11438 schedGroup = 'F'; 11439 break; 11440 default: 11441 schedGroup = '?'; 11442 break; 11443 } 11444 char foreground; 11445 if (r.foregroundActivities) { 11446 foreground = 'A'; 11447 } else if (r.foregroundServices) { 11448 foreground = 'S'; 11449 } else { 11450 foreground = ' '; 11451 } 11452 String procState = ProcessList.makeProcStateString(r.curProcState); 11453 pw.print(prefix); 11454 pw.print(r.persistent ? persistentLabel : normalLabel); 11455 pw.print(" #"); 11456 int num = (origList.size()-1)-list.get(i).second; 11457 if (num < 10) pw.print(' '); 11458 pw.print(num); 11459 pw.print(": "); 11460 pw.print(oomAdj); 11461 pw.print(' '); 11462 pw.print(schedGroup); 11463 pw.print('/'); 11464 pw.print(foreground); 11465 pw.print('/'); 11466 pw.print(procState); 11467 pw.print(" trm:"); 11468 if (r.trimMemoryLevel < 10) pw.print(' '); 11469 pw.print(r.trimMemoryLevel); 11470 pw.print(' '); 11471 pw.print(r.toShortString()); 11472 pw.print(" ("); 11473 pw.print(r.adjType); 11474 pw.println(')'); 11475 if (r.adjSource != null || r.adjTarget != null) { 11476 pw.print(prefix); 11477 pw.print(" "); 11478 if (r.adjTarget instanceof ComponentName) { 11479 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11480 } else if (r.adjTarget != null) { 11481 pw.print(r.adjTarget.toString()); 11482 } else { 11483 pw.print("{null}"); 11484 } 11485 pw.print("<="); 11486 if (r.adjSource instanceof ProcessRecord) { 11487 pw.print("Proc{"); 11488 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11489 pw.println("}"); 11490 } else if (r.adjSource != null) { 11491 pw.println(r.adjSource.toString()); 11492 } else { 11493 pw.println("{null}"); 11494 } 11495 } 11496 if (inclDetails) { 11497 pw.print(prefix); 11498 pw.print(" "); 11499 pw.print("oom: max="); pw.print(r.maxAdj); 11500 pw.print(" curRaw="); pw.print(r.curRawAdj); 11501 pw.print(" setRaw="); pw.print(r.setRawAdj); 11502 pw.print(" cur="); pw.print(r.curAdj); 11503 pw.print(" set="); pw.println(r.setAdj); 11504 pw.print(prefix); 11505 pw.print(" "); 11506 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11507 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11508 pw.print(" lastPss="); pw.print(r.lastPss); 11509 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11510 pw.print(prefix); 11511 pw.print(" "); 11512 pw.print("keeping="); pw.print(r.keeping); 11513 pw.print(" cached="); pw.print(r.cached); 11514 pw.print(" empty="); pw.print(r.empty); 11515 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11516 11517 if (!r.keeping) { 11518 if (r.lastWakeTime != 0) { 11519 long wtime; 11520 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11521 synchronized (stats) { 11522 wtime = stats.getProcessWakeTime(r.info.uid, 11523 r.pid, curRealtime); 11524 } 11525 long timeUsed = wtime - r.lastWakeTime; 11526 pw.print(prefix); 11527 pw.print(" "); 11528 pw.print("keep awake over "); 11529 TimeUtils.formatDuration(realtimeSince, pw); 11530 pw.print(" used "); 11531 TimeUtils.formatDuration(timeUsed, pw); 11532 pw.print(" ("); 11533 pw.print((timeUsed*100)/realtimeSince); 11534 pw.println("%)"); 11535 } 11536 if (r.lastCpuTime != 0) { 11537 long timeUsed = r.curCpuTime - r.lastCpuTime; 11538 pw.print(prefix); 11539 pw.print(" "); 11540 pw.print("run cpu over "); 11541 TimeUtils.formatDuration(uptimeSince, pw); 11542 pw.print(" used "); 11543 TimeUtils.formatDuration(timeUsed, pw); 11544 pw.print(" ("); 11545 pw.print((timeUsed*100)/uptimeSince); 11546 pw.println("%)"); 11547 } 11548 } 11549 } 11550 } 11551 return true; 11552 } 11553 11554 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11555 ArrayList<ProcessRecord> procs; 11556 synchronized (this) { 11557 if (args != null && args.length > start 11558 && args[start].charAt(0) != '-') { 11559 procs = new ArrayList<ProcessRecord>(); 11560 int pid = -1; 11561 try { 11562 pid = Integer.parseInt(args[start]); 11563 } catch (NumberFormatException e) { 11564 } 11565 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11566 ProcessRecord proc = mLruProcesses.get(i); 11567 if (proc.pid == pid) { 11568 procs.add(proc); 11569 } else if (proc.processName.equals(args[start])) { 11570 procs.add(proc); 11571 } 11572 } 11573 if (procs.size() <= 0) { 11574 return null; 11575 } 11576 } else { 11577 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11578 } 11579 } 11580 return procs; 11581 } 11582 11583 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11584 PrintWriter pw, String[] args) { 11585 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11586 if (procs == null) { 11587 pw.println("No process found for: " + args[0]); 11588 return; 11589 } 11590 11591 long uptime = SystemClock.uptimeMillis(); 11592 long realtime = SystemClock.elapsedRealtime(); 11593 pw.println("Applications Graphics Acceleration Info:"); 11594 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11595 11596 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11597 ProcessRecord r = procs.get(i); 11598 if (r.thread != null) { 11599 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11600 pw.flush(); 11601 try { 11602 TransferPipe tp = new TransferPipe(); 11603 try { 11604 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11605 tp.go(fd); 11606 } finally { 11607 tp.kill(); 11608 } 11609 } catch (IOException e) { 11610 pw.println("Failure while dumping the app: " + r); 11611 pw.flush(); 11612 } catch (RemoteException e) { 11613 pw.println("Got a RemoteException while dumping the app " + r); 11614 pw.flush(); 11615 } 11616 } 11617 } 11618 } 11619 11620 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11621 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11622 if (procs == null) { 11623 pw.println("No process found for: " + args[0]); 11624 return; 11625 } 11626 11627 pw.println("Applications Database Info:"); 11628 11629 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11630 ProcessRecord r = procs.get(i); 11631 if (r.thread != null) { 11632 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11633 pw.flush(); 11634 try { 11635 TransferPipe tp = new TransferPipe(); 11636 try { 11637 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11638 tp.go(fd); 11639 } finally { 11640 tp.kill(); 11641 } 11642 } catch (IOException e) { 11643 pw.println("Failure while dumping the app: " + r); 11644 pw.flush(); 11645 } catch (RemoteException e) { 11646 pw.println("Got a RemoteException while dumping the app " + r); 11647 pw.flush(); 11648 } 11649 } 11650 } 11651 } 11652 11653 final static class MemItem { 11654 final boolean isProc; 11655 final String label; 11656 final String shortLabel; 11657 final long pss; 11658 final int id; 11659 final boolean hasActivities; 11660 ArrayList<MemItem> subitems; 11661 11662 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11663 boolean _hasActivities) { 11664 isProc = true; 11665 label = _label; 11666 shortLabel = _shortLabel; 11667 pss = _pss; 11668 id = _id; 11669 hasActivities = _hasActivities; 11670 } 11671 11672 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11673 isProc = false; 11674 label = _label; 11675 shortLabel = _shortLabel; 11676 pss = _pss; 11677 id = _id; 11678 hasActivities = false; 11679 } 11680 } 11681 11682 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11683 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11684 if (sort && !isCompact) { 11685 Collections.sort(items, new Comparator<MemItem>() { 11686 @Override 11687 public int compare(MemItem lhs, MemItem rhs) { 11688 if (lhs.pss < rhs.pss) { 11689 return 1; 11690 } else if (lhs.pss > rhs.pss) { 11691 return -1; 11692 } 11693 return 0; 11694 } 11695 }); 11696 } 11697 11698 for (int i=0; i<items.size(); i++) { 11699 MemItem mi = items.get(i); 11700 if (!isCompact) { 11701 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11702 } else if (mi.isProc) { 11703 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11704 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11705 pw.println(mi.hasActivities ? ",a" : ",e"); 11706 } else { 11707 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11708 pw.println(mi.pss); 11709 } 11710 if (mi.subitems != null) { 11711 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11712 true, isCompact); 11713 } 11714 } 11715 } 11716 11717 // These are in KB. 11718 static final long[] DUMP_MEM_BUCKETS = new long[] { 11719 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11720 120*1024, 160*1024, 200*1024, 11721 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11722 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11723 }; 11724 11725 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11726 boolean stackLike) { 11727 int start = label.lastIndexOf('.'); 11728 if (start >= 0) start++; 11729 else start = 0; 11730 int end = label.length(); 11731 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11732 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11733 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11734 out.append(bucket); 11735 out.append(stackLike ? "MB." : "MB "); 11736 out.append(label, start, end); 11737 return; 11738 } 11739 } 11740 out.append(memKB/1024); 11741 out.append(stackLike ? "MB." : "MB "); 11742 out.append(label, start, end); 11743 } 11744 11745 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11746 ProcessList.NATIVE_ADJ, 11747 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11748 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11749 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11750 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11751 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11752 }; 11753 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11754 "Native", 11755 "System", "Persistent", "Foreground", 11756 "Visible", "Perceptible", 11757 "Heavy Weight", "Backup", 11758 "A Services", "Home", 11759 "Previous", "B Services", "Cached" 11760 }; 11761 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 11762 "native", 11763 "sys", "pers", "fore", 11764 "vis", "percept", 11765 "heavy", "backup", 11766 "servicea", "home", 11767 "prev", "serviceb", "cached" 11768 }; 11769 11770 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 11771 long realtime, boolean isCheckinRequest, boolean isCompact) { 11772 if (isCheckinRequest || isCompact) { 11773 // short checkin version 11774 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 11775 } else { 11776 pw.println("Applications Memory Usage (kB):"); 11777 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11778 } 11779 } 11780 11781 final void dumpApplicationMemoryUsage(FileDescriptor fd, 11782 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 11783 boolean dumpDetails = false; 11784 boolean dumpFullDetails = false; 11785 boolean dumpDalvik = false; 11786 boolean oomOnly = false; 11787 boolean isCompact = false; 11788 boolean localOnly = false; 11789 11790 int opti = 0; 11791 while (opti < args.length) { 11792 String opt = args[opti]; 11793 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11794 break; 11795 } 11796 opti++; 11797 if ("-a".equals(opt)) { 11798 dumpDetails = true; 11799 dumpFullDetails = true; 11800 dumpDalvik = true; 11801 } else if ("-d".equals(opt)) { 11802 dumpDalvik = true; 11803 } else if ("-c".equals(opt)) { 11804 isCompact = true; 11805 } else if ("--oom".equals(opt)) { 11806 oomOnly = true; 11807 } else if ("--local".equals(opt)) { 11808 localOnly = true; 11809 } else if ("-h".equals(opt)) { 11810 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 11811 pw.println(" -a: include all available information for each process."); 11812 pw.println(" -d: include dalvik details when dumping process details."); 11813 pw.println(" -c: dump in a compact machine-parseable representation."); 11814 pw.println(" --oom: only show processes organized by oom adj."); 11815 pw.println(" --local: only collect details locally, don't call process."); 11816 pw.println("If [process] is specified it can be the name or "); 11817 pw.println("pid of a specific process to dump."); 11818 return; 11819 } else { 11820 pw.println("Unknown argument: " + opt + "; use -h for help"); 11821 } 11822 } 11823 11824 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 11825 long uptime = SystemClock.uptimeMillis(); 11826 long realtime = SystemClock.elapsedRealtime(); 11827 final long[] tmpLong = new long[1]; 11828 11829 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 11830 if (procs == null) { 11831 // No Java processes. Maybe they want to print a native process. 11832 if (args != null && args.length > opti 11833 && args[opti].charAt(0) != '-') { 11834 ArrayList<ProcessCpuTracker.Stats> nativeProcs 11835 = new ArrayList<ProcessCpuTracker.Stats>(); 11836 updateCpuStatsNow(); 11837 int findPid = -1; 11838 try { 11839 findPid = Integer.parseInt(args[opti]); 11840 } catch (NumberFormatException e) { 11841 } 11842 synchronized (mProcessCpuThread) { 11843 final int N = mProcessCpuTracker.countStats(); 11844 for (int i=0; i<N; i++) { 11845 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 11846 if (st.pid == findPid || (st.baseName != null 11847 && st.baseName.equals(args[opti]))) { 11848 nativeProcs.add(st); 11849 } 11850 } 11851 } 11852 if (nativeProcs.size() > 0) { 11853 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 11854 isCompact); 11855 Debug.MemoryInfo mi = null; 11856 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 11857 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 11858 final int pid = r.pid; 11859 if (!isCheckinRequest && dumpDetails) { 11860 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 11861 } 11862 if (mi == null) { 11863 mi = new Debug.MemoryInfo(); 11864 } 11865 if (dumpDetails || (!brief && !oomOnly)) { 11866 Debug.getMemoryInfo(pid, mi); 11867 } else { 11868 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11869 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11870 } 11871 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11872 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 11873 if (isCheckinRequest) { 11874 pw.println(); 11875 } 11876 } 11877 return; 11878 } 11879 } 11880 pw.println("No process found for: " + args[opti]); 11881 return; 11882 } 11883 11884 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 11885 dumpDetails = true; 11886 } 11887 11888 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 11889 11890 String[] innerArgs = new String[args.length-opti]; 11891 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 11892 11893 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 11894 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 11895 long nativePss=0, dalvikPss=0, otherPss=0; 11896 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 11897 11898 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 11899 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 11900 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 11901 11902 long totalPss = 0; 11903 long cachedPss = 0; 11904 11905 Debug.MemoryInfo mi = null; 11906 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11907 final ProcessRecord r = procs.get(i); 11908 final IApplicationThread thread; 11909 final int pid; 11910 final int oomAdj; 11911 final boolean hasActivities; 11912 synchronized (this) { 11913 thread = r.thread; 11914 pid = r.pid; 11915 oomAdj = r.getSetAdjWithServices(); 11916 hasActivities = r.activities.size() > 0; 11917 } 11918 if (thread != null) { 11919 if (!isCheckinRequest && dumpDetails) { 11920 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 11921 } 11922 if (mi == null) { 11923 mi = new Debug.MemoryInfo(); 11924 } 11925 if (dumpDetails || (!brief && !oomOnly)) { 11926 Debug.getMemoryInfo(pid, mi); 11927 } else { 11928 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11929 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11930 } 11931 if (dumpDetails) { 11932 if (localOnly) { 11933 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11934 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 11935 if (isCheckinRequest) { 11936 pw.println(); 11937 } 11938 } else { 11939 try { 11940 pw.flush(); 11941 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 11942 dumpDalvik, innerArgs); 11943 } catch (RemoteException e) { 11944 if (!isCheckinRequest) { 11945 pw.println("Got RemoteException!"); 11946 pw.flush(); 11947 } 11948 } 11949 } 11950 } 11951 11952 final long myTotalPss = mi.getTotalPss(); 11953 final long myTotalUss = mi.getTotalUss(); 11954 11955 synchronized (this) { 11956 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 11957 // Record this for posterity if the process has been stable. 11958 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 11959 } 11960 } 11961 11962 if (!isCheckinRequest && mi != null) { 11963 totalPss += myTotalPss; 11964 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 11965 (hasActivities ? " / activities)" : ")"), 11966 r.processName, myTotalPss, pid, hasActivities); 11967 procMems.add(pssItem); 11968 procMemsMap.put(pid, pssItem); 11969 11970 nativePss += mi.nativePss; 11971 dalvikPss += mi.dalvikPss; 11972 otherPss += mi.otherPss; 11973 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 11974 long mem = mi.getOtherPss(j); 11975 miscPss[j] += mem; 11976 otherPss -= mem; 11977 } 11978 11979 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 11980 cachedPss += myTotalPss; 11981 } 11982 11983 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 11984 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 11985 || oomIndex == (oomPss.length-1)) { 11986 oomPss[oomIndex] += myTotalPss; 11987 if (oomProcs[oomIndex] == null) { 11988 oomProcs[oomIndex] = new ArrayList<MemItem>(); 11989 } 11990 oomProcs[oomIndex].add(pssItem); 11991 break; 11992 } 11993 } 11994 } 11995 } 11996 } 11997 11998 if (!isCheckinRequest && procs.size() > 1) { 11999 // If we are showing aggregations, also look for native processes to 12000 // include so that our aggregations are more accurate. 12001 updateCpuStatsNow(); 12002 synchronized (mProcessCpuThread) { 12003 final int N = mProcessCpuTracker.countStats(); 12004 for (int i=0; i<N; i++) { 12005 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12006 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12007 if (mi == null) { 12008 mi = new Debug.MemoryInfo(); 12009 } 12010 if (!brief && !oomOnly) { 12011 Debug.getMemoryInfo(st.pid, mi); 12012 } else { 12013 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12014 mi.nativePrivateDirty = (int)tmpLong[0]; 12015 } 12016 12017 final long myTotalPss = mi.getTotalPss(); 12018 totalPss += myTotalPss; 12019 12020 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12021 st.name, myTotalPss, st.pid, false); 12022 procMems.add(pssItem); 12023 12024 nativePss += mi.nativePss; 12025 dalvikPss += mi.dalvikPss; 12026 otherPss += mi.otherPss; 12027 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12028 long mem = mi.getOtherPss(j); 12029 miscPss[j] += mem; 12030 otherPss -= mem; 12031 } 12032 oomPss[0] += myTotalPss; 12033 if (oomProcs[0] == null) { 12034 oomProcs[0] = new ArrayList<MemItem>(); 12035 } 12036 oomProcs[0].add(pssItem); 12037 } 12038 } 12039 } 12040 12041 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12042 12043 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12044 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12045 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12046 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12047 String label = Debug.MemoryInfo.getOtherLabel(j); 12048 catMems.add(new MemItem(label, label, miscPss[j], j)); 12049 } 12050 12051 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12052 for (int j=0; j<oomPss.length; j++) { 12053 if (oomPss[j] != 0) { 12054 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12055 : DUMP_MEM_OOM_LABEL[j]; 12056 MemItem item = new MemItem(label, label, oomPss[j], 12057 DUMP_MEM_OOM_ADJ[j]); 12058 item.subitems = oomProcs[j]; 12059 oomMems.add(item); 12060 } 12061 } 12062 12063 if (!brief && !oomOnly && !isCompact) { 12064 pw.println(); 12065 pw.println("Total PSS by process:"); 12066 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12067 pw.println(); 12068 } 12069 if (!isCompact) { 12070 pw.println("Total PSS by OOM adjustment:"); 12071 } 12072 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12073 if (!brief && !oomOnly) { 12074 PrintWriter out = categoryPw != null ? categoryPw : pw; 12075 if (!isCompact) { 12076 out.println(); 12077 out.println("Total PSS by category:"); 12078 } 12079 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12080 } 12081 if (!isCompact) { 12082 pw.println(); 12083 } 12084 MemInfoReader memInfo = new MemInfoReader(); 12085 memInfo.readMemInfo(); 12086 if (!brief) { 12087 if (!isCompact) { 12088 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12089 pw.println(" kB"); 12090 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12091 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12092 pw.print(cachedPss); pw.print(" cached pss + "); 12093 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12094 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12095 } else { 12096 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12097 pw.print(cachedPss + memInfo.getCachedSizeKb() 12098 + memInfo.getFreeSizeKb()); pw.print(","); 12099 pw.println(totalPss - cachedPss); 12100 } 12101 } 12102 if (!isCompact) { 12103 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12104 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12105 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12106 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12107 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12108 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12109 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12110 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12111 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12112 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12113 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12114 } 12115 if (!brief) { 12116 if (memInfo.getZramTotalSizeKb() != 0) { 12117 if (!isCompact) { 12118 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12119 pw.print(" kB physical used for "); 12120 pw.print(memInfo.getSwapTotalSizeKb() 12121 - memInfo.getSwapFreeSizeKb()); 12122 pw.print(" kB in swap ("); 12123 pw.print(memInfo.getSwapTotalSizeKb()); 12124 pw.println(" kB total swap)"); 12125 } else { 12126 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12127 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12128 pw.println(memInfo.getSwapFreeSizeKb()); 12129 } 12130 } 12131 final int[] SINGLE_LONG_FORMAT = new int[] { 12132 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12133 }; 12134 long[] longOut = new long[1]; 12135 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12136 SINGLE_LONG_FORMAT, null, longOut, null); 12137 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12138 longOut[0] = 0; 12139 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12140 SINGLE_LONG_FORMAT, null, longOut, null); 12141 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12142 longOut[0] = 0; 12143 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12144 SINGLE_LONG_FORMAT, null, longOut, null); 12145 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12146 longOut[0] = 0; 12147 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12148 SINGLE_LONG_FORMAT, null, longOut, null); 12149 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12150 if (!isCompact) { 12151 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12152 pw.print(" KSM: "); pw.print(sharing); 12153 pw.print(" kB saved from shared "); 12154 pw.print(shared); pw.println(" kB"); 12155 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12156 pw.print(voltile); pw.println(" kB volatile"); 12157 } 12158 pw.print(" Tuning: "); 12159 pw.print(ActivityManager.staticGetMemoryClass()); 12160 pw.print(" (large "); 12161 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12162 pw.print("), oom "); 12163 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12164 pw.print(" kB"); 12165 pw.print(", restore limit "); 12166 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12167 pw.print(" kB"); 12168 if (ActivityManager.isLowRamDeviceStatic()) { 12169 pw.print(" (low-ram)"); 12170 } 12171 if (ActivityManager.isHighEndGfx()) { 12172 pw.print(" (high-end-gfx)"); 12173 } 12174 pw.println(); 12175 } else { 12176 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12177 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12178 pw.println(voltile); 12179 pw.print("tuning,"); 12180 pw.print(ActivityManager.staticGetMemoryClass()); 12181 pw.print(','); 12182 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12183 pw.print(','); 12184 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12185 if (ActivityManager.isLowRamDeviceStatic()) { 12186 pw.print(",low-ram"); 12187 } 12188 if (ActivityManager.isHighEndGfx()) { 12189 pw.print(",high-end-gfx"); 12190 } 12191 pw.println(); 12192 } 12193 } 12194 } 12195 } 12196 12197 /** 12198 * Searches array of arguments for the specified string 12199 * @param args array of argument strings 12200 * @param value value to search for 12201 * @return true if the value is contained in the array 12202 */ 12203 private static boolean scanArgs(String[] args, String value) { 12204 if (args != null) { 12205 for (String arg : args) { 12206 if (value.equals(arg)) { 12207 return true; 12208 } 12209 } 12210 } 12211 return false; 12212 } 12213 12214 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12215 ContentProviderRecord cpr, boolean always) { 12216 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12217 12218 if (!inLaunching || always) { 12219 synchronized (cpr) { 12220 cpr.launchingApp = null; 12221 cpr.notifyAll(); 12222 } 12223 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12224 String names[] = cpr.info.authority.split(";"); 12225 for (int j = 0; j < names.length; j++) { 12226 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12227 } 12228 } 12229 12230 for (int i=0; i<cpr.connections.size(); i++) { 12231 ContentProviderConnection conn = cpr.connections.get(i); 12232 if (conn.waiting) { 12233 // If this connection is waiting for the provider, then we don't 12234 // need to mess with its process unless we are always removing 12235 // or for some reason the provider is not currently launching. 12236 if (inLaunching && !always) { 12237 continue; 12238 } 12239 } 12240 ProcessRecord capp = conn.client; 12241 conn.dead = true; 12242 if (conn.stableCount > 0) { 12243 if (!capp.persistent && capp.thread != null 12244 && capp.pid != 0 12245 && capp.pid != MY_PID) { 12246 killUnneededProcessLocked(capp, "depends on provider " 12247 + cpr.name.flattenToShortString() 12248 + " in dying proc " + (proc != null ? proc.processName : "??")); 12249 } 12250 } else if (capp.thread != null && conn.provider.provider != null) { 12251 try { 12252 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12253 } catch (RemoteException e) { 12254 } 12255 // In the protocol here, we don't expect the client to correctly 12256 // clean up this connection, we'll just remove it. 12257 cpr.connections.remove(i); 12258 conn.client.conProviders.remove(conn); 12259 } 12260 } 12261 12262 if (inLaunching && always) { 12263 mLaunchingProviders.remove(cpr); 12264 } 12265 return inLaunching; 12266 } 12267 12268 /** 12269 * Main code for cleaning up a process when it has gone away. This is 12270 * called both as a result of the process dying, or directly when stopping 12271 * a process when running in single process mode. 12272 */ 12273 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12274 boolean restarting, boolean allowRestart, int index) { 12275 if (index >= 0) { 12276 removeLruProcessLocked(app); 12277 ProcessList.remove(app.pid); 12278 } 12279 12280 mProcessesToGc.remove(app); 12281 mPendingPssProcesses.remove(app); 12282 12283 // Dismiss any open dialogs. 12284 if (app.crashDialog != null && !app.forceCrashReport) { 12285 app.crashDialog.dismiss(); 12286 app.crashDialog = null; 12287 } 12288 if (app.anrDialog != null) { 12289 app.anrDialog.dismiss(); 12290 app.anrDialog = null; 12291 } 12292 if (app.waitDialog != null) { 12293 app.waitDialog.dismiss(); 12294 app.waitDialog = null; 12295 } 12296 12297 app.crashing = false; 12298 app.notResponding = false; 12299 12300 app.resetPackageList(mProcessStats); 12301 app.unlinkDeathRecipient(); 12302 app.makeInactive(mProcessStats); 12303 app.forcingToForeground = null; 12304 app.foregroundServices = false; 12305 app.foregroundActivities = false; 12306 app.hasShownUi = false; 12307 app.hasAboveClient = false; 12308 12309 mServices.killServicesLocked(app, allowRestart); 12310 12311 boolean restart = false; 12312 12313 // Remove published content providers. 12314 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12315 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12316 final boolean always = app.bad || !allowRestart; 12317 if (removeDyingProviderLocked(app, cpr, always) || always) { 12318 // We left the provider in the launching list, need to 12319 // restart it. 12320 restart = true; 12321 } 12322 12323 cpr.provider = null; 12324 cpr.proc = null; 12325 } 12326 app.pubProviders.clear(); 12327 12328 // Take care of any launching providers waiting for this process. 12329 if (checkAppInLaunchingProvidersLocked(app, false)) { 12330 restart = true; 12331 } 12332 12333 // Unregister from connected content providers. 12334 if (!app.conProviders.isEmpty()) { 12335 for (int i=0; i<app.conProviders.size(); i++) { 12336 ContentProviderConnection conn = app.conProviders.get(i); 12337 conn.provider.connections.remove(conn); 12338 } 12339 app.conProviders.clear(); 12340 } 12341 12342 // At this point there may be remaining entries in mLaunchingProviders 12343 // where we were the only one waiting, so they are no longer of use. 12344 // Look for these and clean up if found. 12345 // XXX Commented out for now. Trying to figure out a way to reproduce 12346 // the actual situation to identify what is actually going on. 12347 if (false) { 12348 for (int i=0; i<mLaunchingProviders.size(); i++) { 12349 ContentProviderRecord cpr = (ContentProviderRecord) 12350 mLaunchingProviders.get(i); 12351 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12352 synchronized (cpr) { 12353 cpr.launchingApp = null; 12354 cpr.notifyAll(); 12355 } 12356 } 12357 } 12358 } 12359 12360 skipCurrentReceiverLocked(app); 12361 12362 // Unregister any receivers. 12363 for (int i=app.receivers.size()-1; i>=0; i--) { 12364 removeReceiverLocked(app.receivers.valueAt(i)); 12365 } 12366 app.receivers.clear(); 12367 12368 // If the app is undergoing backup, tell the backup manager about it 12369 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12370 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12371 + mBackupTarget.appInfo + " died during backup"); 12372 try { 12373 IBackupManager bm = IBackupManager.Stub.asInterface( 12374 ServiceManager.getService(Context.BACKUP_SERVICE)); 12375 bm.agentDisconnected(app.info.packageName); 12376 } catch (RemoteException e) { 12377 // can't happen; backup manager is local 12378 } 12379 } 12380 12381 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12382 ProcessChangeItem item = mPendingProcessChanges.get(i); 12383 if (item.pid == app.pid) { 12384 mPendingProcessChanges.remove(i); 12385 mAvailProcessChanges.add(item); 12386 } 12387 } 12388 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12389 12390 // If the caller is restarting this app, then leave it in its 12391 // current lists and let the caller take care of it. 12392 if (restarting) { 12393 return; 12394 } 12395 12396 if (!app.persistent || app.isolated) { 12397 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12398 "Removing non-persistent process during cleanup: " + app); 12399 mProcessNames.remove(app.processName, app.uid); 12400 mIsolatedProcesses.remove(app.uid); 12401 if (mHeavyWeightProcess == app) { 12402 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12403 mHeavyWeightProcess.userId, 0)); 12404 mHeavyWeightProcess = null; 12405 } 12406 } else if (!app.removed) { 12407 // This app is persistent, so we need to keep its record around. 12408 // If it is not already on the pending app list, add it there 12409 // and start a new process for it. 12410 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12411 mPersistentStartingProcesses.add(app); 12412 restart = true; 12413 } 12414 } 12415 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12416 "Clean-up removing on hold: " + app); 12417 mProcessesOnHold.remove(app); 12418 12419 if (app == mHomeProcess) { 12420 mHomeProcess = null; 12421 } 12422 if (app == mPreviousProcess) { 12423 mPreviousProcess = null; 12424 } 12425 12426 if (restart && !app.isolated) { 12427 // We have components that still need to be running in the 12428 // process, so re-launch it. 12429 mProcessNames.put(app.processName, app.uid, app); 12430 startProcessLocked(app, "restart", app.processName); 12431 } else if (app.pid > 0 && app.pid != MY_PID) { 12432 // Goodbye! 12433 synchronized (mPidsSelfLocked) { 12434 mPidsSelfLocked.remove(app.pid); 12435 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12436 } 12437 app.setPid(0); 12438 } 12439 } 12440 12441 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12442 // Look through the content providers we are waiting to have launched, 12443 // and if any run in this process then either schedule a restart of 12444 // the process or kill the client waiting for it if this process has 12445 // gone bad. 12446 int NL = mLaunchingProviders.size(); 12447 boolean restart = false; 12448 for (int i=0; i<NL; i++) { 12449 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12450 if (cpr.launchingApp == app) { 12451 if (!alwaysBad && !app.bad) { 12452 restart = true; 12453 } else { 12454 removeDyingProviderLocked(app, cpr, true); 12455 // cpr should have been removed from mLaunchingProviders 12456 NL = mLaunchingProviders.size(); 12457 i--; 12458 } 12459 } 12460 } 12461 return restart; 12462 } 12463 12464 // ========================================================= 12465 // SERVICES 12466 // ========================================================= 12467 12468 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12469 int flags) { 12470 enforceNotIsolatedCaller("getServices"); 12471 synchronized (this) { 12472 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12473 } 12474 } 12475 12476 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12477 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12478 synchronized (this) { 12479 return mServices.getRunningServiceControlPanelLocked(name); 12480 } 12481 } 12482 12483 public ComponentName startService(IApplicationThread caller, Intent service, 12484 String resolvedType, int userId) { 12485 enforceNotIsolatedCaller("startService"); 12486 // Refuse possible leaked file descriptors 12487 if (service != null && service.hasFileDescriptors() == true) { 12488 throw new IllegalArgumentException("File descriptors passed in Intent"); 12489 } 12490 12491 if (DEBUG_SERVICE) 12492 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12493 synchronized(this) { 12494 final int callingPid = Binder.getCallingPid(); 12495 final int callingUid = Binder.getCallingUid(); 12496 final long origId = Binder.clearCallingIdentity(); 12497 ComponentName res = mServices.startServiceLocked(caller, service, 12498 resolvedType, callingPid, callingUid, userId); 12499 Binder.restoreCallingIdentity(origId); 12500 return res; 12501 } 12502 } 12503 12504 ComponentName startServiceInPackage(int uid, 12505 Intent service, String resolvedType, int userId) { 12506 synchronized(this) { 12507 if (DEBUG_SERVICE) 12508 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12509 final long origId = Binder.clearCallingIdentity(); 12510 ComponentName res = mServices.startServiceLocked(null, service, 12511 resolvedType, -1, uid, userId); 12512 Binder.restoreCallingIdentity(origId); 12513 return res; 12514 } 12515 } 12516 12517 public int stopService(IApplicationThread caller, Intent service, 12518 String resolvedType, int userId) { 12519 enforceNotIsolatedCaller("stopService"); 12520 // Refuse possible leaked file descriptors 12521 if (service != null && service.hasFileDescriptors() == true) { 12522 throw new IllegalArgumentException("File descriptors passed in Intent"); 12523 } 12524 12525 synchronized(this) { 12526 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12527 } 12528 } 12529 12530 public IBinder peekService(Intent service, String resolvedType) { 12531 enforceNotIsolatedCaller("peekService"); 12532 // Refuse possible leaked file descriptors 12533 if (service != null && service.hasFileDescriptors() == true) { 12534 throw new IllegalArgumentException("File descriptors passed in Intent"); 12535 } 12536 synchronized(this) { 12537 return mServices.peekServiceLocked(service, resolvedType); 12538 } 12539 } 12540 12541 public boolean stopServiceToken(ComponentName className, IBinder token, 12542 int startId) { 12543 synchronized(this) { 12544 return mServices.stopServiceTokenLocked(className, token, startId); 12545 } 12546 } 12547 12548 public void setServiceForeground(ComponentName className, IBinder token, 12549 int id, Notification notification, boolean removeNotification) { 12550 synchronized(this) { 12551 mServices.setServiceForegroundLocked(className, token, id, notification, 12552 removeNotification); 12553 } 12554 } 12555 12556 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12557 boolean requireFull, String name, String callerPackage) { 12558 final int callingUserId = UserHandle.getUserId(callingUid); 12559 if (callingUserId != userId) { 12560 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12561 if ((requireFull || checkComponentPermission( 12562 android.Manifest.permission.INTERACT_ACROSS_USERS, 12563 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12564 && checkComponentPermission( 12565 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12566 callingPid, callingUid, -1, true) 12567 != PackageManager.PERMISSION_GRANTED) { 12568 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12569 // In this case, they would like to just execute as their 12570 // owner user instead of failing. 12571 userId = callingUserId; 12572 } else { 12573 StringBuilder builder = new StringBuilder(128); 12574 builder.append("Permission Denial: "); 12575 builder.append(name); 12576 if (callerPackage != null) { 12577 builder.append(" from "); 12578 builder.append(callerPackage); 12579 } 12580 builder.append(" asks to run as user "); 12581 builder.append(userId); 12582 builder.append(" but is calling from user "); 12583 builder.append(UserHandle.getUserId(callingUid)); 12584 builder.append("; this requires "); 12585 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12586 if (!requireFull) { 12587 builder.append(" or "); 12588 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12589 } 12590 String msg = builder.toString(); 12591 Slog.w(TAG, msg); 12592 throw new SecurityException(msg); 12593 } 12594 } 12595 } 12596 if (userId == UserHandle.USER_CURRENT 12597 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12598 // Note that we may be accessing this outside of a lock... 12599 // shouldn't be a big deal, if this is being called outside 12600 // of a locked context there is intrinsically a race with 12601 // the value the caller will receive and someone else changing it. 12602 userId = mCurrentUserId; 12603 } 12604 if (!allowAll && userId < 0) { 12605 throw new IllegalArgumentException( 12606 "Call does not support special user #" + userId); 12607 } 12608 } 12609 return userId; 12610 } 12611 12612 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12613 String className, int flags) { 12614 boolean result = false; 12615 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12616 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12617 if (ActivityManager.checkUidPermission( 12618 android.Manifest.permission.INTERACT_ACROSS_USERS, 12619 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12620 ComponentName comp = new ComponentName(aInfo.packageName, className); 12621 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12622 + " requests FLAG_SINGLE_USER, but app does not hold " 12623 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12624 Slog.w(TAG, msg); 12625 throw new SecurityException(msg); 12626 } 12627 result = true; 12628 } 12629 } else if (componentProcessName == aInfo.packageName) { 12630 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12631 } else if ("system".equals(componentProcessName)) { 12632 result = true; 12633 } 12634 if (DEBUG_MU) { 12635 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12636 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12637 } 12638 return result; 12639 } 12640 12641 public int bindService(IApplicationThread caller, IBinder token, 12642 Intent service, String resolvedType, 12643 IServiceConnection connection, int flags, int userId) { 12644 enforceNotIsolatedCaller("bindService"); 12645 // Refuse possible leaked file descriptors 12646 if (service != null && service.hasFileDescriptors() == true) { 12647 throw new IllegalArgumentException("File descriptors passed in Intent"); 12648 } 12649 12650 synchronized(this) { 12651 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12652 connection, flags, userId); 12653 } 12654 } 12655 12656 public boolean unbindService(IServiceConnection connection) { 12657 synchronized (this) { 12658 return mServices.unbindServiceLocked(connection); 12659 } 12660 } 12661 12662 public void publishService(IBinder token, Intent intent, IBinder service) { 12663 // Refuse possible leaked file descriptors 12664 if (intent != null && intent.hasFileDescriptors() == true) { 12665 throw new IllegalArgumentException("File descriptors passed in Intent"); 12666 } 12667 12668 synchronized(this) { 12669 if (!(token instanceof ServiceRecord)) { 12670 throw new IllegalArgumentException("Invalid service token"); 12671 } 12672 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12673 } 12674 } 12675 12676 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12677 // Refuse possible leaked file descriptors 12678 if (intent != null && intent.hasFileDescriptors() == true) { 12679 throw new IllegalArgumentException("File descriptors passed in Intent"); 12680 } 12681 12682 synchronized(this) { 12683 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12684 } 12685 } 12686 12687 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12688 synchronized(this) { 12689 if (!(token instanceof ServiceRecord)) { 12690 throw new IllegalArgumentException("Invalid service token"); 12691 } 12692 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12693 } 12694 } 12695 12696 // ========================================================= 12697 // BACKUP AND RESTORE 12698 // ========================================================= 12699 12700 // Cause the target app to be launched if necessary and its backup agent 12701 // instantiated. The backup agent will invoke backupAgentCreated() on the 12702 // activity manager to announce its creation. 12703 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12704 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12705 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12706 12707 synchronized(this) { 12708 // !!! TODO: currently no check here that we're already bound 12709 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12710 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12711 synchronized (stats) { 12712 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12713 } 12714 12715 // Backup agent is now in use, its package can't be stopped. 12716 try { 12717 AppGlobals.getPackageManager().setPackageStoppedState( 12718 app.packageName, false, UserHandle.getUserId(app.uid)); 12719 } catch (RemoteException e) { 12720 } catch (IllegalArgumentException e) { 12721 Slog.w(TAG, "Failed trying to unstop package " 12722 + app.packageName + ": " + e); 12723 } 12724 12725 BackupRecord r = new BackupRecord(ss, app, backupMode); 12726 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12727 ? new ComponentName(app.packageName, app.backupAgentName) 12728 : new ComponentName("android", "FullBackupAgent"); 12729 // startProcessLocked() returns existing proc's record if it's already running 12730 ProcessRecord proc = startProcessLocked(app.processName, app, 12731 false, 0, "backup", hostingName, false, false, false); 12732 if (proc == null) { 12733 Slog.e(TAG, "Unable to start backup agent process " + r); 12734 return false; 12735 } 12736 12737 r.app = proc; 12738 mBackupTarget = r; 12739 mBackupAppName = app.packageName; 12740 12741 // Try not to kill the process during backup 12742 updateOomAdjLocked(proc); 12743 12744 // If the process is already attached, schedule the creation of the backup agent now. 12745 // If it is not yet live, this will be done when it attaches to the framework. 12746 if (proc.thread != null) { 12747 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12748 try { 12749 proc.thread.scheduleCreateBackupAgent(app, 12750 compatibilityInfoForPackageLocked(app), backupMode); 12751 } catch (RemoteException e) { 12752 // Will time out on the backup manager side 12753 } 12754 } else { 12755 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12756 } 12757 // Invariants: at this point, the target app process exists and the application 12758 // is either already running or in the process of coming up. mBackupTarget and 12759 // mBackupAppName describe the app, so that when it binds back to the AM we 12760 // know that it's scheduled for a backup-agent operation. 12761 } 12762 12763 return true; 12764 } 12765 12766 @Override 12767 public void clearPendingBackup() { 12768 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 12769 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 12770 12771 synchronized (this) { 12772 mBackupTarget = null; 12773 mBackupAppName = null; 12774 } 12775 } 12776 12777 // A backup agent has just come up 12778 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12779 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12780 + " = " + agent); 12781 12782 synchronized(this) { 12783 if (!agentPackageName.equals(mBackupAppName)) { 12784 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12785 return; 12786 } 12787 } 12788 12789 long oldIdent = Binder.clearCallingIdentity(); 12790 try { 12791 IBackupManager bm = IBackupManager.Stub.asInterface( 12792 ServiceManager.getService(Context.BACKUP_SERVICE)); 12793 bm.agentConnected(agentPackageName, agent); 12794 } catch (RemoteException e) { 12795 // can't happen; the backup manager service is local 12796 } catch (Exception e) { 12797 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12798 e.printStackTrace(); 12799 } finally { 12800 Binder.restoreCallingIdentity(oldIdent); 12801 } 12802 } 12803 12804 // done with this agent 12805 public void unbindBackupAgent(ApplicationInfo appInfo) { 12806 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12807 if (appInfo == null) { 12808 Slog.w(TAG, "unbind backup agent for null app"); 12809 return; 12810 } 12811 12812 synchronized(this) { 12813 try { 12814 if (mBackupAppName == null) { 12815 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12816 return; 12817 } 12818 12819 if (!mBackupAppName.equals(appInfo.packageName)) { 12820 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12821 return; 12822 } 12823 12824 // Not backing this app up any more; reset its OOM adjustment 12825 final ProcessRecord proc = mBackupTarget.app; 12826 updateOomAdjLocked(proc); 12827 12828 // If the app crashed during backup, 'thread' will be null here 12829 if (proc.thread != null) { 12830 try { 12831 proc.thread.scheduleDestroyBackupAgent(appInfo, 12832 compatibilityInfoForPackageLocked(appInfo)); 12833 } catch (Exception e) { 12834 Slog.e(TAG, "Exception when unbinding backup agent:"); 12835 e.printStackTrace(); 12836 } 12837 } 12838 } finally { 12839 mBackupTarget = null; 12840 mBackupAppName = null; 12841 } 12842 } 12843 } 12844 // ========================================================= 12845 // BROADCASTS 12846 // ========================================================= 12847 12848 private final List getStickiesLocked(String action, IntentFilter filter, 12849 List cur, int userId) { 12850 final ContentResolver resolver = mContext.getContentResolver(); 12851 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12852 if (stickies == null) { 12853 return cur; 12854 } 12855 final ArrayList<Intent> list = stickies.get(action); 12856 if (list == null) { 12857 return cur; 12858 } 12859 int N = list.size(); 12860 for (int i=0; i<N; i++) { 12861 Intent intent = list.get(i); 12862 if (filter.match(resolver, intent, true, TAG) >= 0) { 12863 if (cur == null) { 12864 cur = new ArrayList<Intent>(); 12865 } 12866 cur.add(intent); 12867 } 12868 } 12869 return cur; 12870 } 12871 12872 boolean isPendingBroadcastProcessLocked(int pid) { 12873 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12874 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12875 } 12876 12877 void skipPendingBroadcastLocked(int pid) { 12878 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 12879 for (BroadcastQueue queue : mBroadcastQueues) { 12880 queue.skipPendingBroadcastLocked(pid); 12881 } 12882 } 12883 12884 // The app just attached; send any pending broadcasts that it should receive 12885 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 12886 boolean didSomething = false; 12887 for (BroadcastQueue queue : mBroadcastQueues) { 12888 didSomething |= queue.sendPendingBroadcastsLocked(app); 12889 } 12890 return didSomething; 12891 } 12892 12893 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 12894 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 12895 enforceNotIsolatedCaller("registerReceiver"); 12896 int callingUid; 12897 int callingPid; 12898 synchronized(this) { 12899 ProcessRecord callerApp = null; 12900 if (caller != null) { 12901 callerApp = getRecordForAppLocked(caller); 12902 if (callerApp == null) { 12903 throw new SecurityException( 12904 "Unable to find app for caller " + caller 12905 + " (pid=" + Binder.getCallingPid() 12906 + ") when registering receiver " + receiver); 12907 } 12908 if (callerApp.info.uid != Process.SYSTEM_UID && 12909 !callerApp.pkgList.containsKey(callerPackage) && 12910 !"android".equals(callerPackage)) { 12911 throw new SecurityException("Given caller package " + callerPackage 12912 + " is not running in process " + callerApp); 12913 } 12914 callingUid = callerApp.info.uid; 12915 callingPid = callerApp.pid; 12916 } else { 12917 callerPackage = null; 12918 callingUid = Binder.getCallingUid(); 12919 callingPid = Binder.getCallingPid(); 12920 } 12921 12922 userId = this.handleIncomingUser(callingPid, callingUid, userId, 12923 true, true, "registerReceiver", callerPackage); 12924 12925 List allSticky = null; 12926 12927 // Look for any matching sticky broadcasts... 12928 Iterator actions = filter.actionsIterator(); 12929 if (actions != null) { 12930 while (actions.hasNext()) { 12931 String action = (String)actions.next(); 12932 allSticky = getStickiesLocked(action, filter, allSticky, 12933 UserHandle.USER_ALL); 12934 allSticky = getStickiesLocked(action, filter, allSticky, 12935 UserHandle.getUserId(callingUid)); 12936 } 12937 } else { 12938 allSticky = getStickiesLocked(null, filter, allSticky, 12939 UserHandle.USER_ALL); 12940 allSticky = getStickiesLocked(null, filter, allSticky, 12941 UserHandle.getUserId(callingUid)); 12942 } 12943 12944 // The first sticky in the list is returned directly back to 12945 // the client. 12946 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 12947 12948 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 12949 + ": " + sticky); 12950 12951 if (receiver == null) { 12952 return sticky; 12953 } 12954 12955 ReceiverList rl 12956 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12957 if (rl == null) { 12958 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 12959 userId, receiver); 12960 if (rl.app != null) { 12961 rl.app.receivers.add(rl); 12962 } else { 12963 try { 12964 receiver.asBinder().linkToDeath(rl, 0); 12965 } catch (RemoteException e) { 12966 return sticky; 12967 } 12968 rl.linkedToDeath = true; 12969 } 12970 mRegisteredReceivers.put(receiver.asBinder(), rl); 12971 } else if (rl.uid != callingUid) { 12972 throw new IllegalArgumentException( 12973 "Receiver requested to register for uid " + callingUid 12974 + " was previously registered for uid " + rl.uid); 12975 } else if (rl.pid != callingPid) { 12976 throw new IllegalArgumentException( 12977 "Receiver requested to register for pid " + callingPid 12978 + " was previously registered for pid " + rl.pid); 12979 } else if (rl.userId != userId) { 12980 throw new IllegalArgumentException( 12981 "Receiver requested to register for user " + userId 12982 + " was previously registered for user " + rl.userId); 12983 } 12984 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 12985 permission, callingUid, userId); 12986 rl.add(bf); 12987 if (!bf.debugCheck()) { 12988 Slog.w(TAG, "==> For Dynamic broadast"); 12989 } 12990 mReceiverResolver.addFilter(bf); 12991 12992 // Enqueue broadcasts for all existing stickies that match 12993 // this filter. 12994 if (allSticky != null) { 12995 ArrayList receivers = new ArrayList(); 12996 receivers.add(bf); 12997 12998 int N = allSticky.size(); 12999 for (int i=0; i<N; i++) { 13000 Intent intent = (Intent)allSticky.get(i); 13001 BroadcastQueue queue = broadcastQueueForIntent(intent); 13002 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13003 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13004 null, null, false, true, true, -1); 13005 queue.enqueueParallelBroadcastLocked(r); 13006 queue.scheduleBroadcastsLocked(); 13007 } 13008 } 13009 13010 return sticky; 13011 } 13012 } 13013 13014 public void unregisterReceiver(IIntentReceiver receiver) { 13015 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13016 13017 final long origId = Binder.clearCallingIdentity(); 13018 try { 13019 boolean doTrim = false; 13020 13021 synchronized(this) { 13022 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13023 if (rl != null) { 13024 if (rl.curBroadcast != null) { 13025 BroadcastRecord r = rl.curBroadcast; 13026 final boolean doNext = finishReceiverLocked( 13027 receiver.asBinder(), r.resultCode, r.resultData, 13028 r.resultExtras, r.resultAbort); 13029 if (doNext) { 13030 doTrim = true; 13031 r.queue.processNextBroadcast(false); 13032 } 13033 } 13034 13035 if (rl.app != null) { 13036 rl.app.receivers.remove(rl); 13037 } 13038 removeReceiverLocked(rl); 13039 if (rl.linkedToDeath) { 13040 rl.linkedToDeath = false; 13041 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13042 } 13043 } 13044 } 13045 13046 // If we actually concluded any broadcasts, we might now be able 13047 // to trim the recipients' apps from our working set 13048 if (doTrim) { 13049 trimApplications(); 13050 return; 13051 } 13052 13053 } finally { 13054 Binder.restoreCallingIdentity(origId); 13055 } 13056 } 13057 13058 void removeReceiverLocked(ReceiverList rl) { 13059 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13060 int N = rl.size(); 13061 for (int i=0; i<N; i++) { 13062 mReceiverResolver.removeFilter(rl.get(i)); 13063 } 13064 } 13065 13066 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13067 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13068 ProcessRecord r = mLruProcesses.get(i); 13069 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13070 try { 13071 r.thread.dispatchPackageBroadcast(cmd, packages); 13072 } catch (RemoteException ex) { 13073 } 13074 } 13075 } 13076 } 13077 13078 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13079 int[] users) { 13080 List<ResolveInfo> receivers = null; 13081 try { 13082 HashSet<ComponentName> singleUserReceivers = null; 13083 boolean scannedFirstReceivers = false; 13084 for (int user : users) { 13085 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13086 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13087 if (user != 0 && newReceivers != null) { 13088 // If this is not the primary user, we need to check for 13089 // any receivers that should be filtered out. 13090 for (int i=0; i<newReceivers.size(); i++) { 13091 ResolveInfo ri = newReceivers.get(i); 13092 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13093 newReceivers.remove(i); 13094 i--; 13095 } 13096 } 13097 } 13098 if (newReceivers != null && newReceivers.size() == 0) { 13099 newReceivers = null; 13100 } 13101 if (receivers == null) { 13102 receivers = newReceivers; 13103 } else if (newReceivers != null) { 13104 // We need to concatenate the additional receivers 13105 // found with what we have do far. This would be easy, 13106 // but we also need to de-dup any receivers that are 13107 // singleUser. 13108 if (!scannedFirstReceivers) { 13109 // Collect any single user receivers we had already retrieved. 13110 scannedFirstReceivers = true; 13111 for (int i=0; i<receivers.size(); i++) { 13112 ResolveInfo ri = receivers.get(i); 13113 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13114 ComponentName cn = new ComponentName( 13115 ri.activityInfo.packageName, ri.activityInfo.name); 13116 if (singleUserReceivers == null) { 13117 singleUserReceivers = new HashSet<ComponentName>(); 13118 } 13119 singleUserReceivers.add(cn); 13120 } 13121 } 13122 } 13123 // Add the new results to the existing results, tracking 13124 // and de-dupping single user receivers. 13125 for (int i=0; i<newReceivers.size(); i++) { 13126 ResolveInfo ri = newReceivers.get(i); 13127 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13128 ComponentName cn = new ComponentName( 13129 ri.activityInfo.packageName, ri.activityInfo.name); 13130 if (singleUserReceivers == null) { 13131 singleUserReceivers = new HashSet<ComponentName>(); 13132 } 13133 if (!singleUserReceivers.contains(cn)) { 13134 singleUserReceivers.add(cn); 13135 receivers.add(ri); 13136 } 13137 } else { 13138 receivers.add(ri); 13139 } 13140 } 13141 } 13142 } 13143 } catch (RemoteException ex) { 13144 // pm is in same process, this will never happen. 13145 } 13146 return receivers; 13147 } 13148 13149 private final int broadcastIntentLocked(ProcessRecord callerApp, 13150 String callerPackage, Intent intent, String resolvedType, 13151 IIntentReceiver resultTo, int resultCode, String resultData, 13152 Bundle map, String requiredPermission, int appOp, 13153 boolean ordered, boolean sticky, int callingPid, int callingUid, 13154 int userId) { 13155 intent = new Intent(intent); 13156 13157 // By default broadcasts do not go to stopped apps. 13158 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13159 13160 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13161 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13162 + " ordered=" + ordered + " userid=" + userId); 13163 if ((resultTo != null) && !ordered) { 13164 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13165 } 13166 13167 userId = handleIncomingUser(callingPid, callingUid, userId, 13168 true, false, "broadcast", callerPackage); 13169 13170 // Make sure that the user who is receiving this broadcast is started. 13171 // If not, we will just skip it. 13172 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13173 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13174 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13175 Slog.w(TAG, "Skipping broadcast of " + intent 13176 + ": user " + userId + " is stopped"); 13177 return ActivityManager.BROADCAST_SUCCESS; 13178 } 13179 } 13180 13181 /* 13182 * Prevent non-system code (defined here to be non-persistent 13183 * processes) from sending protected broadcasts. 13184 */ 13185 int callingAppId = UserHandle.getAppId(callingUid); 13186 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13187 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13188 callingUid == 0) { 13189 // Always okay. 13190 } else if (callerApp == null || !callerApp.persistent) { 13191 try { 13192 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13193 intent.getAction())) { 13194 String msg = "Permission Denial: not allowed to send broadcast " 13195 + intent.getAction() + " from pid=" 13196 + callingPid + ", uid=" + callingUid; 13197 Slog.w(TAG, msg); 13198 throw new SecurityException(msg); 13199 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13200 // Special case for compatibility: we don't want apps to send this, 13201 // but historically it has not been protected and apps may be using it 13202 // to poke their own app widget. So, instead of making it protected, 13203 // just limit it to the caller. 13204 if (callerApp == null) { 13205 String msg = "Permission Denial: not allowed to send broadcast " 13206 + intent.getAction() + " from unknown caller."; 13207 Slog.w(TAG, msg); 13208 throw new SecurityException(msg); 13209 } else if (intent.getComponent() != null) { 13210 // They are good enough to send to an explicit component... verify 13211 // it is being sent to the calling app. 13212 if (!intent.getComponent().getPackageName().equals( 13213 callerApp.info.packageName)) { 13214 String msg = "Permission Denial: not allowed to send broadcast " 13215 + intent.getAction() + " to " 13216 + intent.getComponent().getPackageName() + " from " 13217 + callerApp.info.packageName; 13218 Slog.w(TAG, msg); 13219 throw new SecurityException(msg); 13220 } 13221 } else { 13222 // Limit broadcast to their own package. 13223 intent.setPackage(callerApp.info.packageName); 13224 } 13225 } 13226 } catch (RemoteException e) { 13227 Slog.w(TAG, "Remote exception", e); 13228 return ActivityManager.BROADCAST_SUCCESS; 13229 } 13230 } 13231 13232 // Handle special intents: if this broadcast is from the package 13233 // manager about a package being removed, we need to remove all of 13234 // its activities from the history stack. 13235 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13236 intent.getAction()); 13237 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13238 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13239 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13240 || uidRemoved) { 13241 if (checkComponentPermission( 13242 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13243 callingPid, callingUid, -1, true) 13244 == PackageManager.PERMISSION_GRANTED) { 13245 if (uidRemoved) { 13246 final Bundle intentExtras = intent.getExtras(); 13247 final int uid = intentExtras != null 13248 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13249 if (uid >= 0) { 13250 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13251 synchronized (bs) { 13252 bs.removeUidStatsLocked(uid); 13253 } 13254 mAppOpsService.uidRemoved(uid); 13255 } 13256 } else { 13257 // If resources are unavailable just force stop all 13258 // those packages and flush the attribute cache as well. 13259 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13260 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13261 if (list != null && (list.length > 0)) { 13262 for (String pkg : list) { 13263 forceStopPackageLocked(pkg, -1, false, true, true, false, userId, 13264 "storage unmount"); 13265 } 13266 sendPackageBroadcastLocked( 13267 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13268 } 13269 } else { 13270 Uri data = intent.getData(); 13271 String ssp; 13272 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13273 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13274 intent.getAction()); 13275 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13276 forceStopPackageLocked(ssp, UserHandle.getAppId( 13277 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13278 false, userId, removed ? "pkg removed" : "pkg changed"); 13279 } 13280 if (removed) { 13281 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13282 new String[] {ssp}, userId); 13283 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13284 mAppOpsService.packageRemoved( 13285 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13286 13287 // Remove all permissions granted from/to this package 13288 removeUriPermissionsForPackageLocked(ssp, userId, true); 13289 } 13290 } 13291 } 13292 } 13293 } 13294 } else { 13295 String msg = "Permission Denial: " + intent.getAction() 13296 + " broadcast from " + callerPackage + " (pid=" + callingPid 13297 + ", uid=" + callingUid + ")" 13298 + " requires " 13299 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13300 Slog.w(TAG, msg); 13301 throw new SecurityException(msg); 13302 } 13303 13304 // Special case for adding a package: by default turn on compatibility 13305 // mode. 13306 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13307 Uri data = intent.getData(); 13308 String ssp; 13309 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13310 mCompatModePackages.handlePackageAddedLocked(ssp, 13311 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13312 } 13313 } 13314 13315 /* 13316 * If this is the time zone changed action, queue up a message that will reset the timezone 13317 * of all currently running processes. This message will get queued up before the broadcast 13318 * happens. 13319 */ 13320 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13321 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13322 } 13323 13324 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13325 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13326 } 13327 13328 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13329 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13330 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13331 } 13332 13333 // Add to the sticky list if requested. 13334 if (sticky) { 13335 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13336 callingPid, callingUid) 13337 != PackageManager.PERMISSION_GRANTED) { 13338 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13339 + callingPid + ", uid=" + callingUid 13340 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13341 Slog.w(TAG, msg); 13342 throw new SecurityException(msg); 13343 } 13344 if (requiredPermission != null) { 13345 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13346 + " and enforce permission " + requiredPermission); 13347 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13348 } 13349 if (intent.getComponent() != null) { 13350 throw new SecurityException( 13351 "Sticky broadcasts can't target a specific component"); 13352 } 13353 // We use userId directly here, since the "all" target is maintained 13354 // as a separate set of sticky broadcasts. 13355 if (userId != UserHandle.USER_ALL) { 13356 // But first, if this is not a broadcast to all users, then 13357 // make sure it doesn't conflict with an existing broadcast to 13358 // all users. 13359 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13360 UserHandle.USER_ALL); 13361 if (stickies != null) { 13362 ArrayList<Intent> list = stickies.get(intent.getAction()); 13363 if (list != null) { 13364 int N = list.size(); 13365 int i; 13366 for (i=0; i<N; i++) { 13367 if (intent.filterEquals(list.get(i))) { 13368 throw new IllegalArgumentException( 13369 "Sticky broadcast " + intent + " for user " 13370 + userId + " conflicts with existing global broadcast"); 13371 } 13372 } 13373 } 13374 } 13375 } 13376 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13377 if (stickies == null) { 13378 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13379 mStickyBroadcasts.put(userId, stickies); 13380 } 13381 ArrayList<Intent> list = stickies.get(intent.getAction()); 13382 if (list == null) { 13383 list = new ArrayList<Intent>(); 13384 stickies.put(intent.getAction(), list); 13385 } 13386 int N = list.size(); 13387 int i; 13388 for (i=0; i<N; i++) { 13389 if (intent.filterEquals(list.get(i))) { 13390 // This sticky already exists, replace it. 13391 list.set(i, new Intent(intent)); 13392 break; 13393 } 13394 } 13395 if (i >= N) { 13396 list.add(new Intent(intent)); 13397 } 13398 } 13399 13400 int[] users; 13401 if (userId == UserHandle.USER_ALL) { 13402 // Caller wants broadcast to go to all started users. 13403 users = mStartedUserArray; 13404 } else { 13405 // Caller wants broadcast to go to one specific user. 13406 users = new int[] {userId}; 13407 } 13408 13409 // Figure out who all will receive this broadcast. 13410 List receivers = null; 13411 List<BroadcastFilter> registeredReceivers = null; 13412 // Need to resolve the intent to interested receivers... 13413 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13414 == 0) { 13415 receivers = collectReceiverComponents(intent, resolvedType, users); 13416 } 13417 if (intent.getComponent() == null) { 13418 registeredReceivers = mReceiverResolver.queryIntent(intent, 13419 resolvedType, false, userId); 13420 } 13421 13422 final boolean replacePending = 13423 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13424 13425 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13426 + " replacePending=" + replacePending); 13427 13428 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13429 if (!ordered && NR > 0) { 13430 // If we are not serializing this broadcast, then send the 13431 // registered receivers separately so they don't wait for the 13432 // components to be launched. 13433 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13434 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13435 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13436 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13437 ordered, sticky, false, userId); 13438 if (DEBUG_BROADCAST) Slog.v( 13439 TAG, "Enqueueing parallel broadcast " + r); 13440 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13441 if (!replaced) { 13442 queue.enqueueParallelBroadcastLocked(r); 13443 queue.scheduleBroadcastsLocked(); 13444 } 13445 registeredReceivers = null; 13446 NR = 0; 13447 } 13448 13449 // Merge into one list. 13450 int ir = 0; 13451 if (receivers != null) { 13452 // A special case for PACKAGE_ADDED: do not allow the package 13453 // being added to see this broadcast. This prevents them from 13454 // using this as a back door to get run as soon as they are 13455 // installed. Maybe in the future we want to have a special install 13456 // broadcast or such for apps, but we'd like to deliberately make 13457 // this decision. 13458 String skipPackages[] = null; 13459 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13460 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13461 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13462 Uri data = intent.getData(); 13463 if (data != null) { 13464 String pkgName = data.getSchemeSpecificPart(); 13465 if (pkgName != null) { 13466 skipPackages = new String[] { pkgName }; 13467 } 13468 } 13469 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13470 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13471 } 13472 if (skipPackages != null && (skipPackages.length > 0)) { 13473 for (String skipPackage : skipPackages) { 13474 if (skipPackage != null) { 13475 int NT = receivers.size(); 13476 for (int it=0; it<NT; it++) { 13477 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13478 if (curt.activityInfo.packageName.equals(skipPackage)) { 13479 receivers.remove(it); 13480 it--; 13481 NT--; 13482 } 13483 } 13484 } 13485 } 13486 } 13487 13488 int NT = receivers != null ? receivers.size() : 0; 13489 int it = 0; 13490 ResolveInfo curt = null; 13491 BroadcastFilter curr = null; 13492 while (it < NT && ir < NR) { 13493 if (curt == null) { 13494 curt = (ResolveInfo)receivers.get(it); 13495 } 13496 if (curr == null) { 13497 curr = registeredReceivers.get(ir); 13498 } 13499 if (curr.getPriority() >= curt.priority) { 13500 // Insert this broadcast record into the final list. 13501 receivers.add(it, curr); 13502 ir++; 13503 curr = null; 13504 it++; 13505 NT++; 13506 } else { 13507 // Skip to the next ResolveInfo in the final list. 13508 it++; 13509 curt = null; 13510 } 13511 } 13512 } 13513 while (ir < NR) { 13514 if (receivers == null) { 13515 receivers = new ArrayList(); 13516 } 13517 receivers.add(registeredReceivers.get(ir)); 13518 ir++; 13519 } 13520 13521 if ((receivers != null && receivers.size() > 0) 13522 || resultTo != null) { 13523 BroadcastQueue queue = broadcastQueueForIntent(intent); 13524 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13525 callerPackage, callingPid, callingUid, resolvedType, 13526 requiredPermission, appOp, receivers, resultTo, resultCode, 13527 resultData, map, ordered, sticky, false, userId); 13528 if (DEBUG_BROADCAST) Slog.v( 13529 TAG, "Enqueueing ordered broadcast " + r 13530 + ": prev had " + queue.mOrderedBroadcasts.size()); 13531 if (DEBUG_BROADCAST) { 13532 int seq = r.intent.getIntExtra("seq", -1); 13533 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13534 } 13535 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13536 if (!replaced) { 13537 queue.enqueueOrderedBroadcastLocked(r); 13538 queue.scheduleBroadcastsLocked(); 13539 } 13540 } 13541 13542 return ActivityManager.BROADCAST_SUCCESS; 13543 } 13544 13545 final Intent verifyBroadcastLocked(Intent intent) { 13546 // Refuse possible leaked file descriptors 13547 if (intent != null && intent.hasFileDescriptors() == true) { 13548 throw new IllegalArgumentException("File descriptors passed in Intent"); 13549 } 13550 13551 int flags = intent.getFlags(); 13552 13553 if (!mProcessesReady) { 13554 // if the caller really truly claims to know what they're doing, go 13555 // ahead and allow the broadcast without launching any receivers 13556 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13557 intent = new Intent(intent); 13558 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13559 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13560 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13561 + " before boot completion"); 13562 throw new IllegalStateException("Cannot broadcast before boot completed"); 13563 } 13564 } 13565 13566 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13567 throw new IllegalArgumentException( 13568 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13569 } 13570 13571 return intent; 13572 } 13573 13574 public final int broadcastIntent(IApplicationThread caller, 13575 Intent intent, String resolvedType, IIntentReceiver resultTo, 13576 int resultCode, String resultData, Bundle map, 13577 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13578 enforceNotIsolatedCaller("broadcastIntent"); 13579 synchronized(this) { 13580 intent = verifyBroadcastLocked(intent); 13581 13582 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13583 final int callingPid = Binder.getCallingPid(); 13584 final int callingUid = Binder.getCallingUid(); 13585 final long origId = Binder.clearCallingIdentity(); 13586 int res = broadcastIntentLocked(callerApp, 13587 callerApp != null ? callerApp.info.packageName : null, 13588 intent, resolvedType, resultTo, 13589 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13590 callingPid, callingUid, userId); 13591 Binder.restoreCallingIdentity(origId); 13592 return res; 13593 } 13594 } 13595 13596 int broadcastIntentInPackage(String packageName, int uid, 13597 Intent intent, String resolvedType, IIntentReceiver resultTo, 13598 int resultCode, String resultData, Bundle map, 13599 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13600 synchronized(this) { 13601 intent = verifyBroadcastLocked(intent); 13602 13603 final long origId = Binder.clearCallingIdentity(); 13604 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13605 resultTo, resultCode, resultData, map, requiredPermission, 13606 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13607 Binder.restoreCallingIdentity(origId); 13608 return res; 13609 } 13610 } 13611 13612 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13613 // Refuse possible leaked file descriptors 13614 if (intent != null && intent.hasFileDescriptors() == true) { 13615 throw new IllegalArgumentException("File descriptors passed in Intent"); 13616 } 13617 13618 userId = handleIncomingUser(Binder.getCallingPid(), 13619 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13620 13621 synchronized(this) { 13622 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13623 != PackageManager.PERMISSION_GRANTED) { 13624 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13625 + Binder.getCallingPid() 13626 + ", uid=" + Binder.getCallingUid() 13627 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13628 Slog.w(TAG, msg); 13629 throw new SecurityException(msg); 13630 } 13631 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13632 if (stickies != null) { 13633 ArrayList<Intent> list = stickies.get(intent.getAction()); 13634 if (list != null) { 13635 int N = list.size(); 13636 int i; 13637 for (i=0; i<N; i++) { 13638 if (intent.filterEquals(list.get(i))) { 13639 list.remove(i); 13640 break; 13641 } 13642 } 13643 if (list.size() <= 0) { 13644 stickies.remove(intent.getAction()); 13645 } 13646 } 13647 if (stickies.size() <= 0) { 13648 mStickyBroadcasts.remove(userId); 13649 } 13650 } 13651 } 13652 } 13653 13654 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13655 String resultData, Bundle resultExtras, boolean resultAbort) { 13656 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13657 if (r == null) { 13658 Slog.w(TAG, "finishReceiver called but not found on queue"); 13659 return false; 13660 } 13661 13662 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13663 } 13664 13665 void backgroundServicesFinishedLocked(int userId) { 13666 for (BroadcastQueue queue : mBroadcastQueues) { 13667 queue.backgroundServicesFinishedLocked(userId); 13668 } 13669 } 13670 13671 public void finishReceiver(IBinder who, int resultCode, String resultData, 13672 Bundle resultExtras, boolean resultAbort) { 13673 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13674 13675 // Refuse possible leaked file descriptors 13676 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13677 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13678 } 13679 13680 final long origId = Binder.clearCallingIdentity(); 13681 try { 13682 boolean doNext = false; 13683 BroadcastRecord r; 13684 13685 synchronized(this) { 13686 r = broadcastRecordForReceiverLocked(who); 13687 if (r != null) { 13688 doNext = r.queue.finishReceiverLocked(r, resultCode, 13689 resultData, resultExtras, resultAbort, true); 13690 } 13691 } 13692 13693 if (doNext) { 13694 r.queue.processNextBroadcast(false); 13695 } 13696 trimApplications(); 13697 } finally { 13698 Binder.restoreCallingIdentity(origId); 13699 } 13700 } 13701 13702 // ========================================================= 13703 // INSTRUMENTATION 13704 // ========================================================= 13705 13706 public boolean startInstrumentation(ComponentName className, 13707 String profileFile, int flags, Bundle arguments, 13708 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13709 int userId) { 13710 enforceNotIsolatedCaller("startInstrumentation"); 13711 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13712 userId, false, true, "startInstrumentation", null); 13713 // Refuse possible leaked file descriptors 13714 if (arguments != null && arguments.hasFileDescriptors()) { 13715 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13716 } 13717 13718 synchronized(this) { 13719 InstrumentationInfo ii = null; 13720 ApplicationInfo ai = null; 13721 try { 13722 ii = mContext.getPackageManager().getInstrumentationInfo( 13723 className, STOCK_PM_FLAGS); 13724 ai = AppGlobals.getPackageManager().getApplicationInfo( 13725 ii.targetPackage, STOCK_PM_FLAGS, userId); 13726 } catch (PackageManager.NameNotFoundException e) { 13727 } catch (RemoteException e) { 13728 } 13729 if (ii == null) { 13730 reportStartInstrumentationFailure(watcher, className, 13731 "Unable to find instrumentation info for: " + className); 13732 return false; 13733 } 13734 if (ai == null) { 13735 reportStartInstrumentationFailure(watcher, className, 13736 "Unable to find instrumentation target package: " + ii.targetPackage); 13737 return false; 13738 } 13739 13740 int match = mContext.getPackageManager().checkSignatures( 13741 ii.targetPackage, ii.packageName); 13742 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13743 String msg = "Permission Denial: starting instrumentation " 13744 + className + " from pid=" 13745 + Binder.getCallingPid() 13746 + ", uid=" + Binder.getCallingPid() 13747 + " not allowed because package " + ii.packageName 13748 + " does not have a signature matching the target " 13749 + ii.targetPackage; 13750 reportStartInstrumentationFailure(watcher, className, msg); 13751 throw new SecurityException(msg); 13752 } 13753 13754 final long origId = Binder.clearCallingIdentity(); 13755 // Instrumentation can kill and relaunch even persistent processes 13756 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId, 13757 "start instr"); 13758 ProcessRecord app = addAppLocked(ai, false); 13759 app.instrumentationClass = className; 13760 app.instrumentationInfo = ai; 13761 app.instrumentationProfileFile = profileFile; 13762 app.instrumentationArguments = arguments; 13763 app.instrumentationWatcher = watcher; 13764 app.instrumentationUiAutomationConnection = uiAutomationConnection; 13765 app.instrumentationResultClass = className; 13766 Binder.restoreCallingIdentity(origId); 13767 } 13768 13769 return true; 13770 } 13771 13772 /** 13773 * Report errors that occur while attempting to start Instrumentation. Always writes the 13774 * error to the logs, but if somebody is watching, send the report there too. This enables 13775 * the "am" command to report errors with more information. 13776 * 13777 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13778 * @param cn The component name of the instrumentation. 13779 * @param report The error report. 13780 */ 13781 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13782 ComponentName cn, String report) { 13783 Slog.w(TAG, report); 13784 try { 13785 if (watcher != null) { 13786 Bundle results = new Bundle(); 13787 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13788 results.putString("Error", report); 13789 watcher.instrumentationStatus(cn, -1, results); 13790 } 13791 } catch (RemoteException e) { 13792 Slog.w(TAG, e); 13793 } 13794 } 13795 13796 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13797 if (app.instrumentationWatcher != null) { 13798 try { 13799 // NOTE: IInstrumentationWatcher *must* be oneway here 13800 app.instrumentationWatcher.instrumentationFinished( 13801 app.instrumentationClass, 13802 resultCode, 13803 results); 13804 } catch (RemoteException e) { 13805 } 13806 } 13807 if (app.instrumentationUiAutomationConnection != null) { 13808 try { 13809 app.instrumentationUiAutomationConnection.shutdown(); 13810 } catch (RemoteException re) { 13811 /* ignore */ 13812 } 13813 // Only a UiAutomation can set this flag and now that 13814 // it is finished we make sure it is reset to its default. 13815 mUserIsMonkey = false; 13816 } 13817 app.instrumentationWatcher = null; 13818 app.instrumentationUiAutomationConnection = null; 13819 app.instrumentationClass = null; 13820 app.instrumentationInfo = null; 13821 app.instrumentationProfileFile = null; 13822 app.instrumentationArguments = null; 13823 13824 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId, 13825 "finished inst"); 13826 } 13827 13828 public void finishInstrumentation(IApplicationThread target, 13829 int resultCode, Bundle results) { 13830 int userId = UserHandle.getCallingUserId(); 13831 // Refuse possible leaked file descriptors 13832 if (results != null && results.hasFileDescriptors()) { 13833 throw new IllegalArgumentException("File descriptors passed in Intent"); 13834 } 13835 13836 synchronized(this) { 13837 ProcessRecord app = getRecordForAppLocked(target); 13838 if (app == null) { 13839 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13840 return; 13841 } 13842 final long origId = Binder.clearCallingIdentity(); 13843 finishInstrumentationLocked(app, resultCode, results); 13844 Binder.restoreCallingIdentity(origId); 13845 } 13846 } 13847 13848 // ========================================================= 13849 // CONFIGURATION 13850 // ========================================================= 13851 13852 public ConfigurationInfo getDeviceConfigurationInfo() { 13853 ConfigurationInfo config = new ConfigurationInfo(); 13854 synchronized (this) { 13855 config.reqTouchScreen = mConfiguration.touchscreen; 13856 config.reqKeyboardType = mConfiguration.keyboard; 13857 config.reqNavigation = mConfiguration.navigation; 13858 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13859 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13860 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13861 } 13862 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13863 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13864 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13865 } 13866 config.reqGlEsVersion = GL_ES_VERSION; 13867 } 13868 return config; 13869 } 13870 13871 ActivityStack getFocusedStack() { 13872 return mStackSupervisor.getFocusedStack(); 13873 } 13874 13875 public Configuration getConfiguration() { 13876 Configuration ci; 13877 synchronized(this) { 13878 ci = new Configuration(mConfiguration); 13879 } 13880 return ci; 13881 } 13882 13883 public void updatePersistentConfiguration(Configuration values) { 13884 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13885 "updateConfiguration()"); 13886 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 13887 "updateConfiguration()"); 13888 if (values == null) { 13889 throw new NullPointerException("Configuration must not be null"); 13890 } 13891 13892 synchronized(this) { 13893 final long origId = Binder.clearCallingIdentity(); 13894 updateConfigurationLocked(values, null, true, false); 13895 Binder.restoreCallingIdentity(origId); 13896 } 13897 } 13898 13899 public void updateConfiguration(Configuration values) { 13900 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13901 "updateConfiguration()"); 13902 13903 synchronized(this) { 13904 if (values == null && mWindowManager != null) { 13905 // sentinel: fetch the current configuration from the window manager 13906 values = mWindowManager.computeNewConfiguration(); 13907 } 13908 13909 if (mWindowManager != null) { 13910 mProcessList.applyDisplaySize(mWindowManager); 13911 } 13912 13913 final long origId = Binder.clearCallingIdentity(); 13914 if (values != null) { 13915 Settings.System.clearConfiguration(values); 13916 } 13917 updateConfigurationLocked(values, null, false, false); 13918 Binder.restoreCallingIdentity(origId); 13919 } 13920 } 13921 13922 /** 13923 * Do either or both things: (1) change the current configuration, and (2) 13924 * make sure the given activity is running with the (now) current 13925 * configuration. Returns true if the activity has been left running, or 13926 * false if <var>starting</var> is being destroyed to match the new 13927 * configuration. 13928 * @param persistent TODO 13929 */ 13930 boolean updateConfigurationLocked(Configuration values, 13931 ActivityRecord starting, boolean persistent, boolean initLocale) { 13932 int changes = 0; 13933 13934 if (values != null) { 13935 Configuration newConfig = new Configuration(mConfiguration); 13936 changes = newConfig.updateFrom(values); 13937 if (changes != 0) { 13938 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13939 Slog.i(TAG, "Updating configuration to: " + values); 13940 } 13941 13942 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 13943 13944 if (values.locale != null && !initLocale) { 13945 saveLocaleLocked(values.locale, 13946 !values.locale.equals(mConfiguration.locale), 13947 values.userSetLocale); 13948 } 13949 13950 mConfigurationSeq++; 13951 if (mConfigurationSeq <= 0) { 13952 mConfigurationSeq = 1; 13953 } 13954 newConfig.seq = mConfigurationSeq; 13955 mConfiguration = newConfig; 13956 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 13957 13958 final Configuration configCopy = new Configuration(mConfiguration); 13959 13960 // TODO: If our config changes, should we auto dismiss any currently 13961 // showing dialogs? 13962 mShowDialogs = shouldShowDialogs(newConfig); 13963 13964 AttributeCache ac = AttributeCache.instance(); 13965 if (ac != null) { 13966 ac.updateConfiguration(configCopy); 13967 } 13968 13969 // Make sure all resources in our process are updated 13970 // right now, so that anyone who is going to retrieve 13971 // resource values after we return will be sure to get 13972 // the new ones. This is especially important during 13973 // boot, where the first config change needs to guarantee 13974 // all resources have that config before following boot 13975 // code is executed. 13976 mSystemThread.applyConfigurationToResources(configCopy); 13977 13978 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 13979 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 13980 msg.obj = new Configuration(configCopy); 13981 mHandler.sendMessage(msg); 13982 } 13983 13984 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13985 ProcessRecord app = mLruProcesses.get(i); 13986 try { 13987 if (app.thread != null) { 13988 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 13989 + app.processName + " new config " + mConfiguration); 13990 app.thread.scheduleConfigurationChanged(configCopy); 13991 } 13992 } catch (Exception e) { 13993 } 13994 } 13995 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 13996 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 13997 | Intent.FLAG_RECEIVER_REPLACE_PENDING 13998 | Intent.FLAG_RECEIVER_FOREGROUND); 13999 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14000 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14001 Process.SYSTEM_UID, UserHandle.USER_ALL); 14002 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14003 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14004 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14005 broadcastIntentLocked(null, null, intent, 14006 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14007 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14008 } 14009 } 14010 } 14011 14012 boolean kept = true; 14013 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14014 // mainStack is null during startup. 14015 if (mainStack != null) { 14016 if (changes != 0 && starting == null) { 14017 // If the configuration changed, and the caller is not already 14018 // in the process of starting an activity, then find the top 14019 // activity to check if its configuration needs to change. 14020 starting = mainStack.topRunningActivityLocked(null); 14021 } 14022 14023 if (starting != null) { 14024 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14025 // And we need to make sure at this point that all other activities 14026 // are made visible with the correct configuration. 14027 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14028 } 14029 } 14030 14031 if (values != null && mWindowManager != null) { 14032 mWindowManager.setNewConfiguration(mConfiguration); 14033 } 14034 14035 return kept; 14036 } 14037 14038 /** 14039 * Decide based on the configuration whether we should shouw the ANR, 14040 * crash, etc dialogs. The idea is that if there is no affordnace to 14041 * press the on-screen buttons, we shouldn't show the dialog. 14042 * 14043 * A thought: SystemUI might also want to get told about this, the Power 14044 * dialog / global actions also might want different behaviors. 14045 */ 14046 private static final boolean shouldShowDialogs(Configuration config) { 14047 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14048 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14049 } 14050 14051 /** 14052 * Save the locale. You must be inside a synchronized (this) block. 14053 */ 14054 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14055 if(isDiff) { 14056 SystemProperties.set("user.language", l.getLanguage()); 14057 SystemProperties.set("user.region", l.getCountry()); 14058 } 14059 14060 if(isPersist) { 14061 SystemProperties.set("persist.sys.language", l.getLanguage()); 14062 SystemProperties.set("persist.sys.country", l.getCountry()); 14063 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14064 } 14065 } 14066 14067 @Override 14068 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14069 ActivityRecord srec = ActivityRecord.forToken(token); 14070 return srec != null && srec.task.affinity != null && 14071 srec.task.affinity.equals(destAffinity); 14072 } 14073 14074 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14075 Intent resultData) { 14076 14077 synchronized (this) { 14078 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14079 if (stack != null) { 14080 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14081 } 14082 return false; 14083 } 14084 } 14085 14086 public int getLaunchedFromUid(IBinder activityToken) { 14087 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14088 if (srec == null) { 14089 return -1; 14090 } 14091 return srec.launchedFromUid; 14092 } 14093 14094 public String getLaunchedFromPackage(IBinder activityToken) { 14095 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14096 if (srec == null) { 14097 return null; 14098 } 14099 return srec.launchedFromPackage; 14100 } 14101 14102 // ========================================================= 14103 // LIFETIME MANAGEMENT 14104 // ========================================================= 14105 14106 // Returns which broadcast queue the app is the current [or imminent] receiver 14107 // on, or 'null' if the app is not an active broadcast recipient. 14108 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14109 BroadcastRecord r = app.curReceiver; 14110 if (r != null) { 14111 return r.queue; 14112 } 14113 14114 // It's not the current receiver, but it might be starting up to become one 14115 synchronized (this) { 14116 for (BroadcastQueue queue : mBroadcastQueues) { 14117 r = queue.mPendingBroadcast; 14118 if (r != null && r.curApp == app) { 14119 // found it; report which queue it's in 14120 return queue; 14121 } 14122 } 14123 } 14124 14125 return null; 14126 } 14127 14128 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14129 boolean doingAll, long now) { 14130 if (mAdjSeq == app.adjSeq) { 14131 // This adjustment has already been computed. 14132 return app.curRawAdj; 14133 } 14134 14135 if (app.thread == null) { 14136 app.adjSeq = mAdjSeq; 14137 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14138 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14139 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14140 } 14141 14142 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14143 app.adjSource = null; 14144 app.adjTarget = null; 14145 app.empty = false; 14146 app.cached = false; 14147 14148 final int activitiesSize = app.activities.size(); 14149 14150 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14151 // The max adjustment doesn't allow this app to be anything 14152 // below foreground, so it is not worth doing work for it. 14153 app.adjType = "fixed"; 14154 app.adjSeq = mAdjSeq; 14155 app.curRawAdj = app.maxAdj; 14156 app.foregroundActivities = false; 14157 app.keeping = true; 14158 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14159 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14160 // System process can do UI, and when they do we want to have 14161 // them trim their memory after the user leaves the UI. To 14162 // facilitate this, here we need to determine whether or not it 14163 // is currently showing UI. 14164 app.systemNoUi = true; 14165 if (app == TOP_APP) { 14166 app.systemNoUi = false; 14167 } else if (activitiesSize > 0) { 14168 for (int j = 0; j < activitiesSize; j++) { 14169 final ActivityRecord r = app.activities.get(j); 14170 if (r.visible) { 14171 app.systemNoUi = false; 14172 } 14173 } 14174 } 14175 if (!app.systemNoUi) { 14176 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14177 } 14178 return (app.curAdj=app.maxAdj); 14179 } 14180 14181 app.keeping = false; 14182 app.systemNoUi = false; 14183 14184 // Determine the importance of the process, starting with most 14185 // important to least, and assign an appropriate OOM adjustment. 14186 int adj; 14187 int schedGroup; 14188 int procState; 14189 boolean foregroundActivities = false; 14190 boolean interesting = false; 14191 BroadcastQueue queue; 14192 if (app == TOP_APP) { 14193 // The last app on the list is the foreground app. 14194 adj = ProcessList.FOREGROUND_APP_ADJ; 14195 schedGroup = Process.THREAD_GROUP_DEFAULT; 14196 app.adjType = "top-activity"; 14197 foregroundActivities = true; 14198 interesting = true; 14199 procState = ActivityManager.PROCESS_STATE_TOP; 14200 } else if (app.instrumentationClass != null) { 14201 // Don't want to kill running instrumentation. 14202 adj = ProcessList.FOREGROUND_APP_ADJ; 14203 schedGroup = Process.THREAD_GROUP_DEFAULT; 14204 app.adjType = "instrumentation"; 14205 interesting = true; 14206 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14207 } else if ((queue = isReceivingBroadcast(app)) != null) { 14208 // An app that is currently receiving a broadcast also 14209 // counts as being in the foreground for OOM killer purposes. 14210 // It's placed in a sched group based on the nature of the 14211 // broadcast as reflected by which queue it's active in. 14212 adj = ProcessList.FOREGROUND_APP_ADJ; 14213 schedGroup = (queue == mFgBroadcastQueue) 14214 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14215 app.adjType = "broadcast"; 14216 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14217 } else if (app.executingServices.size() > 0) { 14218 // An app that is currently executing a service callback also 14219 // counts as being in the foreground. 14220 adj = ProcessList.FOREGROUND_APP_ADJ; 14221 schedGroup = app.execServicesFg ? 14222 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14223 app.adjType = "exec-service"; 14224 procState = ActivityManager.PROCESS_STATE_SERVICE; 14225 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14226 } else { 14227 // As far as we know the process is empty. We may change our mind later. 14228 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14229 // At this point we don't actually know the adjustment. Use the cached adj 14230 // value that the caller wants us to. 14231 adj = cachedAdj; 14232 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14233 app.cached = true; 14234 app.empty = true; 14235 app.adjType = "cch-empty"; 14236 } 14237 14238 // Examine all activities if not already foreground. 14239 if (!foregroundActivities && activitiesSize > 0) { 14240 for (int j = 0; j < activitiesSize; j++) { 14241 final ActivityRecord r = app.activities.get(j); 14242 if (r.app != app) { 14243 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14244 + app + "?!?"); 14245 continue; 14246 } 14247 if (r.visible) { 14248 // App has a visible activity; only upgrade adjustment. 14249 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14250 adj = ProcessList.VISIBLE_APP_ADJ; 14251 app.adjType = "visible"; 14252 } 14253 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14254 procState = ActivityManager.PROCESS_STATE_TOP; 14255 } 14256 schedGroup = Process.THREAD_GROUP_DEFAULT; 14257 app.cached = false; 14258 app.empty = false; 14259 foregroundActivities = true; 14260 break; 14261 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14262 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14263 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14264 app.adjType = "pausing"; 14265 } 14266 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14267 procState = ActivityManager.PROCESS_STATE_TOP; 14268 } 14269 schedGroup = Process.THREAD_GROUP_DEFAULT; 14270 app.cached = false; 14271 app.empty = false; 14272 foregroundActivities = true; 14273 } else if (r.state == ActivityState.STOPPING) { 14274 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14275 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14276 app.adjType = "stopping"; 14277 } 14278 // For the process state, we will at this point consider the 14279 // process to be cached. It will be cached either as an activity 14280 // or empty depending on whether the activity is finishing. We do 14281 // this so that we can treat the process as cached for purposes of 14282 // memory trimming (determing current memory level, trim command to 14283 // send to process) since there can be an arbitrary number of stopping 14284 // processes and they should soon all go into the cached state. 14285 if (!r.finishing) { 14286 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14287 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14288 } 14289 } 14290 app.cached = false; 14291 app.empty = false; 14292 foregroundActivities = true; 14293 } else { 14294 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14295 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14296 app.adjType = "cch-act"; 14297 } 14298 } 14299 } 14300 } 14301 14302 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14303 if (app.foregroundServices) { 14304 // The user is aware of this app, so make it visible. 14305 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14306 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14307 app.cached = false; 14308 app.adjType = "fg-service"; 14309 schedGroup = Process.THREAD_GROUP_DEFAULT; 14310 } else if (app.forcingToForeground != null) { 14311 // The user is aware of this app, so make it visible. 14312 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14313 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14314 app.cached = false; 14315 app.adjType = "force-fg"; 14316 app.adjSource = app.forcingToForeground; 14317 schedGroup = Process.THREAD_GROUP_DEFAULT; 14318 } 14319 } 14320 14321 if (app.foregroundServices) { 14322 interesting = true; 14323 } 14324 14325 if (app == mHeavyWeightProcess) { 14326 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14327 // We don't want to kill the current heavy-weight process. 14328 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14329 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14330 app.cached = false; 14331 app.adjType = "heavy"; 14332 } 14333 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14334 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14335 } 14336 } 14337 14338 if (app == mHomeProcess) { 14339 if (adj > ProcessList.HOME_APP_ADJ) { 14340 // This process is hosting what we currently consider to be the 14341 // home app, so we don't want to let it go into the background. 14342 adj = ProcessList.HOME_APP_ADJ; 14343 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14344 app.cached = false; 14345 app.adjType = "home"; 14346 } 14347 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14348 procState = ActivityManager.PROCESS_STATE_HOME; 14349 } 14350 } 14351 14352 if (app == mPreviousProcess && app.activities.size() > 0) { 14353 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14354 // This was the previous process that showed UI to the user. 14355 // We want to try to keep it around more aggressively, to give 14356 // a good experience around switching between two apps. 14357 adj = ProcessList.PREVIOUS_APP_ADJ; 14358 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14359 app.cached = false; 14360 app.adjType = "previous"; 14361 } 14362 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14363 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14364 } 14365 } 14366 14367 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14368 + " reason=" + app.adjType); 14369 14370 // By default, we use the computed adjustment. It may be changed if 14371 // there are applications dependent on our services or providers, but 14372 // this gives us a baseline and makes sure we don't get into an 14373 // infinite recursion. 14374 app.adjSeq = mAdjSeq; 14375 app.curRawAdj = adj; 14376 app.hasStartedServices = false; 14377 14378 if (mBackupTarget != null && app == mBackupTarget.app) { 14379 // If possible we want to avoid killing apps while they're being backed up 14380 if (adj > ProcessList.BACKUP_APP_ADJ) { 14381 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14382 adj = ProcessList.BACKUP_APP_ADJ; 14383 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14384 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14385 } 14386 app.adjType = "backup"; 14387 app.cached = false; 14388 } 14389 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14390 procState = ActivityManager.PROCESS_STATE_BACKUP; 14391 } 14392 } 14393 14394 boolean mayBeTop = false; 14395 14396 for (int is = app.services.size()-1; 14397 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14398 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14399 || procState > ActivityManager.PROCESS_STATE_TOP); 14400 is--) { 14401 ServiceRecord s = app.services.valueAt(is); 14402 if (s.startRequested) { 14403 app.hasStartedServices = true; 14404 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14405 procState = ActivityManager.PROCESS_STATE_SERVICE; 14406 } 14407 if (app.hasShownUi && app != mHomeProcess) { 14408 // If this process has shown some UI, let it immediately 14409 // go to the LRU list because it may be pretty heavy with 14410 // UI stuff. We'll tag it with a label just to help 14411 // debug and understand what is going on. 14412 if (adj > ProcessList.SERVICE_ADJ) { 14413 app.adjType = "cch-started-ui-services"; 14414 } 14415 } else { 14416 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14417 // This service has seen some activity within 14418 // recent memory, so we will keep its process ahead 14419 // of the background processes. 14420 if (adj > ProcessList.SERVICE_ADJ) { 14421 adj = ProcessList.SERVICE_ADJ; 14422 app.adjType = "started-services"; 14423 app.cached = false; 14424 } 14425 } 14426 // If we have let the service slide into the background 14427 // state, still have some text describing what it is doing 14428 // even though the service no longer has an impact. 14429 if (adj > ProcessList.SERVICE_ADJ) { 14430 app.adjType = "cch-started-services"; 14431 } 14432 } 14433 // Don't kill this process because it is doing work; it 14434 // has said it is doing work. 14435 app.keeping = true; 14436 } 14437 for (int conni = s.connections.size()-1; 14438 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14439 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14440 || procState > ActivityManager.PROCESS_STATE_TOP); 14441 conni--) { 14442 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14443 for (int i = 0; 14444 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14445 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14446 || procState > ActivityManager.PROCESS_STATE_TOP); 14447 i++) { 14448 // XXX should compute this based on the max of 14449 // all connected clients. 14450 ConnectionRecord cr = clist.get(i); 14451 if (cr.binding.client == app) { 14452 // Binding to ourself is not interesting. 14453 continue; 14454 } 14455 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14456 ProcessRecord client = cr.binding.client; 14457 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14458 TOP_APP, doingAll, now); 14459 int clientProcState = client.curProcState; 14460 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14461 // If the other app is cached for any reason, for purposes here 14462 // we are going to consider it empty. The specific cached state 14463 // doesn't propagate except under certain conditions. 14464 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14465 } 14466 String adjType = null; 14467 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14468 // Not doing bind OOM management, so treat 14469 // this guy more like a started service. 14470 if (app.hasShownUi && app != mHomeProcess) { 14471 // If this process has shown some UI, let it immediately 14472 // go to the LRU list because it may be pretty heavy with 14473 // UI stuff. We'll tag it with a label just to help 14474 // debug and understand what is going on. 14475 if (adj > clientAdj) { 14476 adjType = "cch-bound-ui-services"; 14477 } 14478 app.cached = false; 14479 clientAdj = adj; 14480 clientProcState = procState; 14481 } else { 14482 if (now >= (s.lastActivity 14483 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14484 // This service has not seen activity within 14485 // recent memory, so allow it to drop to the 14486 // LRU list if there is no other reason to keep 14487 // it around. We'll also tag it with a label just 14488 // to help debug and undertand what is going on. 14489 if (adj > clientAdj) { 14490 adjType = "cch-bound-services"; 14491 } 14492 clientAdj = adj; 14493 } 14494 } 14495 } 14496 if (adj > clientAdj) { 14497 // If this process has recently shown UI, and 14498 // the process that is binding to it is less 14499 // important than being visible, then we don't 14500 // care about the binding as much as we care 14501 // about letting this process get into the LRU 14502 // list to be killed and restarted if needed for 14503 // memory. 14504 if (app.hasShownUi && app != mHomeProcess 14505 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14506 adjType = "cch-bound-ui-services"; 14507 } else { 14508 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14509 |Context.BIND_IMPORTANT)) != 0) { 14510 adj = clientAdj; 14511 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14512 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14513 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14514 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14515 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14516 adj = clientAdj; 14517 } else { 14518 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14519 adj = ProcessList.VISIBLE_APP_ADJ; 14520 } 14521 } 14522 if (!client.cached) { 14523 app.cached = false; 14524 } 14525 if (client.keeping) { 14526 app.keeping = true; 14527 } 14528 adjType = "service"; 14529 } 14530 } 14531 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14532 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14533 schedGroup = Process.THREAD_GROUP_DEFAULT; 14534 } 14535 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14536 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14537 // Special handling of clients who are in the top state. 14538 // We *may* want to consider this process to be in the 14539 // top state as well, but only if there is not another 14540 // reason for it to be running. Being on the top is a 14541 // special state, meaning you are specifically running 14542 // for the current top app. If the process is already 14543 // running in the background for some other reason, it 14544 // is more important to continue considering it to be 14545 // in the background state. 14546 mayBeTop = true; 14547 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14548 } else { 14549 // Special handling for above-top states (persistent 14550 // processes). These should not bring the current process 14551 // into the top state, since they are not on top. Instead 14552 // give them the best state after that. 14553 clientProcState = 14554 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14555 } 14556 } 14557 } else { 14558 if (clientProcState < 14559 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14560 clientProcState = 14561 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14562 } 14563 } 14564 if (procState > clientProcState) { 14565 procState = clientProcState; 14566 } 14567 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14568 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14569 app.pendingUiClean = true; 14570 } 14571 if (adjType != null) { 14572 app.adjType = adjType; 14573 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14574 .REASON_SERVICE_IN_USE; 14575 app.adjSource = cr.binding.client; 14576 app.adjSourceOom = clientAdj; 14577 app.adjTarget = s.name; 14578 } 14579 } 14580 final ActivityRecord a = cr.activity; 14581 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14582 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14583 (a.visible || a.state == ActivityState.RESUMED 14584 || a.state == ActivityState.PAUSING)) { 14585 adj = ProcessList.FOREGROUND_APP_ADJ; 14586 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14587 schedGroup = Process.THREAD_GROUP_DEFAULT; 14588 } 14589 app.cached = false; 14590 app.adjType = "service"; 14591 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14592 .REASON_SERVICE_IN_USE; 14593 app.adjSource = a; 14594 app.adjSourceOom = adj; 14595 app.adjTarget = s.name; 14596 } 14597 } 14598 } 14599 } 14600 } 14601 14602 for (int provi = app.pubProviders.size()-1; 14603 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14604 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14605 || procState > ActivityManager.PROCESS_STATE_TOP); 14606 provi--) { 14607 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14608 for (int i = cpr.connections.size()-1; 14609 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14610 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14611 || procState > ActivityManager.PROCESS_STATE_TOP); 14612 i--) { 14613 ContentProviderConnection conn = cpr.connections.get(i); 14614 ProcessRecord client = conn.client; 14615 if (client == app) { 14616 // Being our own client is not interesting. 14617 continue; 14618 } 14619 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14620 int clientProcState = client.curProcState; 14621 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14622 // If the other app is cached for any reason, for purposes here 14623 // we are going to consider it empty. 14624 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14625 } 14626 if (adj > clientAdj) { 14627 if (app.hasShownUi && app != mHomeProcess 14628 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14629 app.adjType = "cch-ui-provider"; 14630 } else { 14631 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14632 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14633 app.adjType = "provider"; 14634 } 14635 app.cached &= client.cached; 14636 app.keeping |= client.keeping; 14637 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14638 .REASON_PROVIDER_IN_USE; 14639 app.adjSource = client; 14640 app.adjSourceOom = clientAdj; 14641 app.adjTarget = cpr.name; 14642 } 14643 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14644 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14645 // Special handling of clients who are in the top state. 14646 // We *may* want to consider this process to be in the 14647 // top state as well, but only if there is not another 14648 // reason for it to be running. Being on the top is a 14649 // special state, meaning you are specifically running 14650 // for the current top app. If the process is already 14651 // running in the background for some other reason, it 14652 // is more important to continue considering it to be 14653 // in the background state. 14654 mayBeTop = true; 14655 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14656 } else { 14657 // Special handling for above-top states (persistent 14658 // processes). These should not bring the current process 14659 // into the top state, since they are not on top. Instead 14660 // give them the best state after that. 14661 clientProcState = 14662 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14663 } 14664 } 14665 if (procState > clientProcState) { 14666 procState = clientProcState; 14667 } 14668 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14669 schedGroup = Process.THREAD_GROUP_DEFAULT; 14670 } 14671 } 14672 // If the provider has external (non-framework) process 14673 // dependencies, ensure that its adjustment is at least 14674 // FOREGROUND_APP_ADJ. 14675 if (cpr.hasExternalProcessHandles()) { 14676 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14677 adj = ProcessList.FOREGROUND_APP_ADJ; 14678 schedGroup = Process.THREAD_GROUP_DEFAULT; 14679 app.cached = false; 14680 app.keeping = true; 14681 app.adjType = "provider"; 14682 app.adjTarget = cpr.name; 14683 } 14684 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14685 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14686 } 14687 } 14688 } 14689 14690 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14691 // A client of one of our services or providers is in the top state. We 14692 // *may* want to be in the top state, but not if we are already running in 14693 // the background for some other reason. For the decision here, we are going 14694 // to pick out a few specific states that we want to remain in when a client 14695 // is top (states that tend to be longer-term) and otherwise allow it to go 14696 // to the top state. 14697 switch (procState) { 14698 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14699 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14700 case ActivityManager.PROCESS_STATE_SERVICE: 14701 // These all are longer-term states, so pull them up to the top 14702 // of the background states, but not all the way to the top state. 14703 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14704 break; 14705 default: 14706 // Otherwise, top is a better choice, so take it. 14707 procState = ActivityManager.PROCESS_STATE_TOP; 14708 break; 14709 } 14710 } 14711 14712 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14713 // This is a cached process, but with client activities. Mark it so. 14714 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14715 app.adjType = "cch-client-act"; 14716 } 14717 14718 if (adj == ProcessList.SERVICE_ADJ) { 14719 if (doingAll) { 14720 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14721 mNewNumServiceProcs++; 14722 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14723 if (!app.serviceb) { 14724 // This service isn't far enough down on the LRU list to 14725 // normally be a B service, but if we are low on RAM and it 14726 // is large we want to force it down since we would prefer to 14727 // keep launcher over it. 14728 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 14729 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 14730 app.serviceHighRam = true; 14731 app.serviceb = true; 14732 //Slog.i(TAG, "ADJ " + app + " high ram!"); 14733 } else { 14734 mNewNumAServiceProcs++; 14735 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 14736 } 14737 } else { 14738 app.serviceHighRam = false; 14739 } 14740 } 14741 if (app.serviceb) { 14742 adj = ProcessList.SERVICE_B_ADJ; 14743 } 14744 } 14745 14746 app.curRawAdj = adj; 14747 14748 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14749 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14750 if (adj > app.maxAdj) { 14751 adj = app.maxAdj; 14752 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14753 schedGroup = Process.THREAD_GROUP_DEFAULT; 14754 } 14755 } 14756 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 14757 app.keeping = true; 14758 } 14759 14760 // Do final modification to adj. Everything we do between here and applying 14761 // the final setAdj must be done in this function, because we will also use 14762 // it when computing the final cached adj later. Note that we don't need to 14763 // worry about this for max adj above, since max adj will always be used to 14764 // keep it out of the cached vaues. 14765 adj = app.modifyRawOomAdj(adj); 14766 14767 app.curProcState = procState; 14768 14769 int importance = app.memImportance; 14770 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14771 app.curAdj = adj; 14772 app.curSchedGroup = schedGroup; 14773 if (!interesting) { 14774 // For this reporting, if there is not something explicitly 14775 // interesting in this process then we will push it to the 14776 // background importance. 14777 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14778 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 14779 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14780 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14781 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14782 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14783 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14784 } else if (adj >= ProcessList.SERVICE_ADJ) { 14785 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14786 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14787 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14788 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14789 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14790 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14791 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14792 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14793 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14794 } else { 14795 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14796 } 14797 } 14798 14799 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14800 if (foregroundActivities != app.foregroundActivities) { 14801 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14802 } 14803 if (changes != 0) { 14804 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14805 app.memImportance = importance; 14806 app.foregroundActivities = foregroundActivities; 14807 int i = mPendingProcessChanges.size()-1; 14808 ProcessChangeItem item = null; 14809 while (i >= 0) { 14810 item = mPendingProcessChanges.get(i); 14811 if (item.pid == app.pid) { 14812 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14813 break; 14814 } 14815 i--; 14816 } 14817 if (i < 0) { 14818 // No existing item in pending changes; need a new one. 14819 final int NA = mAvailProcessChanges.size(); 14820 if (NA > 0) { 14821 item = mAvailProcessChanges.remove(NA-1); 14822 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14823 } else { 14824 item = new ProcessChangeItem(); 14825 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14826 } 14827 item.changes = 0; 14828 item.pid = app.pid; 14829 item.uid = app.info.uid; 14830 if (mPendingProcessChanges.size() == 0) { 14831 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14832 "*** Enqueueing dispatch processes changed!"); 14833 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14834 } 14835 mPendingProcessChanges.add(item); 14836 } 14837 item.changes |= changes; 14838 item.importance = importance; 14839 item.foregroundActivities = foregroundActivities; 14840 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14841 + Integer.toHexString(System.identityHashCode(item)) 14842 + " " + app.toShortString() + ": changes=" + item.changes 14843 + " importance=" + item.importance 14844 + " foreground=" + item.foregroundActivities 14845 + " type=" + app.adjType + " source=" + app.adjSource 14846 + " target=" + app.adjTarget); 14847 } 14848 14849 return app.curRawAdj; 14850 } 14851 14852 /** 14853 * Schedule PSS collection of a process. 14854 */ 14855 void requestPssLocked(ProcessRecord proc, int procState) { 14856 if (mPendingPssProcesses.contains(proc)) { 14857 return; 14858 } 14859 if (mPendingPssProcesses.size() == 0) { 14860 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14861 } 14862 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 14863 proc.pssProcState = procState; 14864 mPendingPssProcesses.add(proc); 14865 } 14866 14867 /** 14868 * Schedule PSS collection of all processes. 14869 */ 14870 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 14871 if (!always) { 14872 if (now < (mLastFullPssTime + 14873 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 14874 return; 14875 } 14876 } 14877 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 14878 mLastFullPssTime = now; 14879 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 14880 mPendingPssProcesses.clear(); 14881 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14882 ProcessRecord app = mLruProcesses.get(i); 14883 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 14884 app.pssProcState = app.setProcState; 14885 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 14886 mSleeping, now); 14887 mPendingPssProcesses.add(app); 14888 } 14889 } 14890 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14891 } 14892 14893 /** 14894 * Ask a given process to GC right now. 14895 */ 14896 final void performAppGcLocked(ProcessRecord app) { 14897 try { 14898 app.lastRequestedGc = SystemClock.uptimeMillis(); 14899 if (app.thread != null) { 14900 if (app.reportLowMemory) { 14901 app.reportLowMemory = false; 14902 app.thread.scheduleLowMemory(); 14903 } else { 14904 app.thread.processInBackground(); 14905 } 14906 } 14907 } catch (Exception e) { 14908 // whatever. 14909 } 14910 } 14911 14912 /** 14913 * Returns true if things are idle enough to perform GCs. 14914 */ 14915 private final boolean canGcNowLocked() { 14916 boolean processingBroadcasts = false; 14917 for (BroadcastQueue q : mBroadcastQueues) { 14918 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 14919 processingBroadcasts = true; 14920 } 14921 } 14922 return !processingBroadcasts 14923 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 14924 } 14925 14926 /** 14927 * Perform GCs on all processes that are waiting for it, but only 14928 * if things are idle. 14929 */ 14930 final void performAppGcsLocked() { 14931 final int N = mProcessesToGc.size(); 14932 if (N <= 0) { 14933 return; 14934 } 14935 if (canGcNowLocked()) { 14936 while (mProcessesToGc.size() > 0) { 14937 ProcessRecord proc = mProcessesToGc.remove(0); 14938 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 14939 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 14940 <= SystemClock.uptimeMillis()) { 14941 // To avoid spamming the system, we will GC processes one 14942 // at a time, waiting a few seconds between each. 14943 performAppGcLocked(proc); 14944 scheduleAppGcsLocked(); 14945 return; 14946 } else { 14947 // It hasn't been long enough since we last GCed this 14948 // process... put it in the list to wait for its time. 14949 addProcessToGcListLocked(proc); 14950 break; 14951 } 14952 } 14953 } 14954 14955 scheduleAppGcsLocked(); 14956 } 14957 } 14958 14959 /** 14960 * If all looks good, perform GCs on all processes waiting for them. 14961 */ 14962 final void performAppGcsIfAppropriateLocked() { 14963 if (canGcNowLocked()) { 14964 performAppGcsLocked(); 14965 return; 14966 } 14967 // Still not idle, wait some more. 14968 scheduleAppGcsLocked(); 14969 } 14970 14971 /** 14972 * Schedule the execution of all pending app GCs. 14973 */ 14974 final void scheduleAppGcsLocked() { 14975 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 14976 14977 if (mProcessesToGc.size() > 0) { 14978 // Schedule a GC for the time to the next process. 14979 ProcessRecord proc = mProcessesToGc.get(0); 14980 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 14981 14982 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 14983 long now = SystemClock.uptimeMillis(); 14984 if (when < (now+GC_TIMEOUT)) { 14985 when = now + GC_TIMEOUT; 14986 } 14987 mHandler.sendMessageAtTime(msg, when); 14988 } 14989 } 14990 14991 /** 14992 * Add a process to the array of processes waiting to be GCed. Keeps the 14993 * list in sorted order by the last GC time. The process can't already be 14994 * on the list. 14995 */ 14996 final void addProcessToGcListLocked(ProcessRecord proc) { 14997 boolean added = false; 14998 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 14999 if (mProcessesToGc.get(i).lastRequestedGc < 15000 proc.lastRequestedGc) { 15001 added = true; 15002 mProcessesToGc.add(i+1, proc); 15003 break; 15004 } 15005 } 15006 if (!added) { 15007 mProcessesToGc.add(0, proc); 15008 } 15009 } 15010 15011 /** 15012 * Set up to ask a process to GC itself. This will either do it 15013 * immediately, or put it on the list of processes to gc the next 15014 * time things are idle. 15015 */ 15016 final void scheduleAppGcLocked(ProcessRecord app) { 15017 long now = SystemClock.uptimeMillis(); 15018 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15019 return; 15020 } 15021 if (!mProcessesToGc.contains(app)) { 15022 addProcessToGcListLocked(app); 15023 scheduleAppGcsLocked(); 15024 } 15025 } 15026 15027 final void checkExcessivePowerUsageLocked(boolean doKills) { 15028 updateCpuStatsNow(); 15029 15030 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15031 boolean doWakeKills = doKills; 15032 boolean doCpuKills = doKills; 15033 if (mLastPowerCheckRealtime == 0) { 15034 doWakeKills = false; 15035 } 15036 if (mLastPowerCheckUptime == 0) { 15037 doCpuKills = false; 15038 } 15039 if (stats.isScreenOn()) { 15040 doWakeKills = false; 15041 } 15042 final long curRealtime = SystemClock.elapsedRealtime(); 15043 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15044 final long curUptime = SystemClock.uptimeMillis(); 15045 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15046 mLastPowerCheckRealtime = curRealtime; 15047 mLastPowerCheckUptime = curUptime; 15048 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15049 doWakeKills = false; 15050 } 15051 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15052 doCpuKills = false; 15053 } 15054 int i = mLruProcesses.size(); 15055 while (i > 0) { 15056 i--; 15057 ProcessRecord app = mLruProcesses.get(i); 15058 if (!app.keeping) { 15059 long wtime; 15060 synchronized (stats) { 15061 wtime = stats.getProcessWakeTime(app.info.uid, 15062 app.pid, curRealtime); 15063 } 15064 long wtimeUsed = wtime - app.lastWakeTime; 15065 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15066 if (DEBUG_POWER) { 15067 StringBuilder sb = new StringBuilder(128); 15068 sb.append("Wake for "); 15069 app.toShortString(sb); 15070 sb.append(": over "); 15071 TimeUtils.formatDuration(realtimeSince, sb); 15072 sb.append(" used "); 15073 TimeUtils.formatDuration(wtimeUsed, sb); 15074 sb.append(" ("); 15075 sb.append((wtimeUsed*100)/realtimeSince); 15076 sb.append("%)"); 15077 Slog.i(TAG, sb.toString()); 15078 sb.setLength(0); 15079 sb.append("CPU for "); 15080 app.toShortString(sb); 15081 sb.append(": over "); 15082 TimeUtils.formatDuration(uptimeSince, sb); 15083 sb.append(" used "); 15084 TimeUtils.formatDuration(cputimeUsed, sb); 15085 sb.append(" ("); 15086 sb.append((cputimeUsed*100)/uptimeSince); 15087 sb.append("%)"); 15088 Slog.i(TAG, sb.toString()); 15089 } 15090 // If a process has held a wake lock for more 15091 // than 50% of the time during this period, 15092 // that sounds bad. Kill! 15093 if (doWakeKills && realtimeSince > 0 15094 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15095 synchronized (stats) { 15096 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15097 realtimeSince, wtimeUsed); 15098 } 15099 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15100 + " during " + realtimeSince); 15101 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15102 } else if (doCpuKills && uptimeSince > 0 15103 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15104 synchronized (stats) { 15105 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15106 uptimeSince, cputimeUsed); 15107 } 15108 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15109 + " during " + uptimeSince); 15110 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15111 } else { 15112 app.lastWakeTime = wtime; 15113 app.lastCpuTime = app.curCpuTime; 15114 } 15115 } 15116 } 15117 } 15118 15119 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15120 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15121 boolean success = true; 15122 15123 if (app.curRawAdj != app.setRawAdj) { 15124 if (wasKeeping && !app.keeping) { 15125 // This app is no longer something we want to keep. Note 15126 // its current wake lock time to later know to kill it if 15127 // it is not behaving well. 15128 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15129 synchronized (stats) { 15130 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15131 app.pid, SystemClock.elapsedRealtime()); 15132 } 15133 app.lastCpuTime = app.curCpuTime; 15134 } 15135 15136 app.setRawAdj = app.curRawAdj; 15137 } 15138 15139 if (app.curAdj != app.setAdj) { 15140 ProcessList.setOomAdj(app.pid, app.curAdj); 15141 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15142 TAG, "Set " + app.pid + " " + app.processName + 15143 " adj " + app.curAdj + ": " + app.adjType); 15144 app.setAdj = app.curAdj; 15145 } 15146 15147 if (app.setSchedGroup != app.curSchedGroup) { 15148 app.setSchedGroup = app.curSchedGroup; 15149 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15150 "Setting process group of " + app.processName 15151 + " to " + app.curSchedGroup); 15152 if (app.waitingToKill != null && 15153 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15154 killUnneededProcessLocked(app, app.waitingToKill); 15155 success = false; 15156 } else { 15157 if (true) { 15158 long oldId = Binder.clearCallingIdentity(); 15159 try { 15160 Process.setProcessGroup(app.pid, app.curSchedGroup); 15161 } catch (Exception e) { 15162 Slog.w(TAG, "Failed setting process group of " + app.pid 15163 + " to " + app.curSchedGroup); 15164 e.printStackTrace(); 15165 } finally { 15166 Binder.restoreCallingIdentity(oldId); 15167 } 15168 } else { 15169 if (app.thread != null) { 15170 try { 15171 app.thread.setSchedulingGroup(app.curSchedGroup); 15172 } catch (RemoteException e) { 15173 } 15174 } 15175 } 15176 Process.setSwappiness(app.pid, 15177 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15178 } 15179 } 15180 if (app.repProcState != app.curProcState) { 15181 app.repProcState = app.curProcState; 15182 if (!reportingProcessState && app.thread != null) { 15183 try { 15184 if (false) { 15185 //RuntimeException h = new RuntimeException("here"); 15186 Slog.i(TAG, "Sending new process state " + app.repProcState 15187 + " to " + app /*, h*/); 15188 } 15189 app.thread.setProcessState(app.repProcState); 15190 } catch (RemoteException e) { 15191 } 15192 } 15193 } 15194 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15195 app.setProcState)) { 15196 app.lastStateTime = now; 15197 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15198 mSleeping, now); 15199 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15200 + ProcessList.makeProcStateString(app.setProcState) + " to " 15201 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15202 + (app.nextPssTime-now) + ": " + app); 15203 } else { 15204 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15205 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15206 requestPssLocked(app, app.setProcState); 15207 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15208 mSleeping, now); 15209 } else if (false && DEBUG_PSS) { 15210 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15211 } 15212 } 15213 if (app.setProcState != app.curProcState) { 15214 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15215 "Proc state change of " + app.processName 15216 + " to " + app.curProcState); 15217 app.setProcState = app.curProcState; 15218 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15219 app.notCachedSinceIdle = false; 15220 } 15221 if (!doingAll) { 15222 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15223 } else { 15224 app.procStateChanged = true; 15225 } 15226 } 15227 return success; 15228 } 15229 15230 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15231 if (proc.thread != null && proc.baseProcessTracker != null) { 15232 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15233 } 15234 } 15235 15236 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15237 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15238 if (app.thread == null) { 15239 return false; 15240 } 15241 15242 final boolean wasKeeping = app.keeping; 15243 15244 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15245 15246 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15247 reportingProcessState, now); 15248 } 15249 15250 private final ActivityRecord resumedAppLocked() { 15251 return mStackSupervisor.resumedAppLocked(); 15252 } 15253 15254 final boolean updateOomAdjLocked(ProcessRecord app) { 15255 return updateOomAdjLocked(app, false); 15256 } 15257 15258 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15259 final ActivityRecord TOP_ACT = resumedAppLocked(); 15260 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15261 final boolean wasCached = app.cached; 15262 15263 mAdjSeq++; 15264 15265 // This is the desired cached adjusment we want to tell it to use. 15266 // If our app is currently cached, we know it, and that is it. Otherwise, 15267 // we don't know it yet, and it needs to now be cached we will then 15268 // need to do a complete oom adj. 15269 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15270 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15271 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15272 SystemClock.uptimeMillis()); 15273 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15274 // Changed to/from cached state, so apps after it in the LRU 15275 // list may also be changed. 15276 updateOomAdjLocked(); 15277 } 15278 return success; 15279 } 15280 15281 final void updateOomAdjLocked() { 15282 final ActivityRecord TOP_ACT = resumedAppLocked(); 15283 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15284 final long now = SystemClock.uptimeMillis(); 15285 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15286 final int N = mLruProcesses.size(); 15287 15288 if (false) { 15289 RuntimeException e = new RuntimeException(); 15290 e.fillInStackTrace(); 15291 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15292 } 15293 15294 mAdjSeq++; 15295 mNewNumServiceProcs = 0; 15296 mNewNumAServiceProcs = 0; 15297 15298 final int emptyProcessLimit; 15299 final int cachedProcessLimit; 15300 if (mProcessLimit <= 0) { 15301 emptyProcessLimit = cachedProcessLimit = 0; 15302 } else if (mProcessLimit == 1) { 15303 emptyProcessLimit = 1; 15304 cachedProcessLimit = 0; 15305 } else { 15306 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15307 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15308 } 15309 15310 // Let's determine how many processes we have running vs. 15311 // how many slots we have for background processes; we may want 15312 // to put multiple processes in a slot of there are enough of 15313 // them. 15314 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15315 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15316 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15317 if (numEmptyProcs > cachedProcessLimit) { 15318 // If there are more empty processes than our limit on cached 15319 // processes, then use the cached process limit for the factor. 15320 // This ensures that the really old empty processes get pushed 15321 // down to the bottom, so if we are running low on memory we will 15322 // have a better chance at keeping around more cached processes 15323 // instead of a gazillion empty processes. 15324 numEmptyProcs = cachedProcessLimit; 15325 } 15326 int emptyFactor = numEmptyProcs/numSlots; 15327 if (emptyFactor < 1) emptyFactor = 1; 15328 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15329 if (cachedFactor < 1) cachedFactor = 1; 15330 int stepCached = 0; 15331 int stepEmpty = 0; 15332 int numCached = 0; 15333 int numEmpty = 0; 15334 int numTrimming = 0; 15335 15336 mNumNonCachedProcs = 0; 15337 mNumCachedHiddenProcs = 0; 15338 15339 // First update the OOM adjustment for each of the 15340 // application processes based on their current state. 15341 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15342 int nextCachedAdj = curCachedAdj+1; 15343 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15344 int nextEmptyAdj = curEmptyAdj+2; 15345 for (int i=N-1; i>=0; i--) { 15346 ProcessRecord app = mLruProcesses.get(i); 15347 if (!app.killedByAm && app.thread != null) { 15348 app.procStateChanged = false; 15349 final boolean wasKeeping = app.keeping; 15350 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15351 15352 // If we haven't yet assigned the final cached adj 15353 // to the process, do that now. 15354 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15355 switch (app.curProcState) { 15356 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15357 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15358 // This process is a cached process holding activities... 15359 // assign it the next cached value for that type, and then 15360 // step that cached level. 15361 app.curRawAdj = curCachedAdj; 15362 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15363 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15364 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15365 + ")"); 15366 if (curCachedAdj != nextCachedAdj) { 15367 stepCached++; 15368 if (stepCached >= cachedFactor) { 15369 stepCached = 0; 15370 curCachedAdj = nextCachedAdj; 15371 nextCachedAdj += 2; 15372 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15373 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15374 } 15375 } 15376 } 15377 break; 15378 default: 15379 // For everything else, assign next empty cached process 15380 // level and bump that up. Note that this means that 15381 // long-running services that have dropped down to the 15382 // cached level will be treated as empty (since their process 15383 // state is still as a service), which is what we want. 15384 app.curRawAdj = curEmptyAdj; 15385 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15386 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15387 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15388 + ")"); 15389 if (curEmptyAdj != nextEmptyAdj) { 15390 stepEmpty++; 15391 if (stepEmpty >= emptyFactor) { 15392 stepEmpty = 0; 15393 curEmptyAdj = nextEmptyAdj; 15394 nextEmptyAdj += 2; 15395 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15396 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15397 } 15398 } 15399 } 15400 break; 15401 } 15402 } 15403 15404 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15405 15406 // Count the number of process types. 15407 switch (app.curProcState) { 15408 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15409 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15410 mNumCachedHiddenProcs++; 15411 numCached++; 15412 if (numCached > cachedProcessLimit) { 15413 killUnneededProcessLocked(app, "cached #" + numCached); 15414 } 15415 break; 15416 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15417 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15418 && app.lastActivityTime < oldTime) { 15419 killUnneededProcessLocked(app, "empty for " 15420 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15421 / 1000) + "s"); 15422 } else { 15423 numEmpty++; 15424 if (numEmpty > emptyProcessLimit) { 15425 killUnneededProcessLocked(app, "empty #" + numEmpty); 15426 } 15427 } 15428 break; 15429 default: 15430 mNumNonCachedProcs++; 15431 break; 15432 } 15433 15434 if (app.isolated && app.services.size() <= 0) { 15435 // If this is an isolated process, and there are no 15436 // services running in it, then the process is no longer 15437 // needed. We agressively kill these because we can by 15438 // definition not re-use the same process again, and it is 15439 // good to avoid having whatever code was running in them 15440 // left sitting around after no longer needed. 15441 killUnneededProcessLocked(app, "isolated not needed"); 15442 } 15443 15444 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15445 && !app.killedByAm) { 15446 numTrimming++; 15447 } 15448 } 15449 } 15450 15451 mNumServiceProcs = mNewNumServiceProcs; 15452 15453 // Now determine the memory trimming level of background processes. 15454 // Unfortunately we need to start at the back of the list to do this 15455 // properly. We only do this if the number of background apps we 15456 // are managing to keep around is less than half the maximum we desire; 15457 // if we are keeping a good number around, we'll let them use whatever 15458 // memory they want. 15459 final int numCachedAndEmpty = numCached + numEmpty; 15460 int memFactor; 15461 if (numCached <= ProcessList.TRIM_CACHED_APPS 15462 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15463 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15464 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15465 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15466 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15467 } else { 15468 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15469 } 15470 } else { 15471 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15472 } 15473 // We always allow the memory level to go up (better). We only allow it to go 15474 // down if we are in a state where that is allowed, *and* the total number of processes 15475 // has gone down since last time. 15476 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15477 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15478 + " last=" + mLastNumProcesses); 15479 if (memFactor > mLastMemoryLevel) { 15480 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15481 memFactor = mLastMemoryLevel; 15482 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15483 } 15484 } 15485 mLastMemoryLevel = memFactor; 15486 mLastNumProcesses = mLruProcesses.size(); 15487 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15488 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15489 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15490 if (mLowRamStartTime == 0) { 15491 mLowRamStartTime = now; 15492 } 15493 int step = 0; 15494 int fgTrimLevel; 15495 switch (memFactor) { 15496 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15497 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15498 break; 15499 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15500 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15501 break; 15502 default: 15503 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15504 break; 15505 } 15506 int factor = numTrimming/3; 15507 int minFactor = 2; 15508 if (mHomeProcess != null) minFactor++; 15509 if (mPreviousProcess != null) minFactor++; 15510 if (factor < minFactor) factor = minFactor; 15511 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15512 for (int i=N-1; i>=0; i--) { 15513 ProcessRecord app = mLruProcesses.get(i); 15514 if (allChanged || app.procStateChanged) { 15515 setProcessTrackerState(app, trackerMemFactor, now); 15516 app.procStateChanged = false; 15517 } 15518 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15519 && !app.killedByAm) { 15520 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15521 try { 15522 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15523 "Trimming memory of " + app.processName 15524 + " to " + curLevel); 15525 app.thread.scheduleTrimMemory(curLevel); 15526 } catch (RemoteException e) { 15527 } 15528 if (false) { 15529 // For now we won't do this; our memory trimming seems 15530 // to be good enough at this point that destroying 15531 // activities causes more harm than good. 15532 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15533 && app != mHomeProcess && app != mPreviousProcess) { 15534 // Need to do this on its own message because the stack may not 15535 // be in a consistent state at this point. 15536 // For these apps we will also finish their activities 15537 // to help them free memory. 15538 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15539 } 15540 } 15541 } 15542 app.trimMemoryLevel = curLevel; 15543 step++; 15544 if (step >= factor) { 15545 step = 0; 15546 switch (curLevel) { 15547 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15548 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15549 break; 15550 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15551 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15552 break; 15553 } 15554 } 15555 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15556 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15557 && app.thread != null) { 15558 try { 15559 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15560 "Trimming memory of heavy-weight " + app.processName 15561 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15562 app.thread.scheduleTrimMemory( 15563 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15564 } catch (RemoteException e) { 15565 } 15566 } 15567 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15568 } else { 15569 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15570 || app.systemNoUi) && app.pendingUiClean) { 15571 // If this application is now in the background and it 15572 // had done UI, then give it the special trim level to 15573 // have it free UI resources. 15574 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15575 if (app.trimMemoryLevel < level && app.thread != null) { 15576 try { 15577 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15578 "Trimming memory of bg-ui " + app.processName 15579 + " to " + level); 15580 app.thread.scheduleTrimMemory(level); 15581 } catch (RemoteException e) { 15582 } 15583 } 15584 app.pendingUiClean = false; 15585 } 15586 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15587 try { 15588 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15589 "Trimming memory of fg " + app.processName 15590 + " to " + fgTrimLevel); 15591 app.thread.scheduleTrimMemory(fgTrimLevel); 15592 } catch (RemoteException e) { 15593 } 15594 } 15595 app.trimMemoryLevel = fgTrimLevel; 15596 } 15597 } 15598 } else { 15599 if (mLowRamStartTime != 0) { 15600 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15601 mLowRamStartTime = 0; 15602 } 15603 for (int i=N-1; i>=0; i--) { 15604 ProcessRecord app = mLruProcesses.get(i); 15605 if (allChanged || app.procStateChanged) { 15606 setProcessTrackerState(app, trackerMemFactor, now); 15607 app.procStateChanged = false; 15608 } 15609 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15610 || app.systemNoUi) && app.pendingUiClean) { 15611 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15612 && app.thread != null) { 15613 try { 15614 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15615 "Trimming memory of ui hidden " + app.processName 15616 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15617 app.thread.scheduleTrimMemory( 15618 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15619 } catch (RemoteException e) { 15620 } 15621 } 15622 app.pendingUiClean = false; 15623 } 15624 app.trimMemoryLevel = 0; 15625 } 15626 } 15627 15628 if (mAlwaysFinishActivities) { 15629 // Need to do this on its own message because the stack may not 15630 // be in a consistent state at this point. 15631 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15632 } 15633 15634 if (allChanged) { 15635 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15636 } 15637 15638 if (mProcessStats.shouldWriteNowLocked(now)) { 15639 mHandler.post(new Runnable() { 15640 @Override public void run() { 15641 synchronized (ActivityManagerService.this) { 15642 mProcessStats.writeStateAsyncLocked(); 15643 } 15644 } 15645 }); 15646 } 15647 15648 if (DEBUG_OOM_ADJ) { 15649 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15650 } 15651 } 15652 15653 final void trimApplications() { 15654 synchronized (this) { 15655 int i; 15656 15657 // First remove any unused application processes whose package 15658 // has been removed. 15659 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15660 final ProcessRecord app = mRemovedProcesses.get(i); 15661 if (app.activities.size() == 0 15662 && app.curReceiver == null && app.services.size() == 0) { 15663 Slog.i( 15664 TAG, "Exiting empty application process " 15665 + app.processName + " (" 15666 + (app.thread != null ? app.thread.asBinder() : null) 15667 + ")\n"); 15668 if (app.pid > 0 && app.pid != MY_PID) { 15669 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 15670 app.processName, app.setAdj, "empty"); 15671 app.killedByAm = true; 15672 Process.killProcessQuiet(app.pid); 15673 } else { 15674 try { 15675 app.thread.scheduleExit(); 15676 } catch (Exception e) { 15677 // Ignore exceptions. 15678 } 15679 } 15680 cleanUpApplicationRecordLocked(app, false, true, -1); 15681 mRemovedProcesses.remove(i); 15682 15683 if (app.persistent) { 15684 if (app.persistent) { 15685 addAppLocked(app.info, false); 15686 } 15687 } 15688 } 15689 } 15690 15691 // Now update the oom adj for all processes. 15692 updateOomAdjLocked(); 15693 } 15694 } 15695 15696 /** This method sends the specified signal to each of the persistent apps */ 15697 public void signalPersistentProcesses(int sig) throws RemoteException { 15698 if (sig != Process.SIGNAL_USR1) { 15699 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 15700 } 15701 15702 synchronized (this) { 15703 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 15704 != PackageManager.PERMISSION_GRANTED) { 15705 throw new SecurityException("Requires permission " 15706 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 15707 } 15708 15709 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15710 ProcessRecord r = mLruProcesses.get(i); 15711 if (r.thread != null && r.persistent) { 15712 Process.sendSignal(r.pid, sig); 15713 } 15714 } 15715 } 15716 } 15717 15718 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 15719 if (proc == null || proc == mProfileProc) { 15720 proc = mProfileProc; 15721 path = mProfileFile; 15722 profileType = mProfileType; 15723 clearProfilerLocked(); 15724 } 15725 if (proc == null) { 15726 return; 15727 } 15728 try { 15729 proc.thread.profilerControl(false, path, null, profileType); 15730 } catch (RemoteException e) { 15731 throw new IllegalStateException("Process disappeared"); 15732 } 15733 } 15734 15735 private void clearProfilerLocked() { 15736 if (mProfileFd != null) { 15737 try { 15738 mProfileFd.close(); 15739 } catch (IOException e) { 15740 } 15741 } 15742 mProfileApp = null; 15743 mProfileProc = null; 15744 mProfileFile = null; 15745 mProfileType = 0; 15746 mAutoStopProfiler = false; 15747 } 15748 15749 public boolean profileControl(String process, int userId, boolean start, 15750 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 15751 15752 try { 15753 synchronized (this) { 15754 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15755 // its own permission. 15756 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15757 != PackageManager.PERMISSION_GRANTED) { 15758 throw new SecurityException("Requires permission " 15759 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15760 } 15761 15762 if (start && fd == null) { 15763 throw new IllegalArgumentException("null fd"); 15764 } 15765 15766 ProcessRecord proc = null; 15767 if (process != null) { 15768 proc = findProcessLocked(process, userId, "profileControl"); 15769 } 15770 15771 if (start && (proc == null || proc.thread == null)) { 15772 throw new IllegalArgumentException("Unknown process: " + process); 15773 } 15774 15775 if (start) { 15776 stopProfilerLocked(null, null, 0); 15777 setProfileApp(proc.info, proc.processName, path, fd, false); 15778 mProfileProc = proc; 15779 mProfileType = profileType; 15780 try { 15781 fd = fd.dup(); 15782 } catch (IOException e) { 15783 fd = null; 15784 } 15785 proc.thread.profilerControl(start, path, fd, profileType); 15786 fd = null; 15787 mProfileFd = null; 15788 } else { 15789 stopProfilerLocked(proc, path, profileType); 15790 if (fd != null) { 15791 try { 15792 fd.close(); 15793 } catch (IOException e) { 15794 } 15795 } 15796 } 15797 15798 return true; 15799 } 15800 } catch (RemoteException e) { 15801 throw new IllegalStateException("Process disappeared"); 15802 } finally { 15803 if (fd != null) { 15804 try { 15805 fd.close(); 15806 } catch (IOException e) { 15807 } 15808 } 15809 } 15810 } 15811 15812 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 15813 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15814 userId, true, true, callName, null); 15815 ProcessRecord proc = null; 15816 try { 15817 int pid = Integer.parseInt(process); 15818 synchronized (mPidsSelfLocked) { 15819 proc = mPidsSelfLocked.get(pid); 15820 } 15821 } catch (NumberFormatException e) { 15822 } 15823 15824 if (proc == null) { 15825 ArrayMap<String, SparseArray<ProcessRecord>> all 15826 = mProcessNames.getMap(); 15827 SparseArray<ProcessRecord> procs = all.get(process); 15828 if (procs != null && procs.size() > 0) { 15829 proc = procs.valueAt(0); 15830 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 15831 for (int i=1; i<procs.size(); i++) { 15832 ProcessRecord thisProc = procs.valueAt(i); 15833 if (thisProc.userId == userId) { 15834 proc = thisProc; 15835 break; 15836 } 15837 } 15838 } 15839 } 15840 } 15841 15842 return proc; 15843 } 15844 15845 public boolean dumpHeap(String process, int userId, boolean managed, 15846 String path, ParcelFileDescriptor fd) throws RemoteException { 15847 15848 try { 15849 synchronized (this) { 15850 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15851 // its own permission (same as profileControl). 15852 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15853 != PackageManager.PERMISSION_GRANTED) { 15854 throw new SecurityException("Requires permission " 15855 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15856 } 15857 15858 if (fd == null) { 15859 throw new IllegalArgumentException("null fd"); 15860 } 15861 15862 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 15863 if (proc == null || proc.thread == null) { 15864 throw new IllegalArgumentException("Unknown process: " + process); 15865 } 15866 15867 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 15868 if (!isDebuggable) { 15869 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 15870 throw new SecurityException("Process not debuggable: " + proc); 15871 } 15872 } 15873 15874 proc.thread.dumpHeap(managed, path, fd); 15875 fd = null; 15876 return true; 15877 } 15878 } catch (RemoteException e) { 15879 throw new IllegalStateException("Process disappeared"); 15880 } finally { 15881 if (fd != null) { 15882 try { 15883 fd.close(); 15884 } catch (IOException e) { 15885 } 15886 } 15887 } 15888 } 15889 15890 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 15891 public void monitor() { 15892 synchronized (this) { } 15893 } 15894 15895 void onCoreSettingsChange(Bundle settings) { 15896 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 15897 ProcessRecord processRecord = mLruProcesses.get(i); 15898 try { 15899 if (processRecord.thread != null) { 15900 processRecord.thread.setCoreSettings(settings); 15901 } 15902 } catch (RemoteException re) { 15903 /* ignore */ 15904 } 15905 } 15906 } 15907 15908 // Multi-user methods 15909 15910 @Override 15911 public boolean switchUser(final int userId) { 15912 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 15913 != PackageManager.PERMISSION_GRANTED) { 15914 String msg = "Permission Denial: switchUser() from pid=" 15915 + Binder.getCallingPid() 15916 + ", uid=" + Binder.getCallingUid() 15917 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 15918 Slog.w(TAG, msg); 15919 throw new SecurityException(msg); 15920 } 15921 15922 final long ident = Binder.clearCallingIdentity(); 15923 try { 15924 synchronized (this) { 15925 final int oldUserId = mCurrentUserId; 15926 if (oldUserId == userId) { 15927 return true; 15928 } 15929 15930 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 15931 if (userInfo == null) { 15932 Slog.w(TAG, "No user info for user #" + userId); 15933 return false; 15934 } 15935 15936 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 15937 R.anim.screen_user_enter); 15938 15939 boolean needStart = false; 15940 15941 // If the user we are switching to is not currently started, then 15942 // we need to start it now. 15943 if (mStartedUsers.get(userId) == null) { 15944 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 15945 updateStartedUserArrayLocked(); 15946 needStart = true; 15947 } 15948 15949 mCurrentUserId = userId; 15950 final Integer userIdInt = Integer.valueOf(userId); 15951 mUserLru.remove(userIdInt); 15952 mUserLru.add(userIdInt); 15953 15954 mWindowManager.setCurrentUser(userId); 15955 15956 // Once the internal notion of the active user has switched, we lock the device 15957 // with the option to show the user switcher on the keyguard. 15958 mWindowManager.lockNow(null); 15959 15960 final UserStartedState uss = mStartedUsers.get(userId); 15961 15962 // Make sure user is in the started state. If it is currently 15963 // stopping, we need to knock that off. 15964 if (uss.mState == UserStartedState.STATE_STOPPING) { 15965 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 15966 // so we can just fairly silently bring the user back from 15967 // the almost-dead. 15968 uss.mState = UserStartedState.STATE_RUNNING; 15969 updateStartedUserArrayLocked(); 15970 needStart = true; 15971 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 15972 // This means ACTION_SHUTDOWN has been sent, so we will 15973 // need to treat this as a new boot of the user. 15974 uss.mState = UserStartedState.STATE_BOOTING; 15975 updateStartedUserArrayLocked(); 15976 needStart = true; 15977 } 15978 15979 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 15980 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 15981 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 15982 oldUserId, userId, uss)); 15983 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 15984 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 15985 if (needStart) { 15986 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 15987 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15988 | Intent.FLAG_RECEIVER_FOREGROUND); 15989 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 15990 broadcastIntentLocked(null, null, intent, 15991 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15992 false, false, MY_PID, Process.SYSTEM_UID, userId); 15993 } 15994 15995 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 15996 if (userId != 0) { 15997 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 15998 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 15999 broadcastIntentLocked(null, null, intent, null, 16000 new IIntentReceiver.Stub() { 16001 public void performReceive(Intent intent, int resultCode, 16002 String data, Bundle extras, boolean ordered, 16003 boolean sticky, int sendingUser) { 16004 userInitialized(uss, userId); 16005 } 16006 }, 0, null, null, null, AppOpsManager.OP_NONE, 16007 true, false, MY_PID, Process.SYSTEM_UID, 16008 userId); 16009 uss.initializing = true; 16010 } else { 16011 getUserManagerLocked().makeInitialized(userInfo.id); 16012 } 16013 } 16014 16015 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16016 if (homeInFront) { 16017 startHomeActivityLocked(userId); 16018 } else { 16019 mStackSupervisor.resumeTopActivitiesLocked(); 16020 } 16021 16022 EventLogTags.writeAmSwitchUser(userId); 16023 getUserManagerLocked().userForeground(userId); 16024 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16025 if (needStart) { 16026 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16027 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16028 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16029 broadcastIntentLocked(null, null, intent, 16030 null, new IIntentReceiver.Stub() { 16031 @Override 16032 public void performReceive(Intent intent, int resultCode, String data, 16033 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16034 throws RemoteException { 16035 } 16036 }, 0, null, null, 16037 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16038 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16039 } 16040 } 16041 } finally { 16042 Binder.restoreCallingIdentity(ident); 16043 } 16044 16045 return true; 16046 } 16047 16048 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16049 long ident = Binder.clearCallingIdentity(); 16050 try { 16051 Intent intent; 16052 if (oldUserId >= 0) { 16053 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16054 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16055 | Intent.FLAG_RECEIVER_FOREGROUND); 16056 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16057 broadcastIntentLocked(null, null, intent, 16058 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16059 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16060 } 16061 if (newUserId >= 0) { 16062 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16063 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16064 | Intent.FLAG_RECEIVER_FOREGROUND); 16065 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16066 broadcastIntentLocked(null, null, intent, 16067 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16068 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16069 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16070 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16071 | Intent.FLAG_RECEIVER_FOREGROUND); 16072 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16073 broadcastIntentLocked(null, null, intent, 16074 null, null, 0, null, null, 16075 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16076 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16077 } 16078 } finally { 16079 Binder.restoreCallingIdentity(ident); 16080 } 16081 } 16082 16083 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16084 final int newUserId) { 16085 final int N = mUserSwitchObservers.beginBroadcast(); 16086 if (N > 0) { 16087 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16088 int mCount = 0; 16089 @Override 16090 public void sendResult(Bundle data) throws RemoteException { 16091 synchronized (ActivityManagerService.this) { 16092 if (mCurUserSwitchCallback == this) { 16093 mCount++; 16094 if (mCount == N) { 16095 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16096 } 16097 } 16098 } 16099 } 16100 }; 16101 synchronized (this) { 16102 uss.switching = true; 16103 mCurUserSwitchCallback = callback; 16104 } 16105 for (int i=0; i<N; i++) { 16106 try { 16107 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16108 newUserId, callback); 16109 } catch (RemoteException e) { 16110 } 16111 } 16112 } else { 16113 synchronized (this) { 16114 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16115 } 16116 } 16117 mUserSwitchObservers.finishBroadcast(); 16118 } 16119 16120 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16121 synchronized (this) { 16122 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16123 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16124 } 16125 } 16126 16127 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16128 mCurUserSwitchCallback = null; 16129 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16130 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16131 oldUserId, newUserId, uss)); 16132 } 16133 16134 void userInitialized(UserStartedState uss, int newUserId) { 16135 completeSwitchAndInitalize(uss, newUserId, true, false); 16136 } 16137 16138 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16139 completeSwitchAndInitalize(uss, newUserId, false, true); 16140 } 16141 16142 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16143 boolean clearInitializing, boolean clearSwitching) { 16144 boolean unfrozen = false; 16145 synchronized (this) { 16146 if (clearInitializing) { 16147 uss.initializing = false; 16148 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16149 } 16150 if (clearSwitching) { 16151 uss.switching = false; 16152 } 16153 if (!uss.switching && !uss.initializing) { 16154 mWindowManager.stopFreezingScreen(); 16155 unfrozen = true; 16156 } 16157 } 16158 if (unfrozen) { 16159 final int N = mUserSwitchObservers.beginBroadcast(); 16160 for (int i=0; i<N; i++) { 16161 try { 16162 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16163 } catch (RemoteException e) { 16164 } 16165 } 16166 mUserSwitchObservers.finishBroadcast(); 16167 } 16168 } 16169 16170 void finishUserSwitch(UserStartedState uss) { 16171 synchronized (this) { 16172 if (uss.mState == UserStartedState.STATE_BOOTING 16173 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16174 uss.mState = UserStartedState.STATE_RUNNING; 16175 final int userId = uss.mHandle.getIdentifier(); 16176 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16177 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16178 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16179 broadcastIntentLocked(null, null, intent, 16180 null, null, 0, null, null, 16181 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16182 true, false, MY_PID, Process.SYSTEM_UID, userId); 16183 } 16184 int num = mUserLru.size(); 16185 int i = 0; 16186 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16187 Integer oldUserId = mUserLru.get(i); 16188 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16189 if (oldUss == null) { 16190 // Shouldn't happen, but be sane if it does. 16191 mUserLru.remove(i); 16192 num--; 16193 continue; 16194 } 16195 if (oldUss.mState == UserStartedState.STATE_STOPPING 16196 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16197 // This user is already stopping, doesn't count. 16198 num--; 16199 i++; 16200 continue; 16201 } 16202 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16203 // Owner and current can't be stopped, but count as running. 16204 i++; 16205 continue; 16206 } 16207 // This is a user to be stopped. 16208 stopUserLocked(oldUserId, null); 16209 num--; 16210 i++; 16211 } 16212 } 16213 } 16214 16215 @Override 16216 public int stopUser(final int userId, final IStopUserCallback callback) { 16217 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16218 != PackageManager.PERMISSION_GRANTED) { 16219 String msg = "Permission Denial: switchUser() from pid=" 16220 + Binder.getCallingPid() 16221 + ", uid=" + Binder.getCallingUid() 16222 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16223 Slog.w(TAG, msg); 16224 throw new SecurityException(msg); 16225 } 16226 if (userId <= 0) { 16227 throw new IllegalArgumentException("Can't stop primary user " + userId); 16228 } 16229 synchronized (this) { 16230 return stopUserLocked(userId, callback); 16231 } 16232 } 16233 16234 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16235 if (mCurrentUserId == userId) { 16236 return ActivityManager.USER_OP_IS_CURRENT; 16237 } 16238 16239 final UserStartedState uss = mStartedUsers.get(userId); 16240 if (uss == null) { 16241 // User is not started, nothing to do... but we do need to 16242 // callback if requested. 16243 if (callback != null) { 16244 mHandler.post(new Runnable() { 16245 @Override 16246 public void run() { 16247 try { 16248 callback.userStopped(userId); 16249 } catch (RemoteException e) { 16250 } 16251 } 16252 }); 16253 } 16254 return ActivityManager.USER_OP_SUCCESS; 16255 } 16256 16257 if (callback != null) { 16258 uss.mStopCallbacks.add(callback); 16259 } 16260 16261 if (uss.mState != UserStartedState.STATE_STOPPING 16262 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16263 uss.mState = UserStartedState.STATE_STOPPING; 16264 updateStartedUserArrayLocked(); 16265 16266 long ident = Binder.clearCallingIdentity(); 16267 try { 16268 // We are going to broadcast ACTION_USER_STOPPING and then 16269 // once that is done send a final ACTION_SHUTDOWN and then 16270 // stop the user. 16271 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16272 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16273 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16274 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16275 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16276 // This is the result receiver for the final shutdown broadcast. 16277 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16278 @Override 16279 public void performReceive(Intent intent, int resultCode, String data, 16280 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16281 finishUserStop(uss); 16282 } 16283 }; 16284 // This is the result receiver for the initial stopping broadcast. 16285 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16286 @Override 16287 public void performReceive(Intent intent, int resultCode, String data, 16288 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16289 // On to the next. 16290 synchronized (ActivityManagerService.this) { 16291 if (uss.mState != UserStartedState.STATE_STOPPING) { 16292 // Whoops, we are being started back up. Abort, abort! 16293 return; 16294 } 16295 uss.mState = UserStartedState.STATE_SHUTDOWN; 16296 } 16297 broadcastIntentLocked(null, null, shutdownIntent, 16298 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16299 true, false, MY_PID, Process.SYSTEM_UID, userId); 16300 } 16301 }; 16302 // Kick things off. 16303 broadcastIntentLocked(null, null, stoppingIntent, 16304 null, stoppingReceiver, 0, null, null, 16305 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16306 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16307 } finally { 16308 Binder.restoreCallingIdentity(ident); 16309 } 16310 } 16311 16312 return ActivityManager.USER_OP_SUCCESS; 16313 } 16314 16315 void finishUserStop(UserStartedState uss) { 16316 final int userId = uss.mHandle.getIdentifier(); 16317 boolean stopped; 16318 ArrayList<IStopUserCallback> callbacks; 16319 synchronized (this) { 16320 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16321 if (mStartedUsers.get(userId) != uss) { 16322 stopped = false; 16323 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16324 stopped = false; 16325 } else { 16326 stopped = true; 16327 // User can no longer run. 16328 mStartedUsers.remove(userId); 16329 mUserLru.remove(Integer.valueOf(userId)); 16330 updateStartedUserArrayLocked(); 16331 16332 // Clean up all state and processes associated with the user. 16333 // Kill all the processes for the user. 16334 forceStopUserLocked(userId, "finish user"); 16335 } 16336 } 16337 16338 for (int i=0; i<callbacks.size(); i++) { 16339 try { 16340 if (stopped) callbacks.get(i).userStopped(userId); 16341 else callbacks.get(i).userStopAborted(userId); 16342 } catch (RemoteException e) { 16343 } 16344 } 16345 16346 mStackSupervisor.removeUserLocked(userId); 16347 } 16348 16349 @Override 16350 public UserInfo getCurrentUser() { 16351 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16352 != PackageManager.PERMISSION_GRANTED) && ( 16353 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16354 != PackageManager.PERMISSION_GRANTED)) { 16355 String msg = "Permission Denial: getCurrentUser() from pid=" 16356 + Binder.getCallingPid() 16357 + ", uid=" + Binder.getCallingUid() 16358 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16359 Slog.w(TAG, msg); 16360 throw new SecurityException(msg); 16361 } 16362 synchronized (this) { 16363 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16364 } 16365 } 16366 16367 int getCurrentUserIdLocked() { 16368 return mCurrentUserId; 16369 } 16370 16371 @Override 16372 public boolean isUserRunning(int userId, boolean orStopped) { 16373 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16374 != PackageManager.PERMISSION_GRANTED) { 16375 String msg = "Permission Denial: isUserRunning() from pid=" 16376 + Binder.getCallingPid() 16377 + ", uid=" + Binder.getCallingUid() 16378 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16379 Slog.w(TAG, msg); 16380 throw new SecurityException(msg); 16381 } 16382 synchronized (this) { 16383 return isUserRunningLocked(userId, orStopped); 16384 } 16385 } 16386 16387 boolean isUserRunningLocked(int userId, boolean orStopped) { 16388 UserStartedState state = mStartedUsers.get(userId); 16389 if (state == null) { 16390 return false; 16391 } 16392 if (orStopped) { 16393 return true; 16394 } 16395 return state.mState != UserStartedState.STATE_STOPPING 16396 && state.mState != UserStartedState.STATE_SHUTDOWN; 16397 } 16398 16399 @Override 16400 public int[] getRunningUserIds() { 16401 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16402 != PackageManager.PERMISSION_GRANTED) { 16403 String msg = "Permission Denial: isUserRunning() from pid=" 16404 + Binder.getCallingPid() 16405 + ", uid=" + Binder.getCallingUid() 16406 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16407 Slog.w(TAG, msg); 16408 throw new SecurityException(msg); 16409 } 16410 synchronized (this) { 16411 return mStartedUserArray; 16412 } 16413 } 16414 16415 private void updateStartedUserArrayLocked() { 16416 int num = 0; 16417 for (int i=0; i<mStartedUsers.size(); i++) { 16418 UserStartedState uss = mStartedUsers.valueAt(i); 16419 // This list does not include stopping users. 16420 if (uss.mState != UserStartedState.STATE_STOPPING 16421 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16422 num++; 16423 } 16424 } 16425 mStartedUserArray = new int[num]; 16426 num = 0; 16427 for (int i=0; i<mStartedUsers.size(); i++) { 16428 UserStartedState uss = mStartedUsers.valueAt(i); 16429 if (uss.mState != UserStartedState.STATE_STOPPING 16430 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16431 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16432 num++; 16433 } 16434 } 16435 } 16436 16437 @Override 16438 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16439 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16440 != PackageManager.PERMISSION_GRANTED) { 16441 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16442 + Binder.getCallingPid() 16443 + ", uid=" + Binder.getCallingUid() 16444 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16445 Slog.w(TAG, msg); 16446 throw new SecurityException(msg); 16447 } 16448 16449 mUserSwitchObservers.register(observer); 16450 } 16451 16452 @Override 16453 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16454 mUserSwitchObservers.unregister(observer); 16455 } 16456 16457 private boolean userExists(int userId) { 16458 if (userId == 0) { 16459 return true; 16460 } 16461 UserManagerService ums = getUserManagerLocked(); 16462 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16463 } 16464 16465 int[] getUsersLocked() { 16466 UserManagerService ums = getUserManagerLocked(); 16467 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16468 } 16469 16470 UserManagerService getUserManagerLocked() { 16471 if (mUserManager == null) { 16472 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16473 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16474 } 16475 return mUserManager; 16476 } 16477 16478 private int applyUserId(int uid, int userId) { 16479 return UserHandle.getUid(userId, uid); 16480 } 16481 16482 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16483 if (info == null) return null; 16484 ApplicationInfo newInfo = new ApplicationInfo(info); 16485 newInfo.uid = applyUserId(info.uid, userId); 16486 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16487 + info.packageName; 16488 return newInfo; 16489 } 16490 16491 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16492 if (aInfo == null 16493 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16494 return aInfo; 16495 } 16496 16497 ActivityInfo info = new ActivityInfo(aInfo); 16498 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16499 return info; 16500 } 16501 16502 private final class LocalService extends ActivityManagerInternal { 16503 @Override 16504 public void goingToSleep() { 16505 ActivityManagerService.this.goingToSleep(); 16506 } 16507 16508 @Override 16509 public void wakingUp() { 16510 ActivityManagerService.this.wakingUp(); 16511 } 16512 } 16513} 16514