ActivityManagerService.java revision 6fdb5e6df178b3b1062ac67b505b288aa609a66b
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20import static com.android.internal.util.XmlUtils.readIntAttribute; 21import static com.android.internal.util.XmlUtils.readLongAttribute; 22import static com.android.internal.util.XmlUtils.writeIntAttribute; 23import static com.android.internal.util.XmlUtils.writeLongAttribute; 24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 26import static org.xmlpull.v1.XmlPullParser.START_TAG; 27import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 28 29import android.app.AppOpsManager; 30import android.app.IActivityContainer; 31import android.app.IActivityContainerCallback; 32import android.appwidget.AppWidgetManager; 33import android.graphics.Rect; 34import android.util.ArrayMap; 35 36import com.android.internal.R; 37import com.android.internal.annotations.GuardedBy; 38import com.android.internal.app.IAppOpsService; 39import com.android.internal.app.ProcessMap; 40import com.android.internal.app.ProcessStats; 41import com.android.internal.os.BackgroundThread; 42import com.android.internal.os.BatteryStatsImpl; 43import com.android.internal.os.ProcessCpuTracker; 44import com.android.internal.os.TransferPipe; 45import com.android.internal.os.Zygote; 46import com.android.internal.util.FastPrintWriter; 47import com.android.internal.util.FastXmlSerializer; 48import com.android.internal.util.MemInfoReader; 49import com.android.internal.util.Preconditions; 50import com.android.server.AppOpsService; 51import com.android.server.AttributeCache; 52import com.android.server.IntentResolver; 53import com.android.server.LocalServices; 54import com.android.server.ServiceThread; 55import com.android.server.SystemService; 56import com.android.server.Watchdog; 57import com.android.server.am.ActivityStack.ActivityState; 58import com.android.server.firewall.IntentFirewall; 59import com.android.server.pm.UserManagerService; 60import com.android.server.wm.AppTransition; 61import com.android.server.wm.WindowManagerService; 62import com.google.android.collect.Lists; 63import com.google.android.collect.Maps; 64 65import libcore.io.IoUtils; 66 67import org.xmlpull.v1.XmlPullParser; 68import org.xmlpull.v1.XmlPullParserException; 69import org.xmlpull.v1.XmlSerializer; 70 71import android.app.Activity; 72import android.app.ActivityManager; 73import android.app.ActivityManager.RunningTaskInfo; 74import android.app.ActivityManager.StackInfo; 75import android.app.ActivityManagerInternal; 76import android.app.ActivityManagerNative; 77import android.app.ActivityOptions; 78import android.app.ActivityThread; 79import android.app.AlertDialog; 80import android.app.AppGlobals; 81import android.app.ApplicationErrorReport; 82import android.app.Dialog; 83import android.app.IActivityController; 84import android.app.IApplicationThread; 85import android.app.IInstrumentationWatcher; 86import android.app.INotificationManager; 87import android.app.IProcessObserver; 88import android.app.IServiceConnection; 89import android.app.IStopUserCallback; 90import android.app.IThumbnailReceiver; 91import android.app.IUiAutomationConnection; 92import android.app.IUserSwitchObserver; 93import android.app.Instrumentation; 94import android.app.Notification; 95import android.app.NotificationManager; 96import android.app.PendingIntent; 97import android.app.backup.IBackupManager; 98import android.content.ActivityNotFoundException; 99import android.content.BroadcastReceiver; 100import android.content.ClipData; 101import android.content.ComponentCallbacks2; 102import android.content.ComponentName; 103import android.content.ContentProvider; 104import android.content.ContentResolver; 105import android.content.Context; 106import android.content.DialogInterface; 107import android.content.IContentProvider; 108import android.content.IIntentReceiver; 109import android.content.IIntentSender; 110import android.content.Intent; 111import android.content.IntentFilter; 112import android.content.IntentSender; 113import android.content.pm.ActivityInfo; 114import android.content.pm.ApplicationInfo; 115import android.content.pm.ConfigurationInfo; 116import android.content.pm.IPackageDataObserver; 117import android.content.pm.IPackageManager; 118import android.content.pm.InstrumentationInfo; 119import android.content.pm.PackageInfo; 120import android.content.pm.PackageManager; 121import android.content.pm.ParceledListSlice; 122import android.content.pm.UserInfo; 123import android.content.pm.PackageManager.NameNotFoundException; 124import android.content.pm.PathPermission; 125import android.content.pm.ProviderInfo; 126import android.content.pm.ResolveInfo; 127import android.content.pm.ServiceInfo; 128import android.content.res.CompatibilityInfo; 129import android.content.res.Configuration; 130import android.graphics.Bitmap; 131import android.net.Proxy; 132import android.net.ProxyProperties; 133import android.net.Uri; 134import android.os.Binder; 135import android.os.Build; 136import android.os.Bundle; 137import android.os.Debug; 138import android.os.DropBoxManager; 139import android.os.Environment; 140import android.os.FactoryTest; 141import android.os.FileObserver; 142import android.os.FileUtils; 143import android.os.Handler; 144import android.os.IBinder; 145import android.os.IPermissionController; 146import android.os.IRemoteCallback; 147import android.os.IUserManager; 148import android.os.Looper; 149import android.os.Message; 150import android.os.Parcel; 151import android.os.ParcelFileDescriptor; 152import android.os.Process; 153import android.os.RemoteCallbackList; 154import android.os.RemoteException; 155import android.os.SELinux; 156import android.os.ServiceManager; 157import android.os.StrictMode; 158import android.os.SystemClock; 159import android.os.SystemProperties; 160import android.os.UpdateLock; 161import android.os.UserHandle; 162import android.provider.Settings; 163import android.text.format.DateUtils; 164import android.text.format.Time; 165import android.util.AtomicFile; 166import android.util.EventLog; 167import android.util.Log; 168import android.util.Pair; 169import android.util.PrintWriterPrinter; 170import android.util.Slog; 171import android.util.SparseArray; 172import android.util.TimeUtils; 173import android.util.Xml; 174import android.view.Gravity; 175import android.view.LayoutInflater; 176import android.view.View; 177import android.view.WindowManager; 178 179import java.io.BufferedInputStream; 180import java.io.BufferedOutputStream; 181import java.io.DataInputStream; 182import java.io.DataOutputStream; 183import java.io.File; 184import java.io.FileDescriptor; 185import java.io.FileInputStream; 186import java.io.FileNotFoundException; 187import java.io.FileOutputStream; 188import java.io.IOException; 189import java.io.InputStreamReader; 190import java.io.PrintWriter; 191import java.io.StringWriter; 192import java.lang.ref.WeakReference; 193import java.util.ArrayList; 194import java.util.Arrays; 195import java.util.Collections; 196import java.util.Comparator; 197import java.util.HashMap; 198import java.util.HashSet; 199import java.util.Iterator; 200import java.util.List; 201import java.util.Locale; 202import java.util.Map; 203import java.util.Set; 204import java.util.concurrent.atomic.AtomicBoolean; 205import java.util.concurrent.atomic.AtomicLong; 206 207public final class ActivityManagerService extends ActivityManagerNative 208 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 209 private static final String USER_DATA_DIR = "/data/user/"; 210 static final String TAG = "ActivityManager"; 211 static final String TAG_MU = "ActivityManagerServiceMU"; 212 static final boolean DEBUG = false; 213 static final boolean localLOGV = DEBUG; 214 static final boolean DEBUG_BACKUP = localLOGV || false; 215 static final boolean DEBUG_BROADCAST = localLOGV || false; 216 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 217 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 218 static final boolean DEBUG_CLEANUP = localLOGV || false; 219 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 220 static final boolean DEBUG_FOCUS = false; 221 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 222 static final boolean DEBUG_MU = localLOGV || false; 223 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 224 static final boolean DEBUG_LRU = localLOGV || false; 225 static final boolean DEBUG_PAUSE = localLOGV || false; 226 static final boolean DEBUG_POWER = localLOGV || false; 227 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 228 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 229 static final boolean DEBUG_PROCESSES = localLOGV || false; 230 static final boolean DEBUG_PROVIDER = localLOGV || false; 231 static final boolean DEBUG_RESULTS = localLOGV || false; 232 static final boolean DEBUG_SERVICE = localLOGV || false; 233 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 234 static final boolean DEBUG_STACK = localLOGV || false; 235 static final boolean DEBUG_SWITCH = localLOGV || false; 236 static final boolean DEBUG_TASKS = localLOGV || false; 237 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 238 static final boolean DEBUG_TRANSITION = localLOGV || false; 239 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 240 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 241 static final boolean DEBUG_VISBILITY = localLOGV || false; 242 static final boolean DEBUG_PSS = localLOGV || false; 243 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 244 static final boolean VALIDATE_TOKENS = false; 245 static final boolean SHOW_ACTIVITY_START_TIME = true; 246 247 // Control over CPU and battery monitoring. 248 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 249 static final boolean MONITOR_CPU_USAGE = true; 250 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 251 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 252 static final boolean MONITOR_THREAD_CPU_USAGE = false; 253 254 // The flags that are set for all calls we make to the package manager. 255 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 256 257 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 258 259 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 260 261 // Maximum number of recent tasks that we can remember. 262 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 263 264 // Amount of time after a call to stopAppSwitches() during which we will 265 // prevent further untrusted switches from happening. 266 static final long APP_SWITCH_DELAY_TIME = 5*1000; 267 268 // How long we wait for a launched process to attach to the activity manager 269 // before we decide it's never going to come up for real. 270 static final int PROC_START_TIMEOUT = 10*1000; 271 272 // How long we wait for a launched process to attach to the activity manager 273 // before we decide it's never going to come up for real, when the process was 274 // started with a wrapper for instrumentation (such as Valgrind) because it 275 // could take much longer than usual. 276 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 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 /** 934 * Set if the systemServer made a call to enterSafeMode. 935 */ 936 boolean mSafeMode; 937 938 String mDebugApp = null; 939 boolean mWaitForDebugger = false; 940 boolean mDebugTransient = false; 941 String mOrigDebugApp = null; 942 boolean mOrigWaitForDebugger = false; 943 boolean mAlwaysFinishActivities = false; 944 IActivityController mController = null; 945 String mProfileApp = null; 946 ProcessRecord mProfileProc = null; 947 String mProfileFile; 948 ParcelFileDescriptor mProfileFd; 949 int mProfileType = 0; 950 boolean mAutoStopProfiler = false; 951 String mOpenGlTraceApp = null; 952 953 static class ProcessChangeItem { 954 static final int CHANGE_ACTIVITIES = 1<<0; 955 static final int CHANGE_IMPORTANCE= 1<<1; 956 int changes; 957 int uid; 958 int pid; 959 int importance; 960 boolean foregroundActivities; 961 } 962 963 final RemoteCallbackList<IProcessObserver> mProcessObservers 964 = new RemoteCallbackList<IProcessObserver>(); 965 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 966 967 final ArrayList<ProcessChangeItem> mPendingProcessChanges 968 = new ArrayList<ProcessChangeItem>(); 969 final ArrayList<ProcessChangeItem> mAvailProcessChanges 970 = new ArrayList<ProcessChangeItem>(); 971 972 /** 973 * Runtime CPU use collection thread. This object's lock is used to 974 * protect all related state. 975 */ 976 final Thread mProcessCpuThread; 977 978 /** 979 * Used to collect process stats when showing not responding dialog. 980 * Protected by mProcessCpuThread. 981 */ 982 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 983 MONITOR_THREAD_CPU_USAGE); 984 final AtomicLong mLastCpuTime = new AtomicLong(0); 985 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 986 987 long mLastWriteTime = 0; 988 989 /** 990 * Used to retain an update lock when the foreground activity is in 991 * immersive mode. 992 */ 993 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 994 995 /** 996 * Set to true after the system has finished booting. 997 */ 998 boolean mBooted = false; 999 1000 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1001 int mProcessLimitOverride = -1; 1002 1003 WindowManagerService mWindowManager; 1004 1005 final ActivityThread mSystemThread; 1006 1007 int mCurrentUserId = 0; 1008 private UserManagerService mUserManager; 1009 1010 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1011 final ProcessRecord mApp; 1012 final int mPid; 1013 final IApplicationThread mAppThread; 1014 1015 AppDeathRecipient(ProcessRecord app, int pid, 1016 IApplicationThread thread) { 1017 if (localLOGV) Slog.v( 1018 TAG, "New death recipient " + this 1019 + " for thread " + thread.asBinder()); 1020 mApp = app; 1021 mPid = pid; 1022 mAppThread = thread; 1023 } 1024 1025 @Override 1026 public void binderDied() { 1027 if (localLOGV) Slog.v( 1028 TAG, "Death received in " + this 1029 + " for thread " + mAppThread.asBinder()); 1030 synchronized(ActivityManagerService.this) { 1031 appDiedLocked(mApp, mPid, mAppThread); 1032 } 1033 } 1034 } 1035 1036 static final int SHOW_ERROR_MSG = 1; 1037 static final int SHOW_NOT_RESPONDING_MSG = 2; 1038 static final int SHOW_FACTORY_ERROR_MSG = 3; 1039 static final int UPDATE_CONFIGURATION_MSG = 4; 1040 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1041 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1042 static final int SERVICE_TIMEOUT_MSG = 12; 1043 static final int UPDATE_TIME_ZONE = 13; 1044 static final int SHOW_UID_ERROR_MSG = 14; 1045 static final int IM_FEELING_LUCKY_MSG = 15; 1046 static final int PROC_START_TIMEOUT_MSG = 20; 1047 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1048 static final int KILL_APPLICATION_MSG = 22; 1049 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1050 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1051 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1052 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1053 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1054 static final int CLEAR_DNS_CACHE_MSG = 28; 1055 static final int UPDATE_HTTP_PROXY_MSG = 29; 1056 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1057 static final int DISPATCH_PROCESSES_CHANGED = 31; 1058 static final int DISPATCH_PROCESS_DIED = 32; 1059 static final int REPORT_MEM_USAGE_MSG = 33; 1060 static final int REPORT_USER_SWITCH_MSG = 34; 1061 static final int CONTINUE_USER_SWITCH_MSG = 35; 1062 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1063 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1064 static final int PERSIST_URI_GRANTS_MSG = 38; 1065 static final int REQUEST_ALL_PSS_MSG = 39; 1066 static final int UPDATE_TIME = 40; 1067 1068 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1069 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1070 static final int FIRST_COMPAT_MODE_MSG = 300; 1071 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1072 1073 AlertDialog mUidAlert; 1074 CompatModeDialog mCompatModeDialog; 1075 long mLastMemUsageReportTime = 0; 1076 1077 /** 1078 * Flag whether the current user is a "monkey", i.e. whether 1079 * the UI is driven by a UI automation tool. 1080 */ 1081 private boolean mUserIsMonkey; 1082 1083 final ServiceThread mHandlerThread; 1084 final MainHandler mHandler; 1085 1086 final class MainHandler extends Handler { 1087 public MainHandler(Looper looper) { 1088 super(looper, null, true); 1089 } 1090 1091 @Override 1092 public void handleMessage(Message msg) { 1093 switch (msg.what) { 1094 case SHOW_ERROR_MSG: { 1095 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1096 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1097 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1098 synchronized (ActivityManagerService.this) { 1099 ProcessRecord proc = (ProcessRecord)data.get("app"); 1100 AppErrorResult res = (AppErrorResult) data.get("result"); 1101 if (proc != null && proc.crashDialog != null) { 1102 Slog.e(TAG, "App already has crash dialog: " + proc); 1103 if (res != null) { 1104 res.set(0); 1105 } 1106 return; 1107 } 1108 if (!showBackground && UserHandle.getAppId(proc.uid) 1109 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1110 && proc.pid != MY_PID) { 1111 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1112 if (res != null) { 1113 res.set(0); 1114 } 1115 return; 1116 } 1117 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1118 Dialog d = new AppErrorDialog(mContext, 1119 ActivityManagerService.this, res, proc); 1120 d.show(); 1121 proc.crashDialog = d; 1122 } else { 1123 // The device is asleep, so just pretend that the user 1124 // saw a crash dialog and hit "force quit". 1125 if (res != null) { 1126 res.set(0); 1127 } 1128 } 1129 } 1130 1131 ensureBootCompleted(); 1132 } break; 1133 case SHOW_NOT_RESPONDING_MSG: { 1134 synchronized (ActivityManagerService.this) { 1135 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1136 ProcessRecord proc = (ProcessRecord)data.get("app"); 1137 if (proc != null && proc.anrDialog != null) { 1138 Slog.e(TAG, "App already has anr dialog: " + proc); 1139 return; 1140 } 1141 1142 Intent intent = new Intent("android.intent.action.ANR"); 1143 if (!mProcessesReady) { 1144 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1145 | Intent.FLAG_RECEIVER_FOREGROUND); 1146 } 1147 broadcastIntentLocked(null, null, intent, 1148 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1149 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1150 1151 if (mShowDialogs) { 1152 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1153 mContext, proc, (ActivityRecord)data.get("activity"), 1154 msg.arg1 != 0); 1155 d.show(); 1156 proc.anrDialog = d; 1157 } else { 1158 // Just kill the app if there is no dialog to be shown. 1159 killAppAtUsersRequest(proc, null); 1160 } 1161 } 1162 1163 ensureBootCompleted(); 1164 } break; 1165 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1166 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1167 synchronized (ActivityManagerService.this) { 1168 ProcessRecord proc = (ProcessRecord) data.get("app"); 1169 if (proc == null) { 1170 Slog.e(TAG, "App not found when showing strict mode dialog."); 1171 break; 1172 } 1173 if (proc.crashDialog != null) { 1174 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1175 return; 1176 } 1177 AppErrorResult res = (AppErrorResult) data.get("result"); 1178 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1179 Dialog d = new StrictModeViolationDialog(mContext, 1180 ActivityManagerService.this, res, proc); 1181 d.show(); 1182 proc.crashDialog = d; 1183 } else { 1184 // The device is asleep, so just pretend that the user 1185 // saw a crash dialog and hit "force quit". 1186 res.set(0); 1187 } 1188 } 1189 ensureBootCompleted(); 1190 } break; 1191 case SHOW_FACTORY_ERROR_MSG: { 1192 Dialog d = new FactoryErrorDialog( 1193 mContext, msg.getData().getCharSequence("msg")); 1194 d.show(); 1195 ensureBootCompleted(); 1196 } break; 1197 case UPDATE_CONFIGURATION_MSG: { 1198 final ContentResolver resolver = mContext.getContentResolver(); 1199 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1200 } break; 1201 case GC_BACKGROUND_PROCESSES_MSG: { 1202 synchronized (ActivityManagerService.this) { 1203 performAppGcsIfAppropriateLocked(); 1204 } 1205 } break; 1206 case WAIT_FOR_DEBUGGER_MSG: { 1207 synchronized (ActivityManagerService.this) { 1208 ProcessRecord app = (ProcessRecord)msg.obj; 1209 if (msg.arg1 != 0) { 1210 if (!app.waitedForDebugger) { 1211 Dialog d = new AppWaitingForDebuggerDialog( 1212 ActivityManagerService.this, 1213 mContext, app); 1214 app.waitDialog = d; 1215 app.waitedForDebugger = true; 1216 d.show(); 1217 } 1218 } else { 1219 if (app.waitDialog != null) { 1220 app.waitDialog.dismiss(); 1221 app.waitDialog = null; 1222 } 1223 } 1224 } 1225 } break; 1226 case SERVICE_TIMEOUT_MSG: { 1227 if (mDidDexOpt) { 1228 mDidDexOpt = false; 1229 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1230 nmsg.obj = msg.obj; 1231 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1232 return; 1233 } 1234 mServices.serviceTimeout((ProcessRecord)msg.obj); 1235 } break; 1236 case UPDATE_TIME_ZONE: { 1237 synchronized (ActivityManagerService.this) { 1238 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1239 ProcessRecord r = mLruProcesses.get(i); 1240 if (r.thread != null) { 1241 try { 1242 r.thread.updateTimeZone(); 1243 } catch (RemoteException ex) { 1244 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1245 } 1246 } 1247 } 1248 } 1249 } break; 1250 case CLEAR_DNS_CACHE_MSG: { 1251 synchronized (ActivityManagerService.this) { 1252 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1253 ProcessRecord r = mLruProcesses.get(i); 1254 if (r.thread != null) { 1255 try { 1256 r.thread.clearDnsCache(); 1257 } catch (RemoteException ex) { 1258 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1259 } 1260 } 1261 } 1262 } 1263 } break; 1264 case UPDATE_HTTP_PROXY_MSG: { 1265 ProxyProperties proxy = (ProxyProperties)msg.obj; 1266 String host = ""; 1267 String port = ""; 1268 String exclList = ""; 1269 String pacFileUrl = null; 1270 if (proxy != null) { 1271 host = proxy.getHost(); 1272 port = Integer.toString(proxy.getPort()); 1273 exclList = proxy.getExclusionList(); 1274 pacFileUrl = proxy.getPacFileUrl(); 1275 } 1276 synchronized (ActivityManagerService.this) { 1277 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1278 ProcessRecord r = mLruProcesses.get(i); 1279 if (r.thread != null) { 1280 try { 1281 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1282 } catch (RemoteException ex) { 1283 Slog.w(TAG, "Failed to update http proxy for: " + 1284 r.info.processName); 1285 } 1286 } 1287 } 1288 } 1289 } break; 1290 case SHOW_UID_ERROR_MSG: { 1291 String title = "System UIDs Inconsistent"; 1292 String text = "UIDs on the system are inconsistent, you need to wipe your" 1293 + " data partition or your device will be unstable."; 1294 Log.e(TAG, title + ": " + text); 1295 if (mShowDialogs) { 1296 // XXX This is a temporary dialog, no need to localize. 1297 AlertDialog d = new BaseErrorDialog(mContext); 1298 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1299 d.setCancelable(false); 1300 d.setTitle(title); 1301 d.setMessage(text); 1302 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1303 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1304 mUidAlert = d; 1305 d.show(); 1306 } 1307 } break; 1308 case IM_FEELING_LUCKY_MSG: { 1309 if (mUidAlert != null) { 1310 mUidAlert.dismiss(); 1311 mUidAlert = null; 1312 } 1313 } break; 1314 case PROC_START_TIMEOUT_MSG: { 1315 if (mDidDexOpt) { 1316 mDidDexOpt = false; 1317 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1318 nmsg.obj = msg.obj; 1319 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1320 return; 1321 } 1322 ProcessRecord app = (ProcessRecord)msg.obj; 1323 synchronized (ActivityManagerService.this) { 1324 processStartTimedOutLocked(app); 1325 } 1326 } break; 1327 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1328 synchronized (ActivityManagerService.this) { 1329 doPendingActivityLaunchesLocked(true); 1330 } 1331 } break; 1332 case KILL_APPLICATION_MSG: { 1333 synchronized (ActivityManagerService.this) { 1334 int appid = msg.arg1; 1335 boolean restart = (msg.arg2 == 1); 1336 Bundle bundle = (Bundle)msg.obj; 1337 String pkg = bundle.getString("pkg"); 1338 String reason = bundle.getString("reason"); 1339 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1340 UserHandle.USER_ALL, reason); 1341 } 1342 } break; 1343 case FINALIZE_PENDING_INTENT_MSG: { 1344 ((PendingIntentRecord)msg.obj).completeFinalize(); 1345 } break; 1346 case POST_HEAVY_NOTIFICATION_MSG: { 1347 INotificationManager inm = NotificationManager.getService(); 1348 if (inm == null) { 1349 return; 1350 } 1351 1352 ActivityRecord root = (ActivityRecord)msg.obj; 1353 ProcessRecord process = root.app; 1354 if (process == null) { 1355 return; 1356 } 1357 1358 try { 1359 Context context = mContext.createPackageContext(process.info.packageName, 0); 1360 String text = mContext.getString(R.string.heavy_weight_notification, 1361 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1362 Notification notification = new Notification(); 1363 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1364 notification.when = 0; 1365 notification.flags = Notification.FLAG_ONGOING_EVENT; 1366 notification.tickerText = text; 1367 notification.defaults = 0; // please be quiet 1368 notification.sound = null; 1369 notification.vibrate = null; 1370 notification.setLatestEventInfo(context, text, 1371 mContext.getText(R.string.heavy_weight_notification_detail), 1372 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1373 PendingIntent.FLAG_CANCEL_CURRENT, null, 1374 new UserHandle(root.userId))); 1375 1376 try { 1377 int[] outId = new int[1]; 1378 inm.enqueueNotificationWithTag("android", "android", null, 1379 R.string.heavy_weight_notification, 1380 notification, outId, root.userId); 1381 } catch (RuntimeException e) { 1382 Slog.w(ActivityManagerService.TAG, 1383 "Error showing notification for heavy-weight app", e); 1384 } catch (RemoteException e) { 1385 } 1386 } catch (NameNotFoundException e) { 1387 Slog.w(TAG, "Unable to create context for heavy notification", e); 1388 } 1389 } break; 1390 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1391 INotificationManager inm = NotificationManager.getService(); 1392 if (inm == null) { 1393 return; 1394 } 1395 try { 1396 inm.cancelNotificationWithTag("android", null, 1397 R.string.heavy_weight_notification, msg.arg1); 1398 } catch (RuntimeException e) { 1399 Slog.w(ActivityManagerService.TAG, 1400 "Error canceling notification for service", e); 1401 } catch (RemoteException e) { 1402 } 1403 } break; 1404 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1405 synchronized (ActivityManagerService.this) { 1406 checkExcessivePowerUsageLocked(true); 1407 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1408 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1409 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1410 } 1411 } break; 1412 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1413 synchronized (ActivityManagerService.this) { 1414 ActivityRecord ar = (ActivityRecord)msg.obj; 1415 if (mCompatModeDialog != null) { 1416 if (mCompatModeDialog.mAppInfo.packageName.equals( 1417 ar.info.applicationInfo.packageName)) { 1418 return; 1419 } 1420 mCompatModeDialog.dismiss(); 1421 mCompatModeDialog = null; 1422 } 1423 if (ar != null && false) { 1424 if (mCompatModePackages.getPackageAskCompatModeLocked( 1425 ar.packageName)) { 1426 int mode = mCompatModePackages.computeCompatModeLocked( 1427 ar.info.applicationInfo); 1428 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1429 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1430 mCompatModeDialog = new CompatModeDialog( 1431 ActivityManagerService.this, mContext, 1432 ar.info.applicationInfo); 1433 mCompatModeDialog.show(); 1434 } 1435 } 1436 } 1437 } 1438 break; 1439 } 1440 case DISPATCH_PROCESSES_CHANGED: { 1441 dispatchProcessesChanged(); 1442 break; 1443 } 1444 case DISPATCH_PROCESS_DIED: { 1445 final int pid = msg.arg1; 1446 final int uid = msg.arg2; 1447 dispatchProcessDied(pid, uid); 1448 break; 1449 } 1450 case REPORT_MEM_USAGE_MSG: { 1451 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1452 Thread thread = new Thread() { 1453 @Override public void run() { 1454 final SparseArray<ProcessMemInfo> infoMap 1455 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1456 for (int i=0, N=memInfos.size(); i<N; i++) { 1457 ProcessMemInfo mi = memInfos.get(i); 1458 infoMap.put(mi.pid, mi); 1459 } 1460 updateCpuStatsNow(); 1461 synchronized (mProcessCpuThread) { 1462 final int N = mProcessCpuTracker.countStats(); 1463 for (int i=0; i<N; i++) { 1464 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1465 if (st.vsize > 0) { 1466 long pss = Debug.getPss(st.pid, null); 1467 if (pss > 0) { 1468 if (infoMap.indexOfKey(st.pid) < 0) { 1469 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1470 ProcessList.NATIVE_ADJ, -1, "native", null); 1471 mi.pss = pss; 1472 memInfos.add(mi); 1473 } 1474 } 1475 } 1476 } 1477 } 1478 1479 long totalPss = 0; 1480 for (int i=0, N=memInfos.size(); i<N; i++) { 1481 ProcessMemInfo mi = memInfos.get(i); 1482 if (mi.pss == 0) { 1483 mi.pss = Debug.getPss(mi.pid, null); 1484 } 1485 totalPss += mi.pss; 1486 } 1487 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1488 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1489 if (lhs.oomAdj != rhs.oomAdj) { 1490 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1491 } 1492 if (lhs.pss != rhs.pss) { 1493 return lhs.pss < rhs.pss ? 1 : -1; 1494 } 1495 return 0; 1496 } 1497 }); 1498 1499 StringBuilder tag = new StringBuilder(128); 1500 StringBuilder stack = new StringBuilder(128); 1501 tag.append("Low on memory -- "); 1502 appendMemBucket(tag, totalPss, "total", false); 1503 appendMemBucket(stack, totalPss, "total", true); 1504 1505 StringBuilder logBuilder = new StringBuilder(1024); 1506 logBuilder.append("Low on memory:\n"); 1507 1508 boolean firstLine = true; 1509 int lastOomAdj = Integer.MIN_VALUE; 1510 for (int i=0, N=memInfos.size(); i<N; i++) { 1511 ProcessMemInfo mi = memInfos.get(i); 1512 1513 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1514 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1515 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1516 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1517 if (lastOomAdj != mi.oomAdj) { 1518 lastOomAdj = mi.oomAdj; 1519 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1520 tag.append(" / "); 1521 } 1522 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1523 if (firstLine) { 1524 stack.append(":"); 1525 firstLine = false; 1526 } 1527 stack.append("\n\t at "); 1528 } else { 1529 stack.append("$"); 1530 } 1531 } else { 1532 tag.append(" "); 1533 stack.append("$"); 1534 } 1535 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1536 appendMemBucket(tag, mi.pss, mi.name, false); 1537 } 1538 appendMemBucket(stack, mi.pss, mi.name, true); 1539 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1540 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1541 stack.append("("); 1542 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1543 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1544 stack.append(DUMP_MEM_OOM_LABEL[k]); 1545 stack.append(":"); 1546 stack.append(DUMP_MEM_OOM_ADJ[k]); 1547 } 1548 } 1549 stack.append(")"); 1550 } 1551 } 1552 1553 logBuilder.append(" "); 1554 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1555 logBuilder.append(' '); 1556 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1557 logBuilder.append(' '); 1558 ProcessList.appendRamKb(logBuilder, mi.pss); 1559 logBuilder.append(" kB: "); 1560 logBuilder.append(mi.name); 1561 logBuilder.append(" ("); 1562 logBuilder.append(mi.pid); 1563 logBuilder.append(") "); 1564 logBuilder.append(mi.adjType); 1565 logBuilder.append('\n'); 1566 if (mi.adjReason != null) { 1567 logBuilder.append(" "); 1568 logBuilder.append(mi.adjReason); 1569 logBuilder.append('\n'); 1570 } 1571 } 1572 1573 logBuilder.append(" "); 1574 ProcessList.appendRamKb(logBuilder, totalPss); 1575 logBuilder.append(" kB: TOTAL\n"); 1576 1577 long[] infos = new long[Debug.MEMINFO_COUNT]; 1578 Debug.getMemInfo(infos); 1579 logBuilder.append(" MemInfo: "); 1580 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1581 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1582 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1583 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1584 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1585 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1586 logBuilder.append(" ZRAM: "); 1587 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1588 logBuilder.append(" kB RAM, "); 1589 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1590 logBuilder.append(" kB swap total, "); 1591 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1592 logBuilder.append(" kB swap free\n"); 1593 } 1594 Slog.i(TAG, logBuilder.toString()); 1595 1596 StringBuilder dropBuilder = new StringBuilder(1024); 1597 /* 1598 StringWriter oomSw = new StringWriter(); 1599 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1600 StringWriter catSw = new StringWriter(); 1601 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1602 String[] emptyArgs = new String[] { }; 1603 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1604 oomPw.flush(); 1605 String oomString = oomSw.toString(); 1606 */ 1607 dropBuilder.append(stack); 1608 dropBuilder.append('\n'); 1609 dropBuilder.append('\n'); 1610 dropBuilder.append(logBuilder); 1611 dropBuilder.append('\n'); 1612 /* 1613 dropBuilder.append(oomString); 1614 dropBuilder.append('\n'); 1615 */ 1616 StringWriter catSw = new StringWriter(); 1617 synchronized (ActivityManagerService.this) { 1618 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1619 String[] emptyArgs = new String[] { }; 1620 catPw.println(); 1621 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1622 catPw.println(); 1623 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1624 false, false, null); 1625 catPw.println(); 1626 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1627 catPw.flush(); 1628 } 1629 dropBuilder.append(catSw.toString()); 1630 addErrorToDropBox("lowmem", null, "system_server", null, 1631 null, tag.toString(), dropBuilder.toString(), null, null); 1632 //Slog.i(TAG, "Sent to dropbox:"); 1633 //Slog.i(TAG, dropBuilder.toString()); 1634 synchronized (ActivityManagerService.this) { 1635 long now = SystemClock.uptimeMillis(); 1636 if (mLastMemUsageReportTime < now) { 1637 mLastMemUsageReportTime = now; 1638 } 1639 } 1640 } 1641 }; 1642 thread.start(); 1643 break; 1644 } 1645 case REPORT_USER_SWITCH_MSG: { 1646 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1647 break; 1648 } 1649 case CONTINUE_USER_SWITCH_MSG: { 1650 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1651 break; 1652 } 1653 case USER_SWITCH_TIMEOUT_MSG: { 1654 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1655 break; 1656 } 1657 case IMMERSIVE_MODE_LOCK_MSG: { 1658 final boolean nextState = (msg.arg1 != 0); 1659 if (mUpdateLock.isHeld() != nextState) { 1660 if (DEBUG_IMMERSIVE) { 1661 final ActivityRecord r = (ActivityRecord) msg.obj; 1662 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1663 } 1664 if (nextState) { 1665 mUpdateLock.acquire(); 1666 } else { 1667 mUpdateLock.release(); 1668 } 1669 } 1670 break; 1671 } 1672 case PERSIST_URI_GRANTS_MSG: { 1673 writeGrantedUriPermissions(); 1674 break; 1675 } 1676 case REQUEST_ALL_PSS_MSG: { 1677 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1678 break; 1679 } 1680 case UPDATE_TIME: { 1681 synchronized (ActivityManagerService.this) { 1682 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1683 ProcessRecord r = mLruProcesses.get(i); 1684 if (r.thread != null) { 1685 try { 1686 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1687 } catch (RemoteException ex) { 1688 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1689 } 1690 } 1691 } 1692 } 1693 1694 break; 1695 } 1696 } 1697 } 1698 }; 1699 1700 static final int COLLECT_PSS_BG_MSG = 1; 1701 1702 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1703 @Override 1704 public void handleMessage(Message msg) { 1705 switch (msg.what) { 1706 case COLLECT_PSS_BG_MSG: { 1707 int i=0, num=0; 1708 long start = SystemClock.uptimeMillis(); 1709 long[] tmp = new long[1]; 1710 do { 1711 ProcessRecord proc; 1712 int procState; 1713 int pid; 1714 synchronized (ActivityManagerService.this) { 1715 if (i >= mPendingPssProcesses.size()) { 1716 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1717 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1718 mPendingPssProcesses.clear(); 1719 return; 1720 } 1721 proc = mPendingPssProcesses.get(i); 1722 procState = proc.pssProcState; 1723 if (proc.thread != null && procState == proc.setProcState) { 1724 pid = proc.pid; 1725 } else { 1726 proc = null; 1727 pid = 0; 1728 } 1729 i++; 1730 } 1731 if (proc != null) { 1732 long pss = Debug.getPss(pid, tmp); 1733 synchronized (ActivityManagerService.this) { 1734 if (proc.thread != null && proc.setProcState == procState 1735 && proc.pid == pid) { 1736 num++; 1737 proc.lastPssTime = SystemClock.uptimeMillis(); 1738 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1739 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1740 + ": " + pss + " lastPss=" + proc.lastPss 1741 + " state=" + ProcessList.makeProcStateString(procState)); 1742 if (proc.initialIdlePss == 0) { 1743 proc.initialIdlePss = pss; 1744 } 1745 proc.lastPss = pss; 1746 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1747 proc.lastCachedPss = pss; 1748 } 1749 } 1750 } 1751 } 1752 } while (true); 1753 } 1754 } 1755 } 1756 }; 1757 1758 public void setSystemProcess() { 1759 try { 1760 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1761 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1762 ServiceManager.addService("meminfo", new MemBinder(this)); 1763 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1764 ServiceManager.addService("dbinfo", new DbBinder(this)); 1765 if (MONITOR_CPU_USAGE) { 1766 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1767 } 1768 ServiceManager.addService("permission", new PermissionController(this)); 1769 1770 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1771 "android", STOCK_PM_FLAGS); 1772 mSystemThread.installSystemApplicationInfo(info); 1773 1774 synchronized (this) { 1775 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1776 app.persistent = true; 1777 app.pid = MY_PID; 1778 app.maxAdj = ProcessList.SYSTEM_ADJ; 1779 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1780 mProcessNames.put(app.processName, app.uid, app); 1781 synchronized (mPidsSelfLocked) { 1782 mPidsSelfLocked.put(app.pid, app); 1783 } 1784 updateLruProcessLocked(app, false, null); 1785 updateOomAdjLocked(); 1786 } 1787 } catch (PackageManager.NameNotFoundException e) { 1788 throw new RuntimeException( 1789 "Unable to find android system package", e); 1790 } 1791 } 1792 1793 public void setWindowManager(WindowManagerService wm) { 1794 mWindowManager = wm; 1795 mStackSupervisor.setWindowManager(wm); 1796 } 1797 1798 public void startObservingNativeCrashes() { 1799 final NativeCrashListener ncl = new NativeCrashListener(this); 1800 ncl.start(); 1801 } 1802 1803 public IAppOpsService getAppOpsService() { 1804 return mAppOpsService; 1805 } 1806 1807 static class MemBinder extends Binder { 1808 ActivityManagerService mActivityManagerService; 1809 MemBinder(ActivityManagerService activityManagerService) { 1810 mActivityManagerService = activityManagerService; 1811 } 1812 1813 @Override 1814 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1815 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1816 != PackageManager.PERMISSION_GRANTED) { 1817 pw.println("Permission Denial: can't dump meminfo from from pid=" 1818 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1819 + " without permission " + android.Manifest.permission.DUMP); 1820 return; 1821 } 1822 1823 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1824 } 1825 } 1826 1827 static class GraphicsBinder extends Binder { 1828 ActivityManagerService mActivityManagerService; 1829 GraphicsBinder(ActivityManagerService activityManagerService) { 1830 mActivityManagerService = activityManagerService; 1831 } 1832 1833 @Override 1834 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1835 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1836 != PackageManager.PERMISSION_GRANTED) { 1837 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1838 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1839 + " without permission " + android.Manifest.permission.DUMP); 1840 return; 1841 } 1842 1843 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1844 } 1845 } 1846 1847 static class DbBinder extends Binder { 1848 ActivityManagerService mActivityManagerService; 1849 DbBinder(ActivityManagerService activityManagerService) { 1850 mActivityManagerService = activityManagerService; 1851 } 1852 1853 @Override 1854 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1855 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1856 != PackageManager.PERMISSION_GRANTED) { 1857 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1858 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1859 + " without permission " + android.Manifest.permission.DUMP); 1860 return; 1861 } 1862 1863 mActivityManagerService.dumpDbInfo(fd, pw, args); 1864 } 1865 } 1866 1867 static class CpuBinder extends Binder { 1868 ActivityManagerService mActivityManagerService; 1869 CpuBinder(ActivityManagerService activityManagerService) { 1870 mActivityManagerService = activityManagerService; 1871 } 1872 1873 @Override 1874 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1875 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1876 != PackageManager.PERMISSION_GRANTED) { 1877 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1878 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1879 + " without permission " + android.Manifest.permission.DUMP); 1880 return; 1881 } 1882 1883 synchronized (mActivityManagerService.mProcessCpuThread) { 1884 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1885 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1886 SystemClock.uptimeMillis())); 1887 } 1888 } 1889 } 1890 1891 public static final class Lifecycle extends SystemService { 1892 private final ActivityManagerService mService; 1893 1894 public Lifecycle(Context context) { 1895 super(context); 1896 mService = new ActivityManagerService(context); 1897 } 1898 1899 @Override 1900 public void onStart() { 1901 mService.start(); 1902 } 1903 1904 public ActivityManagerService getService() { 1905 return mService; 1906 } 1907 } 1908 1909 // Note: This method is invoked on the main thread but may need to attach various 1910 // handlers to other threads. So take care to be explicit about the looper. 1911 public ActivityManagerService(Context systemContext) { 1912 mContext = systemContext; 1913 mFactoryTest = FactoryTest.getMode(); 1914 mSystemThread = ActivityThread.currentActivityThread(); 1915 1916 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1917 1918 mHandlerThread = new ServiceThread(TAG, 1919 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1920 mHandlerThread.start(); 1921 mHandler = new MainHandler(mHandlerThread.getLooper()); 1922 1923 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1924 "foreground", BROADCAST_FG_TIMEOUT, false); 1925 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1926 "background", BROADCAST_BG_TIMEOUT, true); 1927 mBroadcastQueues[0] = mFgBroadcastQueue; 1928 mBroadcastQueues[1] = mBgBroadcastQueue; 1929 1930 mServices = new ActiveServices(this); 1931 mProviderMap = new ProviderMap(this); 1932 1933 // TODO: Move creation of battery stats service outside of activity manager service. 1934 File dataDir = Environment.getDataDirectory(); 1935 File systemDir = new File(dataDir, "system"); 1936 systemDir.mkdirs(); 1937 mBatteryStatsService = new BatteryStatsService(new File( 1938 systemDir, "batterystats.bin").toString(), mHandler); 1939 mBatteryStatsService.getActiveStatistics().readLocked(); 1940 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1941 mOnBattery = DEBUG_POWER ? true 1942 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1943 mBatteryStatsService.getActiveStatistics().setCallback(this); 1944 1945 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1946 1947 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1948 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1949 1950 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1951 1952 // User 0 is the first and only user that runs at boot. 1953 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1954 mUserLru.add(Integer.valueOf(0)); 1955 updateStartedUserArrayLocked(); 1956 1957 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1958 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1959 1960 mConfiguration.setToDefaults(); 1961 mConfiguration.setLocale(Locale.getDefault()); 1962 1963 mConfigurationSeq = mConfiguration.seq = 1; 1964 mProcessCpuTracker.init(); 1965 1966 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1967 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1968 mStackSupervisor = new ActivityStackSupervisor(this); 1969 1970 mProcessCpuThread = new Thread("CpuTracker") { 1971 @Override 1972 public void run() { 1973 while (true) { 1974 try { 1975 try { 1976 synchronized(this) { 1977 final long now = SystemClock.uptimeMillis(); 1978 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1979 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1980 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1981 // + ", write delay=" + nextWriteDelay); 1982 if (nextWriteDelay < nextCpuDelay) { 1983 nextCpuDelay = nextWriteDelay; 1984 } 1985 if (nextCpuDelay > 0) { 1986 mProcessCpuMutexFree.set(true); 1987 this.wait(nextCpuDelay); 1988 } 1989 } 1990 } catch (InterruptedException e) { 1991 } 1992 updateCpuStatsNow(); 1993 } catch (Exception e) { 1994 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1995 } 1996 } 1997 } 1998 }; 1999 2000 Watchdog.getInstance().addMonitor(this); 2001 Watchdog.getInstance().addThread(mHandler); 2002 } 2003 2004 private void start() { 2005 mProcessCpuThread.start(); 2006 2007 mBatteryStatsService.publish(mContext); 2008 mUsageStatsService.publish(mContext); 2009 mAppOpsService.publish(mContext); 2010 2011 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2012 } 2013 2014 @Override 2015 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2016 throws RemoteException { 2017 if (code == SYSPROPS_TRANSACTION) { 2018 // We need to tell all apps about the system property change. 2019 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2020 synchronized(this) { 2021 final int NP = mProcessNames.getMap().size(); 2022 for (int ip=0; ip<NP; ip++) { 2023 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2024 final int NA = apps.size(); 2025 for (int ia=0; ia<NA; ia++) { 2026 ProcessRecord app = apps.valueAt(ia); 2027 if (app.thread != null) { 2028 procs.add(app.thread.asBinder()); 2029 } 2030 } 2031 } 2032 } 2033 2034 int N = procs.size(); 2035 for (int i=0; i<N; i++) { 2036 Parcel data2 = Parcel.obtain(); 2037 try { 2038 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2039 } catch (RemoteException e) { 2040 } 2041 data2.recycle(); 2042 } 2043 } 2044 try { 2045 return super.onTransact(code, data, reply, flags); 2046 } catch (RuntimeException e) { 2047 // The activity manager only throws security exceptions, so let's 2048 // log all others. 2049 if (!(e instanceof SecurityException)) { 2050 Slog.wtf(TAG, "Activity Manager Crash", e); 2051 } 2052 throw e; 2053 } 2054 } 2055 2056 void updateCpuStats() { 2057 final long now = SystemClock.uptimeMillis(); 2058 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2059 return; 2060 } 2061 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2062 synchronized (mProcessCpuThread) { 2063 mProcessCpuThread.notify(); 2064 } 2065 } 2066 } 2067 2068 void updateCpuStatsNow() { 2069 synchronized (mProcessCpuThread) { 2070 mProcessCpuMutexFree.set(false); 2071 final long now = SystemClock.uptimeMillis(); 2072 boolean haveNewCpuStats = false; 2073 2074 if (MONITOR_CPU_USAGE && 2075 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2076 mLastCpuTime.set(now); 2077 haveNewCpuStats = true; 2078 mProcessCpuTracker.update(); 2079 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2080 //Slog.i(TAG, "Total CPU usage: " 2081 // + mProcessCpu.getTotalCpuPercent() + "%"); 2082 2083 // Slog the cpu usage if the property is set. 2084 if ("true".equals(SystemProperties.get("events.cpu"))) { 2085 int user = mProcessCpuTracker.getLastUserTime(); 2086 int system = mProcessCpuTracker.getLastSystemTime(); 2087 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2088 int irq = mProcessCpuTracker.getLastIrqTime(); 2089 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2090 int idle = mProcessCpuTracker.getLastIdleTime(); 2091 2092 int total = user + system + iowait + irq + softIrq + idle; 2093 if (total == 0) total = 1; 2094 2095 EventLog.writeEvent(EventLogTags.CPU, 2096 ((user+system+iowait+irq+softIrq) * 100) / total, 2097 (user * 100) / total, 2098 (system * 100) / total, 2099 (iowait * 100) / total, 2100 (irq * 100) / total, 2101 (softIrq * 100) / total); 2102 } 2103 } 2104 2105 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2106 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2107 synchronized(bstats) { 2108 synchronized(mPidsSelfLocked) { 2109 if (haveNewCpuStats) { 2110 if (mOnBattery) { 2111 int perc = bstats.startAddingCpuLocked(); 2112 int totalUTime = 0; 2113 int totalSTime = 0; 2114 final int N = mProcessCpuTracker.countStats(); 2115 for (int i=0; i<N; i++) { 2116 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2117 if (!st.working) { 2118 continue; 2119 } 2120 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2121 int otherUTime = (st.rel_utime*perc)/100; 2122 int otherSTime = (st.rel_stime*perc)/100; 2123 totalUTime += otherUTime; 2124 totalSTime += otherSTime; 2125 if (pr != null) { 2126 BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked( 2127 st.name, st.pid); 2128 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2129 st.rel_stime-otherSTime); 2130 ps.addSpeedStepTimes(cpuSpeedTimes); 2131 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2132 } else if (st.uid >= Process.FIRST_APPLICATION_UID) { 2133 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2134 if (ps == null) { 2135 st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid, 2136 "(Unknown)"); 2137 } 2138 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2139 st.rel_stime-otherSTime); 2140 ps.addSpeedStepTimes(cpuSpeedTimes); 2141 } else { 2142 BatteryStatsImpl.Uid.Proc ps = 2143 bstats.getProcessStatsLocked(st.name, st.pid); 2144 if (ps != null) { 2145 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2146 st.rel_stime-otherSTime); 2147 ps.addSpeedStepTimes(cpuSpeedTimes); 2148 } 2149 } 2150 } 2151 bstats.finishAddingCpuLocked(perc, totalUTime, 2152 totalSTime, cpuSpeedTimes); 2153 } 2154 } 2155 } 2156 2157 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2158 mLastWriteTime = now; 2159 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2160 } 2161 } 2162 } 2163 } 2164 2165 @Override 2166 public void batteryNeedsCpuUpdate() { 2167 updateCpuStatsNow(); 2168 } 2169 2170 @Override 2171 public void batteryPowerChanged(boolean onBattery) { 2172 // When plugging in, update the CPU stats first before changing 2173 // the plug state. 2174 updateCpuStatsNow(); 2175 synchronized (this) { 2176 synchronized(mPidsSelfLocked) { 2177 mOnBattery = DEBUG_POWER ? true : onBattery; 2178 } 2179 } 2180 } 2181 2182 /** 2183 * Initialize the application bind args. These are passed to each 2184 * process when the bindApplication() IPC is sent to the process. They're 2185 * lazily setup to make sure the services are running when they're asked for. 2186 */ 2187 private HashMap<String, IBinder> getCommonServicesLocked() { 2188 if (mAppBindArgs == null) { 2189 mAppBindArgs = new HashMap<String, IBinder>(); 2190 2191 // Setup the application init args 2192 mAppBindArgs.put("package", ServiceManager.getService("package")); 2193 mAppBindArgs.put("window", ServiceManager.getService("window")); 2194 mAppBindArgs.put(Context.ALARM_SERVICE, 2195 ServiceManager.getService(Context.ALARM_SERVICE)); 2196 } 2197 return mAppBindArgs; 2198 } 2199 2200 final void setFocusedActivityLocked(ActivityRecord r) { 2201 if (mFocusedActivity != r) { 2202 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2203 mFocusedActivity = r; 2204 mStackSupervisor.setFocusedStack(r); 2205 if (r != null) { 2206 mWindowManager.setFocusedApp(r.appToken, true); 2207 } 2208 applyUpdateLockStateLocked(r); 2209 } 2210 } 2211 2212 @Override 2213 public void setFocusedStack(int stackId) { 2214 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2215 synchronized (ActivityManagerService.this) { 2216 ActivityStack stack = mStackSupervisor.getStack(stackId); 2217 if (stack != null) { 2218 ActivityRecord r = stack.topRunningActivityLocked(null); 2219 if (r != null) { 2220 setFocusedActivityLocked(r); 2221 } 2222 } 2223 } 2224 } 2225 2226 @Override 2227 public void notifyActivityDrawn(IBinder token) { 2228 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2229 synchronized (this) { 2230 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2231 if (r != null) { 2232 r.task.stack.notifyActivityDrawnLocked(r); 2233 } 2234 } 2235 } 2236 2237 final void applyUpdateLockStateLocked(ActivityRecord r) { 2238 // Modifications to the UpdateLock state are done on our handler, outside 2239 // the activity manager's locks. The new state is determined based on the 2240 // state *now* of the relevant activity record. The object is passed to 2241 // the handler solely for logging detail, not to be consulted/modified. 2242 final boolean nextState = r != null && r.immersive; 2243 mHandler.sendMessage( 2244 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2245 } 2246 2247 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2248 Message msg = Message.obtain(); 2249 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2250 msg.obj = r.task.askedCompatMode ? null : r; 2251 mHandler.sendMessage(msg); 2252 } 2253 2254 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2255 String what, Object obj, ProcessRecord srcApp) { 2256 app.lastActivityTime = now; 2257 2258 if (app.activities.size() > 0) { 2259 // Don't want to touch dependent processes that are hosting activities. 2260 return index; 2261 } 2262 2263 int lrui = mLruProcesses.lastIndexOf(app); 2264 if (lrui < 0) { 2265 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2266 + what + " " + obj + " from " + srcApp); 2267 return index; 2268 } 2269 2270 if (lrui >= index) { 2271 // Don't want to cause this to move dependent processes *back* in the 2272 // list as if they were less frequently used. 2273 return index; 2274 } 2275 2276 if (lrui >= mLruProcessActivityStart) { 2277 // Don't want to touch dependent processes that are hosting activities. 2278 return index; 2279 } 2280 2281 mLruProcesses.remove(lrui); 2282 if (index > 0) { 2283 index--; 2284 } 2285 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2286 + " in LRU list: " + app); 2287 mLruProcesses.add(index, app); 2288 return index; 2289 } 2290 2291 final void removeLruProcessLocked(ProcessRecord app) { 2292 int lrui = mLruProcesses.lastIndexOf(app); 2293 if (lrui >= 0) { 2294 if (lrui <= mLruProcessActivityStart) { 2295 mLruProcessActivityStart--; 2296 } 2297 if (lrui <= mLruProcessServiceStart) { 2298 mLruProcessServiceStart--; 2299 } 2300 mLruProcesses.remove(lrui); 2301 } 2302 } 2303 2304 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2305 ProcessRecord client) { 2306 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities; 2307 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2308 if (!activityChange && hasActivity) { 2309 // The process has activties, so we are only going to allow activity-based 2310 // adjustments move it. It should be kept in the front of the list with other 2311 // processes that have activities, and we don't want those to change their 2312 // order except due to activity operations. 2313 return; 2314 } 2315 2316 mLruSeq++; 2317 final long now = SystemClock.uptimeMillis(); 2318 app.lastActivityTime = now; 2319 2320 // First a quick reject: if the app is already at the position we will 2321 // put it, then there is nothing to do. 2322 if (hasActivity) { 2323 final int N = mLruProcesses.size(); 2324 if (N > 0 && mLruProcesses.get(N-1) == app) { 2325 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2326 return; 2327 } 2328 } else { 2329 if (mLruProcessServiceStart > 0 2330 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2331 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2332 return; 2333 } 2334 } 2335 2336 int lrui = mLruProcesses.lastIndexOf(app); 2337 2338 if (app.persistent && lrui >= 0) { 2339 // We don't care about the position of persistent processes, as long as 2340 // they are in the list. 2341 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2342 return; 2343 } 2344 2345 /* In progress: compute new position first, so we can avoid doing work 2346 if the process is not actually going to move. Not yet working. 2347 int addIndex; 2348 int nextIndex; 2349 boolean inActivity = false, inService = false; 2350 if (hasActivity) { 2351 // Process has activities, put it at the very tipsy-top. 2352 addIndex = mLruProcesses.size(); 2353 nextIndex = mLruProcessServiceStart; 2354 inActivity = true; 2355 } else if (hasService) { 2356 // Process has services, put it at the top of the service list. 2357 addIndex = mLruProcessActivityStart; 2358 nextIndex = mLruProcessServiceStart; 2359 inActivity = true; 2360 inService = true; 2361 } else { 2362 // Process not otherwise of interest, it goes to the top of the non-service area. 2363 addIndex = mLruProcessServiceStart; 2364 if (client != null) { 2365 int clientIndex = mLruProcesses.lastIndexOf(client); 2366 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2367 + app); 2368 if (clientIndex >= 0 && addIndex > clientIndex) { 2369 addIndex = clientIndex; 2370 } 2371 } 2372 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2373 } 2374 2375 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2376 + mLruProcessActivityStart + "): " + app); 2377 */ 2378 2379 if (lrui >= 0) { 2380 if (lrui < mLruProcessActivityStart) { 2381 mLruProcessActivityStart--; 2382 } 2383 if (lrui < mLruProcessServiceStart) { 2384 mLruProcessServiceStart--; 2385 } 2386 /* 2387 if (addIndex > lrui) { 2388 addIndex--; 2389 } 2390 if (nextIndex > lrui) { 2391 nextIndex--; 2392 } 2393 */ 2394 mLruProcesses.remove(lrui); 2395 } 2396 2397 /* 2398 mLruProcesses.add(addIndex, app); 2399 if (inActivity) { 2400 mLruProcessActivityStart++; 2401 } 2402 if (inService) { 2403 mLruProcessActivityStart++; 2404 } 2405 */ 2406 2407 int nextIndex; 2408 if (hasActivity) { 2409 final int N = mLruProcesses.size(); 2410 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2411 // Process doesn't have activities, but has clients with 2412 // activities... move it up, but one below the top (the top 2413 // should always have a real activity). 2414 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2415 mLruProcesses.add(N-1, app); 2416 // To keep it from spamming the LRU list (by making a bunch of clients), 2417 // we will push down any other entries owned by the app. 2418 final int uid = app.info.uid; 2419 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2420 ProcessRecord subProc = mLruProcesses.get(i); 2421 if (subProc.info.uid == uid) { 2422 // We want to push this one down the list. If the process after 2423 // it is for the same uid, however, don't do so, because we don't 2424 // want them internally to be re-ordered. 2425 if (mLruProcesses.get(i-1).info.uid != uid) { 2426 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2427 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2428 ProcessRecord tmp = mLruProcesses.get(i); 2429 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2430 mLruProcesses.set(i-1, tmp); 2431 i--; 2432 } 2433 } else { 2434 // A gap, we can stop here. 2435 break; 2436 } 2437 } 2438 } else { 2439 // Process has activities, put it at the very tipsy-top. 2440 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2441 mLruProcesses.add(app); 2442 } 2443 nextIndex = mLruProcessServiceStart; 2444 } else if (hasService) { 2445 // Process has services, put it at the top of the service list. 2446 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2447 mLruProcesses.add(mLruProcessActivityStart, app); 2448 nextIndex = mLruProcessServiceStart; 2449 mLruProcessActivityStart++; 2450 } else { 2451 // Process not otherwise of interest, it goes to the top of the non-service area. 2452 int index = mLruProcessServiceStart; 2453 if (client != null) { 2454 // If there is a client, don't allow the process to be moved up higher 2455 // in the list than that client. 2456 int clientIndex = mLruProcesses.lastIndexOf(client); 2457 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2458 + " when updating " + app); 2459 if (clientIndex <= lrui) { 2460 // Don't allow the client index restriction to push it down farther in the 2461 // list than it already is. 2462 clientIndex = lrui; 2463 } 2464 if (clientIndex >= 0 && index > clientIndex) { 2465 index = clientIndex; 2466 } 2467 } 2468 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2469 mLruProcesses.add(index, app); 2470 nextIndex = index-1; 2471 mLruProcessActivityStart++; 2472 mLruProcessServiceStart++; 2473 } 2474 2475 // If the app is currently using a content provider or service, 2476 // bump those processes as well. 2477 for (int j=app.connections.size()-1; j>=0; j--) { 2478 ConnectionRecord cr = app.connections.valueAt(j); 2479 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2480 && cr.binding.service.app != null 2481 && cr.binding.service.app.lruSeq != mLruSeq 2482 && !cr.binding.service.app.persistent) { 2483 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2484 "service connection", cr, app); 2485 } 2486 } 2487 for (int j=app.conProviders.size()-1; j>=0; j--) { 2488 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2489 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2490 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2491 "provider reference", cpr, app); 2492 } 2493 } 2494 } 2495 2496 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2497 if (uid == Process.SYSTEM_UID) { 2498 // The system gets to run in any process. If there are multiple 2499 // processes with the same uid, just pick the first (this 2500 // should never happen). 2501 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2502 if (procs == null) return null; 2503 final int N = procs.size(); 2504 for (int i = 0; i < N; i++) { 2505 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2506 } 2507 } 2508 ProcessRecord proc = mProcessNames.get(processName, uid); 2509 if (false && proc != null && !keepIfLarge 2510 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2511 && proc.lastCachedPss >= 4000) { 2512 // Turn this condition on to cause killing to happen regularly, for testing. 2513 if (proc.baseProcessTracker != null) { 2514 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2515 } 2516 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2517 + "k from cached"); 2518 } else if (proc != null && !keepIfLarge 2519 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2520 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2521 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2522 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2523 if (proc.baseProcessTracker != null) { 2524 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2525 } 2526 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2527 + "k from cached"); 2528 } 2529 } 2530 return proc; 2531 } 2532 2533 void ensurePackageDexOpt(String packageName) { 2534 IPackageManager pm = AppGlobals.getPackageManager(); 2535 try { 2536 if (pm.performDexOpt(packageName)) { 2537 mDidDexOpt = true; 2538 } 2539 } catch (RemoteException e) { 2540 } 2541 } 2542 2543 boolean isNextTransitionForward() { 2544 int transit = mWindowManager.getPendingAppTransition(); 2545 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2546 || transit == AppTransition.TRANSIT_TASK_OPEN 2547 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2548 } 2549 2550 final ProcessRecord startProcessLocked(String processName, 2551 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2552 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2553 boolean isolated, boolean keepIfLarge) { 2554 ProcessRecord app; 2555 if (!isolated) { 2556 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2557 } else { 2558 // If this is an isolated process, it can't re-use an existing process. 2559 app = null; 2560 } 2561 // We don't have to do anything more if: 2562 // (1) There is an existing application record; and 2563 // (2) The caller doesn't think it is dead, OR there is no thread 2564 // object attached to it so we know it couldn't have crashed; and 2565 // (3) There is a pid assigned to it, so it is either starting or 2566 // already running. 2567 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2568 + " app=" + app + " knownToBeDead=" + knownToBeDead 2569 + " thread=" + (app != null ? app.thread : null) 2570 + " pid=" + (app != null ? app.pid : -1)); 2571 if (app != null && app.pid > 0) { 2572 if (!knownToBeDead || app.thread == null) { 2573 // We already have the app running, or are waiting for it to 2574 // come up (we have a pid but not yet its thread), so keep it. 2575 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2576 // If this is a new package in the process, add the package to the list 2577 app.addPackage(info.packageName, mProcessStats); 2578 return app; 2579 } 2580 2581 // An application record is attached to a previous process, 2582 // clean it up now. 2583 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2584 handleAppDiedLocked(app, true, true); 2585 } 2586 2587 String hostingNameStr = hostingName != null 2588 ? hostingName.flattenToShortString() : null; 2589 2590 if (!isolated) { 2591 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2592 // If we are in the background, then check to see if this process 2593 // is bad. If so, we will just silently fail. 2594 if (mBadProcesses.get(info.processName, info.uid) != null) { 2595 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2596 + "/" + info.processName); 2597 return null; 2598 } 2599 } else { 2600 // When the user is explicitly starting a process, then clear its 2601 // crash count so that we won't make it bad until they see at 2602 // least one crash dialog again, and make the process good again 2603 // if it had been bad. 2604 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2605 + "/" + info.processName); 2606 mProcessCrashTimes.remove(info.processName, info.uid); 2607 if (mBadProcesses.get(info.processName, info.uid) != null) { 2608 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2609 UserHandle.getUserId(info.uid), info.uid, 2610 info.processName); 2611 mBadProcesses.remove(info.processName, info.uid); 2612 if (app != null) { 2613 app.bad = false; 2614 } 2615 } 2616 } 2617 } 2618 2619 if (app == null) { 2620 app = newProcessRecordLocked(info, processName, isolated); 2621 if (app == null) { 2622 Slog.w(TAG, "Failed making new process record for " 2623 + processName + "/" + info.uid + " isolated=" + isolated); 2624 return null; 2625 } 2626 mProcessNames.put(processName, app.uid, app); 2627 if (isolated) { 2628 mIsolatedProcesses.put(app.uid, app); 2629 } 2630 } else { 2631 // If this is a new package in the process, add the package to the list 2632 app.addPackage(info.packageName, mProcessStats); 2633 } 2634 2635 // If the system is not ready yet, then hold off on starting this 2636 // process until it is. 2637 if (!mProcessesReady 2638 && !isAllowedWhileBooting(info) 2639 && !allowWhileBooting) { 2640 if (!mProcessesOnHold.contains(app)) { 2641 mProcessesOnHold.add(app); 2642 } 2643 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2644 return app; 2645 } 2646 2647 startProcessLocked(app, hostingType, hostingNameStr); 2648 return (app.pid != 0) ? app : null; 2649 } 2650 2651 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2652 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2653 } 2654 2655 private final void startProcessLocked(ProcessRecord app, 2656 String hostingType, String hostingNameStr) { 2657 if (app.pid > 0 && app.pid != MY_PID) { 2658 synchronized (mPidsSelfLocked) { 2659 mPidsSelfLocked.remove(app.pid); 2660 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2661 } 2662 app.setPid(0); 2663 } 2664 2665 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2666 "startProcessLocked removing on hold: " + app); 2667 mProcessesOnHold.remove(app); 2668 2669 updateCpuStats(); 2670 2671 try { 2672 int uid = app.uid; 2673 2674 int[] gids = null; 2675 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2676 if (!app.isolated) { 2677 int[] permGids = null; 2678 try { 2679 final PackageManager pm = mContext.getPackageManager(); 2680 permGids = pm.getPackageGids(app.info.packageName); 2681 2682 if (Environment.isExternalStorageEmulated()) { 2683 if (pm.checkPermission( 2684 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2685 app.info.packageName) == PERMISSION_GRANTED) { 2686 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2687 } else { 2688 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2689 } 2690 } 2691 } catch (PackageManager.NameNotFoundException e) { 2692 Slog.w(TAG, "Unable to retrieve gids", e); 2693 } 2694 2695 /* 2696 * Add shared application GID so applications can share some 2697 * resources like shared libraries 2698 */ 2699 if (permGids == null) { 2700 gids = new int[1]; 2701 } else { 2702 gids = new int[permGids.length + 1]; 2703 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2704 } 2705 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2706 } 2707 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2708 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2709 && mTopComponent != null 2710 && app.processName.equals(mTopComponent.getPackageName())) { 2711 uid = 0; 2712 } 2713 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2714 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2715 uid = 0; 2716 } 2717 } 2718 int debugFlags = 0; 2719 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2720 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2721 // Also turn on CheckJNI for debuggable apps. It's quite 2722 // awkward to turn on otherwise. 2723 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2724 } 2725 // Run the app in safe mode if its manifest requests so or the 2726 // system is booted in safe mode. 2727 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2728 mSafeMode == true) { 2729 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2730 } 2731 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2732 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2733 } 2734 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2735 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2736 } 2737 if ("1".equals(SystemProperties.get("debug.assert"))) { 2738 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2739 } 2740 2741 // Start the process. It will either succeed and return a result containing 2742 // the PID of the new process, or else throw a RuntimeException. 2743 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2744 app.processName, uid, uid, gids, debugFlags, mountExternal, 2745 app.info.targetSdkVersion, app.info.seinfo, null); 2746 2747 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2748 synchronized (bs) { 2749 if (bs.isOnBattery()) { 2750 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2751 } 2752 } 2753 2754 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2755 UserHandle.getUserId(uid), startResult.pid, uid, 2756 app.processName, hostingType, 2757 hostingNameStr != null ? hostingNameStr : ""); 2758 2759 if (app.persistent) { 2760 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2761 } 2762 2763 StringBuilder buf = mStringBuilder; 2764 buf.setLength(0); 2765 buf.append("Start proc "); 2766 buf.append(app.processName); 2767 buf.append(" for "); 2768 buf.append(hostingType); 2769 if (hostingNameStr != null) { 2770 buf.append(" "); 2771 buf.append(hostingNameStr); 2772 } 2773 buf.append(": pid="); 2774 buf.append(startResult.pid); 2775 buf.append(" uid="); 2776 buf.append(uid); 2777 buf.append(" gids={"); 2778 if (gids != null) { 2779 for (int gi=0; gi<gids.length; gi++) { 2780 if (gi != 0) buf.append(", "); 2781 buf.append(gids[gi]); 2782 2783 } 2784 } 2785 buf.append("}"); 2786 Slog.i(TAG, buf.toString()); 2787 app.setPid(startResult.pid); 2788 app.usingWrapper = startResult.usingWrapper; 2789 app.removed = false; 2790 synchronized (mPidsSelfLocked) { 2791 this.mPidsSelfLocked.put(startResult.pid, app); 2792 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2793 msg.obj = app; 2794 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2795 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2796 } 2797 } catch (RuntimeException e) { 2798 // XXX do better error recovery. 2799 app.setPid(0); 2800 Slog.e(TAG, "Failure starting process " + app.processName, e); 2801 } 2802 } 2803 2804 void updateUsageStats(ActivityRecord component, boolean resumed) { 2805 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2806 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2807 if (resumed) { 2808 mUsageStatsService.noteResumeComponent(component.realActivity); 2809 synchronized (stats) { 2810 stats.noteActivityResumedLocked(component.app.uid); 2811 } 2812 } else { 2813 mUsageStatsService.notePauseComponent(component.realActivity); 2814 synchronized (stats) { 2815 stats.noteActivityPausedLocked(component.app.uid); 2816 } 2817 } 2818 } 2819 2820 Intent getHomeIntent() { 2821 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2822 intent.setComponent(mTopComponent); 2823 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2824 intent.addCategory(Intent.CATEGORY_HOME); 2825 } 2826 return intent; 2827 } 2828 2829 boolean startHomeActivityLocked(int userId) { 2830 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2831 && mTopAction == null) { 2832 // We are running in factory test mode, but unable to find 2833 // the factory test app, so just sit around displaying the 2834 // error message and don't try to start anything. 2835 return false; 2836 } 2837 Intent intent = getHomeIntent(); 2838 ActivityInfo aInfo = 2839 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2840 if (aInfo != null) { 2841 intent.setComponent(new ComponentName( 2842 aInfo.applicationInfo.packageName, aInfo.name)); 2843 // Don't do this if the home app is currently being 2844 // instrumented. 2845 aInfo = new ActivityInfo(aInfo); 2846 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2847 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2848 aInfo.applicationInfo.uid, true); 2849 if (app == null || app.instrumentationClass == null) { 2850 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2851 mStackSupervisor.startHomeActivity(intent, aInfo); 2852 } 2853 } 2854 2855 return true; 2856 } 2857 2858 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2859 ActivityInfo ai = null; 2860 ComponentName comp = intent.getComponent(); 2861 try { 2862 if (comp != null) { 2863 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2864 } else { 2865 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2866 intent, 2867 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2868 flags, userId); 2869 2870 if (info != null) { 2871 ai = info.activityInfo; 2872 } 2873 } 2874 } catch (RemoteException e) { 2875 // ignore 2876 } 2877 2878 return ai; 2879 } 2880 2881 /** 2882 * Starts the "new version setup screen" if appropriate. 2883 */ 2884 void startSetupActivityLocked() { 2885 // Only do this once per boot. 2886 if (mCheckedForSetup) { 2887 return; 2888 } 2889 2890 // We will show this screen if the current one is a different 2891 // version than the last one shown, and we are not running in 2892 // low-level factory test mode. 2893 final ContentResolver resolver = mContext.getContentResolver(); 2894 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2895 Settings.Global.getInt(resolver, 2896 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2897 mCheckedForSetup = true; 2898 2899 // See if we should be showing the platform update setup UI. 2900 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2901 List<ResolveInfo> ris = mContext.getPackageManager() 2902 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2903 2904 // We don't allow third party apps to replace this. 2905 ResolveInfo ri = null; 2906 for (int i=0; ris != null && i<ris.size(); i++) { 2907 if ((ris.get(i).activityInfo.applicationInfo.flags 2908 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2909 ri = ris.get(i); 2910 break; 2911 } 2912 } 2913 2914 if (ri != null) { 2915 String vers = ri.activityInfo.metaData != null 2916 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2917 : null; 2918 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2919 vers = ri.activityInfo.applicationInfo.metaData.getString( 2920 Intent.METADATA_SETUP_VERSION); 2921 } 2922 String lastVers = Settings.Secure.getString( 2923 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2924 if (vers != null && !vers.equals(lastVers)) { 2925 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2926 intent.setComponent(new ComponentName( 2927 ri.activityInfo.packageName, ri.activityInfo.name)); 2928 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2929 null, null, 0, 0, 0, null, 0, null, false, null, null); 2930 } 2931 } 2932 } 2933 } 2934 2935 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2936 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2937 } 2938 2939 void enforceNotIsolatedCaller(String caller) { 2940 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2941 throw new SecurityException("Isolated process not allowed to call " + caller); 2942 } 2943 } 2944 2945 @Override 2946 public int getFrontActivityScreenCompatMode() { 2947 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2948 synchronized (this) { 2949 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2950 } 2951 } 2952 2953 @Override 2954 public void setFrontActivityScreenCompatMode(int mode) { 2955 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2956 "setFrontActivityScreenCompatMode"); 2957 synchronized (this) { 2958 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2959 } 2960 } 2961 2962 @Override 2963 public int getPackageScreenCompatMode(String packageName) { 2964 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2965 synchronized (this) { 2966 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2967 } 2968 } 2969 2970 @Override 2971 public void setPackageScreenCompatMode(String packageName, int mode) { 2972 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2973 "setPackageScreenCompatMode"); 2974 synchronized (this) { 2975 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2976 } 2977 } 2978 2979 @Override 2980 public boolean getPackageAskScreenCompat(String packageName) { 2981 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2982 synchronized (this) { 2983 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2984 } 2985 } 2986 2987 @Override 2988 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2989 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2990 "setPackageAskScreenCompat"); 2991 synchronized (this) { 2992 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2993 } 2994 } 2995 2996 private void dispatchProcessesChanged() { 2997 int N; 2998 synchronized (this) { 2999 N = mPendingProcessChanges.size(); 3000 if (mActiveProcessChanges.length < N) { 3001 mActiveProcessChanges = new ProcessChangeItem[N]; 3002 } 3003 mPendingProcessChanges.toArray(mActiveProcessChanges); 3004 mAvailProcessChanges.addAll(mPendingProcessChanges); 3005 mPendingProcessChanges.clear(); 3006 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3007 } 3008 3009 int i = mProcessObservers.beginBroadcast(); 3010 while (i > 0) { 3011 i--; 3012 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3013 if (observer != null) { 3014 try { 3015 for (int j=0; j<N; j++) { 3016 ProcessChangeItem item = mActiveProcessChanges[j]; 3017 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3018 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3019 + item.pid + " uid=" + item.uid + ": " 3020 + item.foregroundActivities); 3021 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3022 item.foregroundActivities); 3023 } 3024 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3025 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3026 + item.pid + " uid=" + item.uid + ": " + item.importance); 3027 observer.onImportanceChanged(item.pid, item.uid, 3028 item.importance); 3029 } 3030 } 3031 } catch (RemoteException e) { 3032 } 3033 } 3034 } 3035 mProcessObservers.finishBroadcast(); 3036 } 3037 3038 private void dispatchProcessDied(int pid, int uid) { 3039 int i = mProcessObservers.beginBroadcast(); 3040 while (i > 0) { 3041 i--; 3042 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3043 if (observer != null) { 3044 try { 3045 observer.onProcessDied(pid, uid); 3046 } catch (RemoteException e) { 3047 } 3048 } 3049 } 3050 mProcessObservers.finishBroadcast(); 3051 } 3052 3053 final void doPendingActivityLaunchesLocked(boolean doResume) { 3054 final int N = mPendingActivityLaunches.size(); 3055 if (N <= 0) { 3056 return; 3057 } 3058 for (int i=0; i<N; i++) { 3059 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3060 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3061 doResume && i == (N-1), null); 3062 } 3063 mPendingActivityLaunches.clear(); 3064 } 3065 3066 @Override 3067 public final int startActivity(IApplicationThread caller, String callingPackage, 3068 Intent intent, String resolvedType, IBinder resultTo, 3069 String resultWho, int requestCode, int startFlags, 3070 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3071 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3072 resultWho, requestCode, 3073 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3074 } 3075 3076 @Override 3077 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3078 Intent intent, String resolvedType, IBinder resultTo, 3079 String resultWho, int requestCode, int startFlags, 3080 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3081 enforceNotIsolatedCaller("startActivity"); 3082 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3083 false, true, "startActivity", null); 3084 // TODO: Switch to user app stacks here. 3085 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3086 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3087 null, null, options, userId, null); 3088 } 3089 3090 @Override 3091 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3092 Intent intent, String resolvedType, IBinder resultTo, 3093 String resultWho, int requestCode, int startFlags, String profileFile, 3094 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3095 enforceNotIsolatedCaller("startActivityAndWait"); 3096 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3097 false, true, "startActivityAndWait", null); 3098 WaitResult res = new WaitResult(); 3099 // TODO: Switch to user app stacks here. 3100 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3101 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3102 res, null, options, UserHandle.getCallingUserId(), null); 3103 return res; 3104 } 3105 3106 @Override 3107 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3108 Intent intent, String resolvedType, IBinder resultTo, 3109 String resultWho, int requestCode, int startFlags, Configuration config, 3110 Bundle options, int userId) { 3111 enforceNotIsolatedCaller("startActivityWithConfig"); 3112 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3113 false, true, "startActivityWithConfig", null); 3114 // TODO: Switch to user app stacks here. 3115 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3116 resolvedType, resultTo, resultWho, requestCode, startFlags, 3117 null, null, null, config, options, userId, null); 3118 return ret; 3119 } 3120 3121 @Override 3122 public int startActivityIntentSender(IApplicationThread caller, 3123 IntentSender intent, Intent fillInIntent, String resolvedType, 3124 IBinder resultTo, String resultWho, int requestCode, 3125 int flagsMask, int flagsValues, Bundle options) { 3126 enforceNotIsolatedCaller("startActivityIntentSender"); 3127 // Refuse possible leaked file descriptors 3128 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3129 throw new IllegalArgumentException("File descriptors passed in Intent"); 3130 } 3131 3132 IIntentSender sender = intent.getTarget(); 3133 if (!(sender instanceof PendingIntentRecord)) { 3134 throw new IllegalArgumentException("Bad PendingIntent object"); 3135 } 3136 3137 PendingIntentRecord pir = (PendingIntentRecord)sender; 3138 3139 synchronized (this) { 3140 // If this is coming from the currently resumed activity, it is 3141 // effectively saying that app switches are allowed at this point. 3142 final ActivityStack stack = getFocusedStack(); 3143 if (stack.mResumedActivity != null && 3144 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3145 mAppSwitchesAllowedTime = 0; 3146 } 3147 } 3148 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3149 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3150 return ret; 3151 } 3152 3153 @Override 3154 public boolean startNextMatchingActivity(IBinder callingActivity, 3155 Intent intent, Bundle options) { 3156 // Refuse possible leaked file descriptors 3157 if (intent != null && intent.hasFileDescriptors() == true) { 3158 throw new IllegalArgumentException("File descriptors passed in Intent"); 3159 } 3160 3161 synchronized (this) { 3162 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3163 if (r == null) { 3164 ActivityOptions.abort(options); 3165 return false; 3166 } 3167 if (r.app == null || r.app.thread == null) { 3168 // The caller is not running... d'oh! 3169 ActivityOptions.abort(options); 3170 return false; 3171 } 3172 intent = new Intent(intent); 3173 // The caller is not allowed to change the data. 3174 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3175 // And we are resetting to find the next component... 3176 intent.setComponent(null); 3177 3178 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3179 3180 ActivityInfo aInfo = null; 3181 try { 3182 List<ResolveInfo> resolves = 3183 AppGlobals.getPackageManager().queryIntentActivities( 3184 intent, r.resolvedType, 3185 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3186 UserHandle.getCallingUserId()); 3187 3188 // Look for the original activity in the list... 3189 final int N = resolves != null ? resolves.size() : 0; 3190 for (int i=0; i<N; i++) { 3191 ResolveInfo rInfo = resolves.get(i); 3192 if (rInfo.activityInfo.packageName.equals(r.packageName) 3193 && rInfo.activityInfo.name.equals(r.info.name)) { 3194 // We found the current one... the next matching is 3195 // after it. 3196 i++; 3197 if (i<N) { 3198 aInfo = resolves.get(i).activityInfo; 3199 } 3200 if (debug) { 3201 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3202 + "/" + r.info.name); 3203 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3204 + "/" + aInfo.name); 3205 } 3206 break; 3207 } 3208 } 3209 } catch (RemoteException e) { 3210 } 3211 3212 if (aInfo == null) { 3213 // Nobody who is next! 3214 ActivityOptions.abort(options); 3215 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3216 return false; 3217 } 3218 3219 intent.setComponent(new ComponentName( 3220 aInfo.applicationInfo.packageName, aInfo.name)); 3221 intent.setFlags(intent.getFlags()&~( 3222 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3223 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3224 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3225 Intent.FLAG_ACTIVITY_NEW_TASK)); 3226 3227 // Okay now we need to start the new activity, replacing the 3228 // currently running activity. This is a little tricky because 3229 // we want to start the new one as if the current one is finished, 3230 // but not finish the current one first so that there is no flicker. 3231 // And thus... 3232 final boolean wasFinishing = r.finishing; 3233 r.finishing = true; 3234 3235 // Propagate reply information over to the new activity. 3236 final ActivityRecord resultTo = r.resultTo; 3237 final String resultWho = r.resultWho; 3238 final int requestCode = r.requestCode; 3239 r.resultTo = null; 3240 if (resultTo != null) { 3241 resultTo.removeResultsLocked(r, resultWho, requestCode); 3242 } 3243 3244 final long origId = Binder.clearCallingIdentity(); 3245 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3246 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3247 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3248 options, false, null, null); 3249 Binder.restoreCallingIdentity(origId); 3250 3251 r.finishing = wasFinishing; 3252 if (res != ActivityManager.START_SUCCESS) { 3253 return false; 3254 } 3255 return true; 3256 } 3257 } 3258 3259 final int startActivityInPackage(int uid, String callingPackage, 3260 Intent intent, String resolvedType, IBinder resultTo, 3261 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3262 IActivityContainer container) { 3263 3264 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3265 false, true, "startActivityInPackage", null); 3266 3267 // TODO: Switch to user app stacks here. 3268 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3269 resultTo, resultWho, requestCode, startFlags, 3270 null, null, null, null, options, userId, container); 3271 return ret; 3272 } 3273 3274 @Override 3275 public final int startActivities(IApplicationThread caller, String callingPackage, 3276 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3277 int userId) { 3278 enforceNotIsolatedCaller("startActivities"); 3279 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3280 false, true, "startActivity", null); 3281 // TODO: Switch to user app stacks here. 3282 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3283 resolvedTypes, resultTo, options, userId); 3284 return ret; 3285 } 3286 3287 final int startActivitiesInPackage(int uid, String callingPackage, 3288 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3289 Bundle options, int userId) { 3290 3291 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3292 false, true, "startActivityInPackage", null); 3293 // TODO: Switch to user app stacks here. 3294 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3295 resultTo, options, userId); 3296 return ret; 3297 } 3298 3299 final void addRecentTaskLocked(TaskRecord task) { 3300 int N = mRecentTasks.size(); 3301 // Quick case: check if the top-most recent task is the same. 3302 if (N > 0 && mRecentTasks.get(0) == task) { 3303 return; 3304 } 3305 // Remove any existing entries that are the same kind of task. 3306 for (int i=0; i<N; i++) { 3307 TaskRecord tr = mRecentTasks.get(i); 3308 if (task.userId == tr.userId 3309 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 3310 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 3311 tr.disposeThumbnail(); 3312 mRecentTasks.remove(i); 3313 i--; 3314 N--; 3315 if (task.intent == null) { 3316 // If the new recent task we are adding is not fully 3317 // specified, then replace it with the existing recent task. 3318 task = tr; 3319 } 3320 } 3321 } 3322 if (N >= MAX_RECENT_TASKS) { 3323 mRecentTasks.remove(N-1).disposeThumbnail(); 3324 } 3325 mRecentTasks.add(0, task); 3326 } 3327 3328 @Override 3329 public void reportActivityFullyDrawn(IBinder token) { 3330 synchronized (this) { 3331 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3332 if (r == null) { 3333 return; 3334 } 3335 r.reportFullyDrawnLocked(); 3336 } 3337 } 3338 3339 @Override 3340 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3341 synchronized (this) { 3342 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3343 if (r == null) { 3344 return; 3345 } 3346 final long origId = Binder.clearCallingIdentity(); 3347 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3348 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3349 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3350 if (config != null) { 3351 r.frozenBeforeDestroy = true; 3352 if (!updateConfigurationLocked(config, r, false, false)) { 3353 mStackSupervisor.resumeTopActivitiesLocked(); 3354 } 3355 } 3356 Binder.restoreCallingIdentity(origId); 3357 } 3358 } 3359 3360 @Override 3361 public int getRequestedOrientation(IBinder token) { 3362 synchronized (this) { 3363 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3364 if (r == null) { 3365 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3366 } 3367 return mWindowManager.getAppOrientation(r.appToken); 3368 } 3369 } 3370 3371 /** 3372 * This is the internal entry point for handling Activity.finish(). 3373 * 3374 * @param token The Binder token referencing the Activity we want to finish. 3375 * @param resultCode Result code, if any, from this Activity. 3376 * @param resultData Result data (Intent), if any, from this Activity. 3377 * 3378 * @return Returns true if the activity successfully finished, or false if it is still running. 3379 */ 3380 @Override 3381 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3382 // Refuse possible leaked file descriptors 3383 if (resultData != null && resultData.hasFileDescriptors() == true) { 3384 throw new IllegalArgumentException("File descriptors passed in Intent"); 3385 } 3386 3387 synchronized(this) { 3388 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3389 if (r == null) { 3390 return true; 3391 } 3392 if (mController != null) { 3393 // Find the first activity that is not finishing. 3394 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3395 if (next != null) { 3396 // ask watcher if this is allowed 3397 boolean resumeOK = true; 3398 try { 3399 resumeOK = mController.activityResuming(next.packageName); 3400 } catch (RemoteException e) { 3401 mController = null; 3402 Watchdog.getInstance().setActivityController(null); 3403 } 3404 3405 if (!resumeOK) { 3406 return false; 3407 } 3408 } 3409 } 3410 final long origId = Binder.clearCallingIdentity(); 3411 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3412 resultData, "app-request", true); 3413 Binder.restoreCallingIdentity(origId); 3414 return res; 3415 } 3416 } 3417 3418 @Override 3419 public final void finishHeavyWeightApp() { 3420 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3421 != PackageManager.PERMISSION_GRANTED) { 3422 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3423 + Binder.getCallingPid() 3424 + ", uid=" + Binder.getCallingUid() 3425 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3426 Slog.w(TAG, msg); 3427 throw new SecurityException(msg); 3428 } 3429 3430 synchronized(this) { 3431 if (mHeavyWeightProcess == null) { 3432 return; 3433 } 3434 3435 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3436 mHeavyWeightProcess.activities); 3437 for (int i=0; i<activities.size(); i++) { 3438 ActivityRecord r = activities.get(i); 3439 if (!r.finishing) { 3440 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3441 null, "finish-heavy", true); 3442 } 3443 } 3444 3445 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3446 mHeavyWeightProcess.userId, 0)); 3447 mHeavyWeightProcess = null; 3448 } 3449 } 3450 3451 @Override 3452 public void crashApplication(int uid, int initialPid, String packageName, 3453 String message) { 3454 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3455 != PackageManager.PERMISSION_GRANTED) { 3456 String msg = "Permission Denial: crashApplication() from pid=" 3457 + Binder.getCallingPid() 3458 + ", uid=" + Binder.getCallingUid() 3459 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3460 Slog.w(TAG, msg); 3461 throw new SecurityException(msg); 3462 } 3463 3464 synchronized(this) { 3465 ProcessRecord proc = null; 3466 3467 // Figure out which process to kill. We don't trust that initialPid 3468 // still has any relation to current pids, so must scan through the 3469 // list. 3470 synchronized (mPidsSelfLocked) { 3471 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3472 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3473 if (p.uid != uid) { 3474 continue; 3475 } 3476 if (p.pid == initialPid) { 3477 proc = p; 3478 break; 3479 } 3480 if (p.pkgList.containsKey(packageName)) { 3481 proc = p; 3482 } 3483 } 3484 } 3485 3486 if (proc == null) { 3487 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3488 + " initialPid=" + initialPid 3489 + " packageName=" + packageName); 3490 return; 3491 } 3492 3493 if (proc.thread != null) { 3494 if (proc.pid == Process.myPid()) { 3495 Log.w(TAG, "crashApplication: trying to crash self!"); 3496 return; 3497 } 3498 long ident = Binder.clearCallingIdentity(); 3499 try { 3500 proc.thread.scheduleCrash(message); 3501 } catch (RemoteException e) { 3502 } 3503 Binder.restoreCallingIdentity(ident); 3504 } 3505 } 3506 } 3507 3508 @Override 3509 public final void finishSubActivity(IBinder token, String resultWho, 3510 int requestCode) { 3511 synchronized(this) { 3512 final long origId = Binder.clearCallingIdentity(); 3513 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3514 if (r != null) { 3515 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3516 } 3517 Binder.restoreCallingIdentity(origId); 3518 } 3519 } 3520 3521 @Override 3522 public boolean finishActivityAffinity(IBinder token) { 3523 synchronized(this) { 3524 final long origId = Binder.clearCallingIdentity(); 3525 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3526 boolean res = false; 3527 if (r != null) { 3528 res = r.task.stack.finishActivityAffinityLocked(r); 3529 } 3530 Binder.restoreCallingIdentity(origId); 3531 return res; 3532 } 3533 } 3534 3535 @Override 3536 public boolean willActivityBeVisible(IBinder token) { 3537 synchronized(this) { 3538 ActivityStack stack = ActivityRecord.getStackLocked(token); 3539 if (stack != null) { 3540 return stack.willActivityBeVisibleLocked(token); 3541 } 3542 return false; 3543 } 3544 } 3545 3546 @Override 3547 public void overridePendingTransition(IBinder token, String packageName, 3548 int enterAnim, int exitAnim) { 3549 synchronized(this) { 3550 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3551 if (self == null) { 3552 return; 3553 } 3554 3555 final long origId = Binder.clearCallingIdentity(); 3556 3557 if (self.state == ActivityState.RESUMED 3558 || self.state == ActivityState.PAUSING) { 3559 mWindowManager.overridePendingAppTransition(packageName, 3560 enterAnim, exitAnim, null); 3561 } 3562 3563 Binder.restoreCallingIdentity(origId); 3564 } 3565 } 3566 3567 /** 3568 * Main function for removing an existing process from the activity manager 3569 * as a result of that process going away. Clears out all connections 3570 * to the process. 3571 */ 3572 private final void handleAppDiedLocked(ProcessRecord app, 3573 boolean restarting, boolean allowRestart) { 3574 int pid = app.pid; 3575 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3576 if (!restarting) { 3577 removeLruProcessLocked(app); 3578 if (pid > 0) { 3579 ProcessList.remove(pid); 3580 } 3581 } 3582 3583 if (mProfileProc == app) { 3584 clearProfilerLocked(); 3585 } 3586 3587 // Remove this application's activities from active lists. 3588 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3589 3590 app.activities.clear(); 3591 3592 if (app.instrumentationClass != null) { 3593 Slog.w(TAG, "Crash of app " + app.processName 3594 + " running instrumentation " + app.instrumentationClass); 3595 Bundle info = new Bundle(); 3596 info.putString("shortMsg", "Process crashed."); 3597 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3598 } 3599 3600 if (!restarting) { 3601 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3602 // If there was nothing to resume, and we are not already 3603 // restarting this process, but there is a visible activity that 3604 // is hosted by the process... then make sure all visible 3605 // activities are running, taking care of restarting this 3606 // process. 3607 if (hasVisibleActivities) { 3608 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3609 } 3610 } 3611 } 3612 } 3613 3614 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3615 IBinder threadBinder = thread.asBinder(); 3616 // Find the application record. 3617 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3618 ProcessRecord rec = mLruProcesses.get(i); 3619 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3620 return i; 3621 } 3622 } 3623 return -1; 3624 } 3625 3626 final ProcessRecord getRecordForAppLocked( 3627 IApplicationThread thread) { 3628 if (thread == null) { 3629 return null; 3630 } 3631 3632 int appIndex = getLRURecordIndexForAppLocked(thread); 3633 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3634 } 3635 3636 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3637 // If there are no longer any background processes running, 3638 // and the app that died was not running instrumentation, 3639 // then tell everyone we are now low on memory. 3640 boolean haveBg = false; 3641 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3642 ProcessRecord rec = mLruProcesses.get(i); 3643 if (rec.thread != null 3644 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3645 haveBg = true; 3646 break; 3647 } 3648 } 3649 3650 if (!haveBg) { 3651 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3652 if (doReport) { 3653 long now = SystemClock.uptimeMillis(); 3654 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3655 doReport = false; 3656 } else { 3657 mLastMemUsageReportTime = now; 3658 } 3659 } 3660 final ArrayList<ProcessMemInfo> memInfos 3661 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3662 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3663 long now = SystemClock.uptimeMillis(); 3664 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3665 ProcessRecord rec = mLruProcesses.get(i); 3666 if (rec == dyingProc || rec.thread == null) { 3667 continue; 3668 } 3669 if (doReport) { 3670 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3671 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3672 } 3673 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3674 // The low memory report is overriding any current 3675 // state for a GC request. Make sure to do 3676 // heavy/important/visible/foreground processes first. 3677 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3678 rec.lastRequestedGc = 0; 3679 } else { 3680 rec.lastRequestedGc = rec.lastLowMemory; 3681 } 3682 rec.reportLowMemory = true; 3683 rec.lastLowMemory = now; 3684 mProcessesToGc.remove(rec); 3685 addProcessToGcListLocked(rec); 3686 } 3687 } 3688 if (doReport) { 3689 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3690 mHandler.sendMessage(msg); 3691 } 3692 scheduleAppGcsLocked(); 3693 } 3694 } 3695 3696 final void appDiedLocked(ProcessRecord app, int pid, 3697 IApplicationThread thread) { 3698 3699 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3700 synchronized (stats) { 3701 stats.noteProcessDiedLocked(app.info.uid, pid); 3702 } 3703 3704 // Clean up already done if the process has been re-started. 3705 if (app.pid == pid && app.thread != null && 3706 app.thread.asBinder() == thread.asBinder()) { 3707 boolean doLowMem = app.instrumentationClass == null; 3708 boolean doOomAdj = doLowMem; 3709 if (!app.killedByAm) { 3710 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3711 + ") has died."); 3712 mAllowLowerMemLevel = true; 3713 } else { 3714 // Note that we always want to do oom adj to update our state with the 3715 // new number of procs. 3716 mAllowLowerMemLevel = false; 3717 doLowMem = false; 3718 } 3719 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3720 if (DEBUG_CLEANUP) Slog.v( 3721 TAG, "Dying app: " + app + ", pid: " + pid 3722 + ", thread: " + thread.asBinder()); 3723 handleAppDiedLocked(app, false, true); 3724 3725 if (doOomAdj) { 3726 updateOomAdjLocked(); 3727 } 3728 if (doLowMem) { 3729 doLowMemReportIfNeededLocked(app); 3730 } 3731 } else if (app.pid != pid) { 3732 // A new process has already been started. 3733 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3734 + ") has died and restarted (pid " + app.pid + ")."); 3735 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3736 } else if (DEBUG_PROCESSES) { 3737 Slog.d(TAG, "Received spurious death notification for thread " 3738 + thread.asBinder()); 3739 } 3740 } 3741 3742 /** 3743 * If a stack trace dump file is configured, dump process stack traces. 3744 * @param clearTraces causes the dump file to be erased prior to the new 3745 * traces being written, if true; when false, the new traces will be 3746 * appended to any existing file content. 3747 * @param firstPids of dalvik VM processes to dump stack traces for first 3748 * @param lastPids of dalvik VM processes to dump stack traces for last 3749 * @param nativeProcs optional list of native process names to dump stack crawls 3750 * @return file containing stack traces, or null if no dump file is configured 3751 */ 3752 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3753 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3754 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3755 if (tracesPath == null || tracesPath.length() == 0) { 3756 return null; 3757 } 3758 3759 File tracesFile = new File(tracesPath); 3760 try { 3761 File tracesDir = tracesFile.getParentFile(); 3762 if (!tracesDir.exists()) { 3763 tracesFile.mkdirs(); 3764 if (!SELinux.restorecon(tracesDir)) { 3765 return null; 3766 } 3767 } 3768 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3769 3770 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3771 tracesFile.createNewFile(); 3772 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3773 } catch (IOException e) { 3774 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3775 return null; 3776 } 3777 3778 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3779 return tracesFile; 3780 } 3781 3782 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3783 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3784 // Use a FileObserver to detect when traces finish writing. 3785 // The order of traces is considered important to maintain for legibility. 3786 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3787 @Override 3788 public synchronized void onEvent(int event, String path) { notify(); } 3789 }; 3790 3791 try { 3792 observer.startWatching(); 3793 3794 // First collect all of the stacks of the most important pids. 3795 if (firstPids != null) { 3796 try { 3797 int num = firstPids.size(); 3798 for (int i = 0; i < num; i++) { 3799 synchronized (observer) { 3800 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3801 observer.wait(200); // Wait for write-close, give up after 200msec 3802 } 3803 } 3804 } catch (InterruptedException e) { 3805 Log.wtf(TAG, e); 3806 } 3807 } 3808 3809 // Next collect the stacks of the native pids 3810 if (nativeProcs != null) { 3811 int[] pids = Process.getPidsForCommands(nativeProcs); 3812 if (pids != null) { 3813 for (int pid : pids) { 3814 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3815 } 3816 } 3817 } 3818 3819 // Lastly, measure CPU usage. 3820 if (processCpuTracker != null) { 3821 processCpuTracker.init(); 3822 System.gc(); 3823 processCpuTracker.update(); 3824 try { 3825 synchronized (processCpuTracker) { 3826 processCpuTracker.wait(500); // measure over 1/2 second. 3827 } 3828 } catch (InterruptedException e) { 3829 } 3830 processCpuTracker.update(); 3831 3832 // We'll take the stack crawls of just the top apps using CPU. 3833 final int N = processCpuTracker.countWorkingStats(); 3834 int numProcs = 0; 3835 for (int i=0; i<N && numProcs<5; i++) { 3836 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3837 if (lastPids.indexOfKey(stats.pid) >= 0) { 3838 numProcs++; 3839 try { 3840 synchronized (observer) { 3841 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3842 observer.wait(200); // Wait for write-close, give up after 200msec 3843 } 3844 } catch (InterruptedException e) { 3845 Log.wtf(TAG, e); 3846 } 3847 3848 } 3849 } 3850 } 3851 } finally { 3852 observer.stopWatching(); 3853 } 3854 } 3855 3856 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3857 if (true || IS_USER_BUILD) { 3858 return; 3859 } 3860 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3861 if (tracesPath == null || tracesPath.length() == 0) { 3862 return; 3863 } 3864 3865 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3866 StrictMode.allowThreadDiskWrites(); 3867 try { 3868 final File tracesFile = new File(tracesPath); 3869 final File tracesDir = tracesFile.getParentFile(); 3870 final File tracesTmp = new File(tracesDir, "__tmp__"); 3871 try { 3872 if (!tracesDir.exists()) { 3873 tracesFile.mkdirs(); 3874 if (!SELinux.restorecon(tracesDir.getPath())) { 3875 return; 3876 } 3877 } 3878 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3879 3880 if (tracesFile.exists()) { 3881 tracesTmp.delete(); 3882 tracesFile.renameTo(tracesTmp); 3883 } 3884 StringBuilder sb = new StringBuilder(); 3885 Time tobj = new Time(); 3886 tobj.set(System.currentTimeMillis()); 3887 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3888 sb.append(": "); 3889 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3890 sb.append(" since "); 3891 sb.append(msg); 3892 FileOutputStream fos = new FileOutputStream(tracesFile); 3893 fos.write(sb.toString().getBytes()); 3894 if (app == null) { 3895 fos.write("\n*** No application process!".getBytes()); 3896 } 3897 fos.close(); 3898 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3899 } catch (IOException e) { 3900 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3901 return; 3902 } 3903 3904 if (app != null) { 3905 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3906 firstPids.add(app.pid); 3907 dumpStackTraces(tracesPath, firstPids, null, null, null); 3908 } 3909 3910 File lastTracesFile = null; 3911 File curTracesFile = null; 3912 for (int i=9; i>=0; i--) { 3913 String name = String.format(Locale.US, "slow%02d.txt", i); 3914 curTracesFile = new File(tracesDir, name); 3915 if (curTracesFile.exists()) { 3916 if (lastTracesFile != null) { 3917 curTracesFile.renameTo(lastTracesFile); 3918 } else { 3919 curTracesFile.delete(); 3920 } 3921 } 3922 lastTracesFile = curTracesFile; 3923 } 3924 tracesFile.renameTo(curTracesFile); 3925 if (tracesTmp.exists()) { 3926 tracesTmp.renameTo(tracesFile); 3927 } 3928 } finally { 3929 StrictMode.setThreadPolicy(oldPolicy); 3930 } 3931 } 3932 3933 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3934 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3935 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3936 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3937 3938 if (mController != null) { 3939 try { 3940 // 0 == continue, -1 = kill process immediately 3941 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3942 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3943 } catch (RemoteException e) { 3944 mController = null; 3945 Watchdog.getInstance().setActivityController(null); 3946 } 3947 } 3948 3949 long anrTime = SystemClock.uptimeMillis(); 3950 if (MONITOR_CPU_USAGE) { 3951 updateCpuStatsNow(); 3952 } 3953 3954 synchronized (this) { 3955 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3956 if (mShuttingDown) { 3957 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3958 return; 3959 } else if (app.notResponding) { 3960 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3961 return; 3962 } else if (app.crashing) { 3963 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3964 return; 3965 } 3966 3967 // In case we come through here for the same app before completing 3968 // this one, mark as anring now so we will bail out. 3969 app.notResponding = true; 3970 3971 // Log the ANR to the event log. 3972 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3973 app.processName, app.info.flags, annotation); 3974 3975 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3976 firstPids.add(app.pid); 3977 3978 int parentPid = app.pid; 3979 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3980 if (parentPid != app.pid) firstPids.add(parentPid); 3981 3982 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3983 3984 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3985 ProcessRecord r = mLruProcesses.get(i); 3986 if (r != null && r.thread != null) { 3987 int pid = r.pid; 3988 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3989 if (r.persistent) { 3990 firstPids.add(pid); 3991 } else { 3992 lastPids.put(pid, Boolean.TRUE); 3993 } 3994 } 3995 } 3996 } 3997 } 3998 3999 // Log the ANR to the main log. 4000 StringBuilder info = new StringBuilder(); 4001 info.setLength(0); 4002 info.append("ANR in ").append(app.processName); 4003 if (activity != null && activity.shortComponentName != null) { 4004 info.append(" (").append(activity.shortComponentName).append(")"); 4005 } 4006 info.append("\n"); 4007 info.append("PID: ").append(app.pid).append("\n"); 4008 if (annotation != null) { 4009 info.append("Reason: ").append(annotation).append("\n"); 4010 } 4011 if (parent != null && parent != activity) { 4012 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4013 } 4014 4015 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4016 4017 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4018 NATIVE_STACKS_OF_INTEREST); 4019 4020 String cpuInfo = null; 4021 if (MONITOR_CPU_USAGE) { 4022 updateCpuStatsNow(); 4023 synchronized (mProcessCpuThread) { 4024 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4025 } 4026 info.append(processCpuTracker.printCurrentLoad()); 4027 info.append(cpuInfo); 4028 } 4029 4030 info.append(processCpuTracker.printCurrentState(anrTime)); 4031 4032 Slog.e(TAG, info.toString()); 4033 if (tracesFile == null) { 4034 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4035 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4036 } 4037 4038 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4039 cpuInfo, tracesFile, null); 4040 4041 if (mController != null) { 4042 try { 4043 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4044 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4045 if (res != 0) { 4046 if (res < 0 && app.pid != MY_PID) { 4047 Process.killProcess(app.pid); 4048 } else { 4049 synchronized (this) { 4050 mServices.scheduleServiceTimeoutLocked(app); 4051 } 4052 } 4053 return; 4054 } 4055 } catch (RemoteException e) { 4056 mController = null; 4057 Watchdog.getInstance().setActivityController(null); 4058 } 4059 } 4060 4061 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4062 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4063 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4064 4065 synchronized (this) { 4066 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4067 killUnneededProcessLocked(app, "background ANR"); 4068 return; 4069 } 4070 4071 // Set the app's notResponding state, and look up the errorReportReceiver 4072 makeAppNotRespondingLocked(app, 4073 activity != null ? activity.shortComponentName : null, 4074 annotation != null ? "ANR " + annotation : "ANR", 4075 info.toString()); 4076 4077 // Bring up the infamous App Not Responding dialog 4078 Message msg = Message.obtain(); 4079 HashMap<String, Object> map = new HashMap<String, Object>(); 4080 msg.what = SHOW_NOT_RESPONDING_MSG; 4081 msg.obj = map; 4082 msg.arg1 = aboveSystem ? 1 : 0; 4083 map.put("app", app); 4084 if (activity != null) { 4085 map.put("activity", activity); 4086 } 4087 4088 mHandler.sendMessage(msg); 4089 } 4090 } 4091 4092 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4093 if (!mLaunchWarningShown) { 4094 mLaunchWarningShown = true; 4095 mHandler.post(new Runnable() { 4096 @Override 4097 public void run() { 4098 synchronized (ActivityManagerService.this) { 4099 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4100 d.show(); 4101 mHandler.postDelayed(new Runnable() { 4102 @Override 4103 public void run() { 4104 synchronized (ActivityManagerService.this) { 4105 d.dismiss(); 4106 mLaunchWarningShown = false; 4107 } 4108 } 4109 }, 4000); 4110 } 4111 } 4112 }); 4113 } 4114 } 4115 4116 @Override 4117 public boolean clearApplicationUserData(final String packageName, 4118 final IPackageDataObserver observer, int userId) { 4119 enforceNotIsolatedCaller("clearApplicationUserData"); 4120 int uid = Binder.getCallingUid(); 4121 int pid = Binder.getCallingPid(); 4122 userId = handleIncomingUser(pid, uid, 4123 userId, false, true, "clearApplicationUserData", null); 4124 long callingId = Binder.clearCallingIdentity(); 4125 try { 4126 IPackageManager pm = AppGlobals.getPackageManager(); 4127 int pkgUid = -1; 4128 synchronized(this) { 4129 try { 4130 pkgUid = pm.getPackageUid(packageName, userId); 4131 } catch (RemoteException e) { 4132 } 4133 if (pkgUid == -1) { 4134 Slog.w(TAG, "Invalid packageName: " + packageName); 4135 if (observer != null) { 4136 try { 4137 observer.onRemoveCompleted(packageName, false); 4138 } catch (RemoteException e) { 4139 Slog.i(TAG, "Observer no longer exists."); 4140 } 4141 } 4142 return false; 4143 } 4144 if (uid == pkgUid || checkComponentPermission( 4145 android.Manifest.permission.CLEAR_APP_USER_DATA, 4146 pid, uid, -1, true) 4147 == PackageManager.PERMISSION_GRANTED) { 4148 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4149 } else { 4150 throw new SecurityException("PID " + pid + " does not have permission " 4151 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4152 + " of package " + packageName); 4153 } 4154 } 4155 4156 try { 4157 // Clear application user data 4158 pm.clearApplicationUserData(packageName, observer, userId); 4159 4160 // Remove all permissions granted from/to this package 4161 removeUriPermissionsForPackageLocked(packageName, userId, true); 4162 4163 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4164 Uri.fromParts("package", packageName, null)); 4165 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4166 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4167 null, null, 0, null, null, null, false, false, userId); 4168 } catch (RemoteException e) { 4169 } 4170 } finally { 4171 Binder.restoreCallingIdentity(callingId); 4172 } 4173 return true; 4174 } 4175 4176 @Override 4177 public void killBackgroundProcesses(final String packageName, int userId) { 4178 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4179 != PackageManager.PERMISSION_GRANTED && 4180 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4181 != PackageManager.PERMISSION_GRANTED) { 4182 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4183 + Binder.getCallingPid() 4184 + ", uid=" + Binder.getCallingUid() 4185 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4186 Slog.w(TAG, msg); 4187 throw new SecurityException(msg); 4188 } 4189 4190 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4191 userId, true, true, "killBackgroundProcesses", null); 4192 long callingId = Binder.clearCallingIdentity(); 4193 try { 4194 IPackageManager pm = AppGlobals.getPackageManager(); 4195 synchronized(this) { 4196 int appId = -1; 4197 try { 4198 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4199 } catch (RemoteException e) { 4200 } 4201 if (appId == -1) { 4202 Slog.w(TAG, "Invalid packageName: " + packageName); 4203 return; 4204 } 4205 killPackageProcessesLocked(packageName, appId, userId, 4206 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4207 } 4208 } finally { 4209 Binder.restoreCallingIdentity(callingId); 4210 } 4211 } 4212 4213 @Override 4214 public void killAllBackgroundProcesses() { 4215 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4216 != PackageManager.PERMISSION_GRANTED) { 4217 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4218 + Binder.getCallingPid() 4219 + ", uid=" + Binder.getCallingUid() 4220 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4221 Slog.w(TAG, msg); 4222 throw new SecurityException(msg); 4223 } 4224 4225 long callingId = Binder.clearCallingIdentity(); 4226 try { 4227 synchronized(this) { 4228 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4229 final int NP = mProcessNames.getMap().size(); 4230 for (int ip=0; ip<NP; ip++) { 4231 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4232 final int NA = apps.size(); 4233 for (int ia=0; ia<NA; ia++) { 4234 ProcessRecord app = apps.valueAt(ia); 4235 if (app.persistent) { 4236 // we don't kill persistent processes 4237 continue; 4238 } 4239 if (app.removed) { 4240 procs.add(app); 4241 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4242 app.removed = true; 4243 procs.add(app); 4244 } 4245 } 4246 } 4247 4248 int N = procs.size(); 4249 for (int i=0; i<N; i++) { 4250 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4251 } 4252 mAllowLowerMemLevel = true; 4253 updateOomAdjLocked(); 4254 doLowMemReportIfNeededLocked(null); 4255 } 4256 } finally { 4257 Binder.restoreCallingIdentity(callingId); 4258 } 4259 } 4260 4261 @Override 4262 public void forceStopPackage(final String packageName, int userId) { 4263 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4264 != PackageManager.PERMISSION_GRANTED) { 4265 String msg = "Permission Denial: forceStopPackage() from pid=" 4266 + Binder.getCallingPid() 4267 + ", uid=" + Binder.getCallingUid() 4268 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4269 Slog.w(TAG, msg); 4270 throw new SecurityException(msg); 4271 } 4272 final int callingPid = Binder.getCallingPid(); 4273 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4274 userId, true, true, "forceStopPackage", null); 4275 long callingId = Binder.clearCallingIdentity(); 4276 try { 4277 IPackageManager pm = AppGlobals.getPackageManager(); 4278 synchronized(this) { 4279 int[] users = userId == UserHandle.USER_ALL 4280 ? getUsersLocked() : new int[] { userId }; 4281 for (int user : users) { 4282 int pkgUid = -1; 4283 try { 4284 pkgUid = pm.getPackageUid(packageName, user); 4285 } catch (RemoteException e) { 4286 } 4287 if (pkgUid == -1) { 4288 Slog.w(TAG, "Invalid packageName: " + packageName); 4289 continue; 4290 } 4291 try { 4292 pm.setPackageStoppedState(packageName, true, user); 4293 } catch (RemoteException e) { 4294 } catch (IllegalArgumentException e) { 4295 Slog.w(TAG, "Failed trying to unstop package " 4296 + packageName + ": " + e); 4297 } 4298 if (isUserRunningLocked(user, false)) { 4299 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4300 } 4301 } 4302 } 4303 } finally { 4304 Binder.restoreCallingIdentity(callingId); 4305 } 4306 } 4307 4308 /* 4309 * The pkg name and app id have to be specified. 4310 */ 4311 @Override 4312 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4313 if (pkg == null) { 4314 return; 4315 } 4316 // Make sure the uid is valid. 4317 if (appid < 0) { 4318 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4319 return; 4320 } 4321 int callerUid = Binder.getCallingUid(); 4322 // Only the system server can kill an application 4323 if (callerUid == Process.SYSTEM_UID) { 4324 // Post an aysnc message to kill the application 4325 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4326 msg.arg1 = appid; 4327 msg.arg2 = 0; 4328 Bundle bundle = new Bundle(); 4329 bundle.putString("pkg", pkg); 4330 bundle.putString("reason", reason); 4331 msg.obj = bundle; 4332 mHandler.sendMessage(msg); 4333 } else { 4334 throw new SecurityException(callerUid + " cannot kill pkg: " + 4335 pkg); 4336 } 4337 } 4338 4339 @Override 4340 public void closeSystemDialogs(String reason) { 4341 enforceNotIsolatedCaller("closeSystemDialogs"); 4342 4343 final int pid = Binder.getCallingPid(); 4344 final int uid = Binder.getCallingUid(); 4345 final long origId = Binder.clearCallingIdentity(); 4346 try { 4347 synchronized (this) { 4348 // Only allow this from foreground processes, so that background 4349 // applications can't abuse it to prevent system UI from being shown. 4350 if (uid >= Process.FIRST_APPLICATION_UID) { 4351 ProcessRecord proc; 4352 synchronized (mPidsSelfLocked) { 4353 proc = mPidsSelfLocked.get(pid); 4354 } 4355 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4356 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4357 + " from background process " + proc); 4358 return; 4359 } 4360 } 4361 closeSystemDialogsLocked(reason); 4362 } 4363 } finally { 4364 Binder.restoreCallingIdentity(origId); 4365 } 4366 } 4367 4368 void closeSystemDialogsLocked(String reason) { 4369 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4370 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4371 | Intent.FLAG_RECEIVER_FOREGROUND); 4372 if (reason != null) { 4373 intent.putExtra("reason", reason); 4374 } 4375 mWindowManager.closeSystemDialogs(reason); 4376 4377 mStackSupervisor.closeSystemDialogsLocked(); 4378 4379 broadcastIntentLocked(null, null, intent, null, 4380 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4381 Process.SYSTEM_UID, UserHandle.USER_ALL); 4382 } 4383 4384 @Override 4385 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4386 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4387 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4388 for (int i=pids.length-1; i>=0; i--) { 4389 ProcessRecord proc; 4390 int oomAdj; 4391 synchronized (this) { 4392 synchronized (mPidsSelfLocked) { 4393 proc = mPidsSelfLocked.get(pids[i]); 4394 oomAdj = proc != null ? proc.setAdj : 0; 4395 } 4396 } 4397 infos[i] = new Debug.MemoryInfo(); 4398 Debug.getMemoryInfo(pids[i], infos[i]); 4399 if (proc != null) { 4400 synchronized (this) { 4401 if (proc.thread != null && proc.setAdj == oomAdj) { 4402 // Record this for posterity if the process has been stable. 4403 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4404 infos[i].getTotalUss(), false, proc.pkgList); 4405 } 4406 } 4407 } 4408 } 4409 return infos; 4410 } 4411 4412 @Override 4413 public long[] getProcessPss(int[] pids) { 4414 enforceNotIsolatedCaller("getProcessPss"); 4415 long[] pss = new long[pids.length]; 4416 for (int i=pids.length-1; i>=0; i--) { 4417 ProcessRecord proc; 4418 int oomAdj; 4419 synchronized (this) { 4420 synchronized (mPidsSelfLocked) { 4421 proc = mPidsSelfLocked.get(pids[i]); 4422 oomAdj = proc != null ? proc.setAdj : 0; 4423 } 4424 } 4425 long[] tmpUss = new long[1]; 4426 pss[i] = Debug.getPss(pids[i], tmpUss); 4427 if (proc != null) { 4428 synchronized (this) { 4429 if (proc.thread != null && proc.setAdj == oomAdj) { 4430 // Record this for posterity if the process has been stable. 4431 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4432 } 4433 } 4434 } 4435 } 4436 return pss; 4437 } 4438 4439 @Override 4440 public void killApplicationProcess(String processName, int uid) { 4441 if (processName == null) { 4442 return; 4443 } 4444 4445 int callerUid = Binder.getCallingUid(); 4446 // Only the system server can kill an application 4447 if (callerUid == Process.SYSTEM_UID) { 4448 synchronized (this) { 4449 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4450 if (app != null && app.thread != null) { 4451 try { 4452 app.thread.scheduleSuicide(); 4453 } catch (RemoteException e) { 4454 // If the other end already died, then our work here is done. 4455 } 4456 } else { 4457 Slog.w(TAG, "Process/uid not found attempting kill of " 4458 + processName + " / " + uid); 4459 } 4460 } 4461 } else { 4462 throw new SecurityException(callerUid + " cannot kill app process: " + 4463 processName); 4464 } 4465 } 4466 4467 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4468 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4469 false, true, false, UserHandle.getUserId(uid), reason); 4470 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4471 Uri.fromParts("package", packageName, null)); 4472 if (!mProcessesReady) { 4473 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4474 | Intent.FLAG_RECEIVER_FOREGROUND); 4475 } 4476 intent.putExtra(Intent.EXTRA_UID, uid); 4477 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4478 broadcastIntentLocked(null, null, intent, 4479 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4480 false, false, 4481 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4482 } 4483 4484 private void forceStopUserLocked(int userId, String reason) { 4485 forceStopPackageLocked(null, -1, false, false, true, false, userId, reason); 4486 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4487 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4488 | Intent.FLAG_RECEIVER_FOREGROUND); 4489 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4490 broadcastIntentLocked(null, null, intent, 4491 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4492 false, false, 4493 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4494 } 4495 4496 private final boolean killPackageProcessesLocked(String packageName, int appId, 4497 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4498 boolean doit, boolean evenPersistent, String reason) { 4499 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4500 4501 // Remove all processes this package may have touched: all with the 4502 // same UID (except for the system or root user), and all whose name 4503 // matches the package name. 4504 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4505 final int NP = mProcessNames.getMap().size(); 4506 for (int ip=0; ip<NP; ip++) { 4507 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4508 final int NA = apps.size(); 4509 for (int ia=0; ia<NA; ia++) { 4510 ProcessRecord app = apps.valueAt(ia); 4511 if (app.persistent && !evenPersistent) { 4512 // we don't kill persistent processes 4513 continue; 4514 } 4515 if (app.removed) { 4516 if (doit) { 4517 procs.add(app); 4518 } 4519 continue; 4520 } 4521 4522 // Skip process if it doesn't meet our oom adj requirement. 4523 if (app.setAdj < minOomAdj) { 4524 continue; 4525 } 4526 4527 // If no package is specified, we call all processes under the 4528 // give user id. 4529 if (packageName == null) { 4530 if (app.userId != userId) { 4531 continue; 4532 } 4533 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4534 continue; 4535 } 4536 // Package has been specified, we want to hit all processes 4537 // that match it. We need to qualify this by the processes 4538 // that are running under the specified app and user ID. 4539 } else { 4540 if (UserHandle.getAppId(app.uid) != appId) { 4541 continue; 4542 } 4543 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4544 continue; 4545 } 4546 if (!app.pkgList.containsKey(packageName)) { 4547 continue; 4548 } 4549 } 4550 4551 // Process has passed all conditions, kill it! 4552 if (!doit) { 4553 return true; 4554 } 4555 app.removed = true; 4556 procs.add(app); 4557 } 4558 } 4559 4560 int N = procs.size(); 4561 for (int i=0; i<N; i++) { 4562 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4563 } 4564 updateOomAdjLocked(); 4565 return N > 0; 4566 } 4567 4568 private final boolean forceStopPackageLocked(String name, int appId, 4569 boolean callerWillRestart, boolean purgeCache, boolean doit, 4570 boolean evenPersistent, int userId, String reason) { 4571 int i; 4572 int N; 4573 4574 if (userId == UserHandle.USER_ALL && name == null) { 4575 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4576 } 4577 4578 if (appId < 0 && name != null) { 4579 try { 4580 appId = UserHandle.getAppId( 4581 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4582 } catch (RemoteException e) { 4583 } 4584 } 4585 4586 if (doit) { 4587 if (name != null) { 4588 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4589 + " user=" + userId + ": " + reason); 4590 } else { 4591 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4592 } 4593 4594 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4595 for (int ip=pmap.size()-1; ip>=0; ip--) { 4596 SparseArray<Long> ba = pmap.valueAt(ip); 4597 for (i=ba.size()-1; i>=0; i--) { 4598 boolean remove = false; 4599 final int entUid = ba.keyAt(i); 4600 if (name != null) { 4601 if (userId == UserHandle.USER_ALL) { 4602 if (UserHandle.getAppId(entUid) == appId) { 4603 remove = true; 4604 } 4605 } else { 4606 if (entUid == UserHandle.getUid(userId, appId)) { 4607 remove = true; 4608 } 4609 } 4610 } else if (UserHandle.getUserId(entUid) == userId) { 4611 remove = true; 4612 } 4613 if (remove) { 4614 ba.removeAt(i); 4615 } 4616 } 4617 if (ba.size() == 0) { 4618 pmap.removeAt(ip); 4619 } 4620 } 4621 } 4622 4623 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4624 -100, callerWillRestart, true, doit, evenPersistent, 4625 name == null ? ("stop user " + userId) : ("stop " + name)); 4626 4627 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4628 if (!doit) { 4629 return true; 4630 } 4631 didSomething = true; 4632 } 4633 4634 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4635 if (!doit) { 4636 return true; 4637 } 4638 didSomething = true; 4639 } 4640 4641 if (name == null) { 4642 // Remove all sticky broadcasts from this user. 4643 mStickyBroadcasts.remove(userId); 4644 } 4645 4646 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4647 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4648 userId, providers)) { 4649 if (!doit) { 4650 return true; 4651 } 4652 didSomething = true; 4653 } 4654 N = providers.size(); 4655 for (i=0; i<N; i++) { 4656 removeDyingProviderLocked(null, providers.get(i), true); 4657 } 4658 4659 // Remove transient permissions granted from/to this package/user 4660 removeUriPermissionsForPackageLocked(name, userId, false); 4661 4662 if (name == null) { 4663 // Remove pending intents. For now we only do this when force 4664 // stopping users, because we have some problems when doing this 4665 // for packages -- app widgets are not currently cleaned up for 4666 // such packages, so they can be left with bad pending intents. 4667 if (mIntentSenderRecords.size() > 0) { 4668 Iterator<WeakReference<PendingIntentRecord>> it 4669 = mIntentSenderRecords.values().iterator(); 4670 while (it.hasNext()) { 4671 WeakReference<PendingIntentRecord> wpir = it.next(); 4672 if (wpir == null) { 4673 it.remove(); 4674 continue; 4675 } 4676 PendingIntentRecord pir = wpir.get(); 4677 if (pir == null) { 4678 it.remove(); 4679 continue; 4680 } 4681 if (name == null) { 4682 // Stopping user, remove all objects for the user. 4683 if (pir.key.userId != userId) { 4684 // Not the same user, skip it. 4685 continue; 4686 } 4687 } else { 4688 if (UserHandle.getAppId(pir.uid) != appId) { 4689 // Different app id, skip it. 4690 continue; 4691 } 4692 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4693 // Different user, skip it. 4694 continue; 4695 } 4696 if (!pir.key.packageName.equals(name)) { 4697 // Different package, skip it. 4698 continue; 4699 } 4700 } 4701 if (!doit) { 4702 return true; 4703 } 4704 didSomething = true; 4705 it.remove(); 4706 pir.canceled = true; 4707 if (pir.key.activity != null) { 4708 pir.key.activity.pendingResults.remove(pir.ref); 4709 } 4710 } 4711 } 4712 } 4713 4714 if (doit) { 4715 if (purgeCache && name != null) { 4716 AttributeCache ac = AttributeCache.instance(); 4717 if (ac != null) { 4718 ac.removePackage(name); 4719 } 4720 } 4721 if (mBooted) { 4722 mStackSupervisor.resumeTopActivitiesLocked(); 4723 mStackSupervisor.scheduleIdleLocked(); 4724 } 4725 } 4726 4727 return didSomething; 4728 } 4729 4730 private final boolean removeProcessLocked(ProcessRecord app, 4731 boolean callerWillRestart, boolean allowRestart, String reason) { 4732 final String name = app.processName; 4733 final int uid = app.uid; 4734 if (DEBUG_PROCESSES) Slog.d( 4735 TAG, "Force removing proc " + app.toShortString() + " (" + name 4736 + "/" + uid + ")"); 4737 4738 mProcessNames.remove(name, uid); 4739 mIsolatedProcesses.remove(app.uid); 4740 if (mHeavyWeightProcess == app) { 4741 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4742 mHeavyWeightProcess.userId, 0)); 4743 mHeavyWeightProcess = null; 4744 } 4745 boolean needRestart = false; 4746 if (app.pid > 0 && app.pid != MY_PID) { 4747 int pid = app.pid; 4748 synchronized (mPidsSelfLocked) { 4749 mPidsSelfLocked.remove(pid); 4750 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4751 } 4752 killUnneededProcessLocked(app, reason); 4753 handleAppDiedLocked(app, true, allowRestart); 4754 removeLruProcessLocked(app); 4755 4756 if (app.persistent && !app.isolated) { 4757 if (!callerWillRestart) { 4758 addAppLocked(app.info, false); 4759 } else { 4760 needRestart = true; 4761 } 4762 } 4763 } else { 4764 mRemovedProcesses.add(app); 4765 } 4766 4767 return needRestart; 4768 } 4769 4770 private final void processStartTimedOutLocked(ProcessRecord app) { 4771 final int pid = app.pid; 4772 boolean gone = false; 4773 synchronized (mPidsSelfLocked) { 4774 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4775 if (knownApp != null && knownApp.thread == null) { 4776 mPidsSelfLocked.remove(pid); 4777 gone = true; 4778 } 4779 } 4780 4781 if (gone) { 4782 Slog.w(TAG, "Process " + app + " failed to attach"); 4783 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4784 pid, app.uid, app.processName); 4785 mProcessNames.remove(app.processName, app.uid); 4786 mIsolatedProcesses.remove(app.uid); 4787 if (mHeavyWeightProcess == app) { 4788 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4789 mHeavyWeightProcess.userId, 0)); 4790 mHeavyWeightProcess = null; 4791 } 4792 // Take care of any launching providers waiting for this process. 4793 checkAppInLaunchingProvidersLocked(app, true); 4794 // Take care of any services that are waiting for the process. 4795 mServices.processStartTimedOutLocked(app); 4796 killUnneededProcessLocked(app, "start timeout"); 4797 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4798 Slog.w(TAG, "Unattached app died before backup, skipping"); 4799 try { 4800 IBackupManager bm = IBackupManager.Stub.asInterface( 4801 ServiceManager.getService(Context.BACKUP_SERVICE)); 4802 bm.agentDisconnected(app.info.packageName); 4803 } catch (RemoteException e) { 4804 // Can't happen; the backup manager is local 4805 } 4806 } 4807 if (isPendingBroadcastProcessLocked(pid)) { 4808 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4809 skipPendingBroadcastLocked(pid); 4810 } 4811 } else { 4812 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4813 } 4814 } 4815 4816 private final boolean attachApplicationLocked(IApplicationThread thread, 4817 int pid) { 4818 4819 // Find the application record that is being attached... either via 4820 // the pid if we are running in multiple processes, or just pull the 4821 // next app record if we are emulating process with anonymous threads. 4822 ProcessRecord app; 4823 if (pid != MY_PID && pid >= 0) { 4824 synchronized (mPidsSelfLocked) { 4825 app = mPidsSelfLocked.get(pid); 4826 } 4827 } else { 4828 app = null; 4829 } 4830 4831 if (app == null) { 4832 Slog.w(TAG, "No pending application record for pid " + pid 4833 + " (IApplicationThread " + thread + "); dropping process"); 4834 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4835 if (pid > 0 && pid != MY_PID) { 4836 Process.killProcessQuiet(pid); 4837 } else { 4838 try { 4839 thread.scheduleExit(); 4840 } catch (Exception e) { 4841 // Ignore exceptions. 4842 } 4843 } 4844 return false; 4845 } 4846 4847 // If this application record is still attached to a previous 4848 // process, clean it up now. 4849 if (app.thread != null) { 4850 handleAppDiedLocked(app, true, true); 4851 } 4852 4853 // Tell the process all about itself. 4854 4855 if (localLOGV) Slog.v( 4856 TAG, "Binding process pid " + pid + " to record " + app); 4857 4858 final String processName = app.processName; 4859 try { 4860 AppDeathRecipient adr = new AppDeathRecipient( 4861 app, pid, thread); 4862 thread.asBinder().linkToDeath(adr, 0); 4863 app.deathRecipient = adr; 4864 } catch (RemoteException e) { 4865 app.resetPackageList(mProcessStats); 4866 startProcessLocked(app, "link fail", processName); 4867 return false; 4868 } 4869 4870 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4871 4872 app.makeActive(thread, mProcessStats); 4873 app.curAdj = app.setAdj = -100; 4874 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4875 app.forcingToForeground = null; 4876 app.foregroundServices = false; 4877 app.hasShownUi = false; 4878 app.debugging = false; 4879 app.cached = false; 4880 4881 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4882 4883 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4884 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4885 4886 if (!normalMode) { 4887 Slog.i(TAG, "Launching preboot mode app: " + app); 4888 } 4889 4890 if (localLOGV) Slog.v( 4891 TAG, "New app record " + app 4892 + " thread=" + thread.asBinder() + " pid=" + pid); 4893 try { 4894 int testMode = IApplicationThread.DEBUG_OFF; 4895 if (mDebugApp != null && mDebugApp.equals(processName)) { 4896 testMode = mWaitForDebugger 4897 ? IApplicationThread.DEBUG_WAIT 4898 : IApplicationThread.DEBUG_ON; 4899 app.debugging = true; 4900 if (mDebugTransient) { 4901 mDebugApp = mOrigDebugApp; 4902 mWaitForDebugger = mOrigWaitForDebugger; 4903 } 4904 } 4905 String profileFile = app.instrumentationProfileFile; 4906 ParcelFileDescriptor profileFd = null; 4907 boolean profileAutoStop = false; 4908 if (mProfileApp != null && mProfileApp.equals(processName)) { 4909 mProfileProc = app; 4910 profileFile = mProfileFile; 4911 profileFd = mProfileFd; 4912 profileAutoStop = mAutoStopProfiler; 4913 } 4914 boolean enableOpenGlTrace = false; 4915 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4916 enableOpenGlTrace = true; 4917 mOpenGlTraceApp = null; 4918 } 4919 4920 // If the app is being launched for restore or full backup, set it up specially 4921 boolean isRestrictedBackupMode = false; 4922 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4923 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4924 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4925 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4926 } 4927 4928 ensurePackageDexOpt(app.instrumentationInfo != null 4929 ? app.instrumentationInfo.packageName 4930 : app.info.packageName); 4931 if (app.instrumentationClass != null) { 4932 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4933 } 4934 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4935 + processName + " with config " + mConfiguration); 4936 ApplicationInfo appInfo = app.instrumentationInfo != null 4937 ? app.instrumentationInfo : app.info; 4938 app.compat = compatibilityInfoForPackageLocked(appInfo); 4939 if (profileFd != null) { 4940 profileFd = profileFd.dup(); 4941 } 4942 thread.bindApplication(processName, appInfo, providers, 4943 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4944 app.instrumentationArguments, app.instrumentationWatcher, 4945 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4946 isRestrictedBackupMode || !normalMode, app.persistent, 4947 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4948 mCoreSettingsObserver.getCoreSettingsLocked()); 4949 updateLruProcessLocked(app, false, null); 4950 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4951 } catch (Exception e) { 4952 // todo: Yikes! What should we do? For now we will try to 4953 // start another process, but that could easily get us in 4954 // an infinite loop of restarting processes... 4955 Slog.w(TAG, "Exception thrown during bind!", e); 4956 4957 app.resetPackageList(mProcessStats); 4958 app.unlinkDeathRecipient(); 4959 startProcessLocked(app, "bind fail", processName); 4960 return false; 4961 } 4962 4963 // Remove this record from the list of starting applications. 4964 mPersistentStartingProcesses.remove(app); 4965 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4966 "Attach application locked removing on hold: " + app); 4967 mProcessesOnHold.remove(app); 4968 4969 boolean badApp = false; 4970 boolean didSomething = false; 4971 4972 // See if the top visible activity is waiting to run in this process... 4973 if (normalMode) { 4974 try { 4975 if (mStackSupervisor.attachApplicationLocked(app)) { 4976 didSomething = true; 4977 } 4978 } catch (Exception e) { 4979 badApp = true; 4980 } 4981 } 4982 4983 // Find any services that should be running in this process... 4984 if (!badApp) { 4985 try { 4986 didSomething |= mServices.attachApplicationLocked(app, processName); 4987 } catch (Exception e) { 4988 badApp = true; 4989 } 4990 } 4991 4992 // Check if a next-broadcast receiver is in this process... 4993 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4994 try { 4995 didSomething |= sendPendingBroadcastsLocked(app); 4996 } catch (Exception e) { 4997 // If the app died trying to launch the receiver we declare it 'bad' 4998 badApp = true; 4999 } 5000 } 5001 5002 // Check whether the next backup agent is in this process... 5003 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5004 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5005 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5006 try { 5007 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5008 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5009 mBackupTarget.backupMode); 5010 } catch (Exception e) { 5011 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5012 e.printStackTrace(); 5013 } 5014 } 5015 5016 if (badApp) { 5017 // todo: Also need to kill application to deal with all 5018 // kinds of exceptions. 5019 handleAppDiedLocked(app, false, true); 5020 return false; 5021 } 5022 5023 if (!didSomething) { 5024 updateOomAdjLocked(); 5025 } 5026 5027 return true; 5028 } 5029 5030 @Override 5031 public final void attachApplication(IApplicationThread thread) { 5032 synchronized (this) { 5033 int callingPid = Binder.getCallingPid(); 5034 final long origId = Binder.clearCallingIdentity(); 5035 attachApplicationLocked(thread, callingPid); 5036 Binder.restoreCallingIdentity(origId); 5037 } 5038 } 5039 5040 @Override 5041 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5042 final long origId = Binder.clearCallingIdentity(); 5043 synchronized (this) { 5044 ActivityStack stack = ActivityRecord.getStackLocked(token); 5045 if (stack != null) { 5046 ActivityRecord r = 5047 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5048 if (stopProfiling) { 5049 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5050 try { 5051 mProfileFd.close(); 5052 } catch (IOException e) { 5053 } 5054 clearProfilerLocked(); 5055 } 5056 } 5057 } 5058 } 5059 Binder.restoreCallingIdentity(origId); 5060 } 5061 5062 void enableScreenAfterBoot() { 5063 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5064 SystemClock.uptimeMillis()); 5065 mWindowManager.enableScreenAfterBoot(); 5066 5067 synchronized (this) { 5068 updateEventDispatchingLocked(); 5069 } 5070 } 5071 5072 @Override 5073 public void showBootMessage(final CharSequence msg, final boolean always) { 5074 enforceNotIsolatedCaller("showBootMessage"); 5075 mWindowManager.showBootMessage(msg, always); 5076 } 5077 5078 @Override 5079 public void dismissKeyguardOnNextActivity() { 5080 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5081 final long token = Binder.clearCallingIdentity(); 5082 try { 5083 synchronized (this) { 5084 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5085 if (mLockScreenShown) { 5086 mLockScreenShown = false; 5087 comeOutOfSleepIfNeededLocked(); 5088 } 5089 mStackSupervisor.setDismissKeyguard(true); 5090 } 5091 } finally { 5092 Binder.restoreCallingIdentity(token); 5093 } 5094 } 5095 5096 final void finishBooting() { 5097 IntentFilter pkgFilter = new IntentFilter(); 5098 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5099 pkgFilter.addDataScheme("package"); 5100 mContext.registerReceiver(new BroadcastReceiver() { 5101 @Override 5102 public void onReceive(Context context, Intent intent) { 5103 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5104 if (pkgs != null) { 5105 for (String pkg : pkgs) { 5106 synchronized (ActivityManagerService.this) { 5107 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0, 5108 "finished booting")) { 5109 setResultCode(Activity.RESULT_OK); 5110 return; 5111 } 5112 } 5113 } 5114 } 5115 } 5116 }, pkgFilter); 5117 5118 synchronized (this) { 5119 // Ensure that any processes we had put on hold are now started 5120 // up. 5121 final int NP = mProcessesOnHold.size(); 5122 if (NP > 0) { 5123 ArrayList<ProcessRecord> procs = 5124 new ArrayList<ProcessRecord>(mProcessesOnHold); 5125 for (int ip=0; ip<NP; ip++) { 5126 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5127 + procs.get(ip)); 5128 startProcessLocked(procs.get(ip), "on-hold", null); 5129 } 5130 } 5131 5132 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5133 // Start looking for apps that are abusing wake locks. 5134 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5135 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5136 // Tell anyone interested that we are done booting! 5137 SystemProperties.set("sys.boot_completed", "1"); 5138 SystemProperties.set("dev.bootcomplete", "1"); 5139 for (int i=0; i<mStartedUsers.size(); i++) { 5140 UserStartedState uss = mStartedUsers.valueAt(i); 5141 if (uss.mState == UserStartedState.STATE_BOOTING) { 5142 uss.mState = UserStartedState.STATE_RUNNING; 5143 final int userId = mStartedUsers.keyAt(i); 5144 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5145 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5146 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5147 broadcastIntentLocked(null, null, intent, null, 5148 new IIntentReceiver.Stub() { 5149 @Override 5150 public void performReceive(Intent intent, int resultCode, 5151 String data, Bundle extras, boolean ordered, 5152 boolean sticky, int sendingUser) { 5153 synchronized (ActivityManagerService.this) { 5154 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5155 true, false); 5156 } 5157 } 5158 }, 5159 0, null, null, 5160 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5161 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5162 userId); 5163 } 5164 } 5165 } 5166 } 5167 } 5168 5169 final void ensureBootCompleted() { 5170 boolean booting; 5171 boolean enableScreen; 5172 synchronized (this) { 5173 booting = mBooting; 5174 mBooting = false; 5175 enableScreen = !mBooted; 5176 mBooted = true; 5177 } 5178 5179 if (booting) { 5180 finishBooting(); 5181 } 5182 5183 if (enableScreen) { 5184 enableScreenAfterBoot(); 5185 } 5186 } 5187 5188 @Override 5189 public final void activityResumed(IBinder token) { 5190 final long origId = Binder.clearCallingIdentity(); 5191 synchronized(this) { 5192 ActivityStack stack = ActivityRecord.getStackLocked(token); 5193 if (stack != null) { 5194 ActivityRecord.activityResumedLocked(token); 5195 } 5196 } 5197 Binder.restoreCallingIdentity(origId); 5198 } 5199 5200 @Override 5201 public final void activityPaused(IBinder token) { 5202 final long origId = Binder.clearCallingIdentity(); 5203 synchronized(this) { 5204 ActivityStack stack = ActivityRecord.getStackLocked(token); 5205 if (stack != null) { 5206 stack.activityPausedLocked(token, false); 5207 } 5208 } 5209 Binder.restoreCallingIdentity(origId); 5210 } 5211 5212 @Override 5213 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5214 CharSequence description) { 5215 if (localLOGV) Slog.v( 5216 TAG, "Activity stopped: token=" + token); 5217 5218 // Refuse possible leaked file descriptors 5219 if (icicle != null && icicle.hasFileDescriptors()) { 5220 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5221 } 5222 5223 ActivityRecord r = null; 5224 5225 final long origId = Binder.clearCallingIdentity(); 5226 5227 synchronized (this) { 5228 r = ActivityRecord.isInStackLocked(token); 5229 if (r != null) { 5230 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5231 } 5232 } 5233 5234 if (r != null) { 5235 sendPendingThumbnail(r, null, null, null, false); 5236 } 5237 5238 trimApplications(); 5239 5240 Binder.restoreCallingIdentity(origId); 5241 } 5242 5243 @Override 5244 public final void activityDestroyed(IBinder token) { 5245 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5246 synchronized (this) { 5247 ActivityStack stack = ActivityRecord.getStackLocked(token); 5248 if (stack != null) { 5249 stack.activityDestroyedLocked(token); 5250 } 5251 } 5252 } 5253 5254 @Override 5255 public String getCallingPackage(IBinder token) { 5256 synchronized (this) { 5257 ActivityRecord r = getCallingRecordLocked(token); 5258 return r != null ? r.info.packageName : null; 5259 } 5260 } 5261 5262 @Override 5263 public ComponentName getCallingActivity(IBinder token) { 5264 synchronized (this) { 5265 ActivityRecord r = getCallingRecordLocked(token); 5266 return r != null ? r.intent.getComponent() : null; 5267 } 5268 } 5269 5270 private ActivityRecord getCallingRecordLocked(IBinder token) { 5271 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5272 if (r == null) { 5273 return null; 5274 } 5275 return r.resultTo; 5276 } 5277 5278 @Override 5279 public ComponentName getActivityClassForToken(IBinder token) { 5280 synchronized(this) { 5281 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5282 if (r == null) { 5283 return null; 5284 } 5285 return r.intent.getComponent(); 5286 } 5287 } 5288 5289 @Override 5290 public String getPackageForToken(IBinder token) { 5291 synchronized(this) { 5292 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5293 if (r == null) { 5294 return null; 5295 } 5296 return r.packageName; 5297 } 5298 } 5299 5300 @Override 5301 public IIntentSender getIntentSender(int type, 5302 String packageName, IBinder token, String resultWho, 5303 int requestCode, Intent[] intents, String[] resolvedTypes, 5304 int flags, Bundle options, int userId) { 5305 enforceNotIsolatedCaller("getIntentSender"); 5306 // Refuse possible leaked file descriptors 5307 if (intents != null) { 5308 if (intents.length < 1) { 5309 throw new IllegalArgumentException("Intents array length must be >= 1"); 5310 } 5311 for (int i=0; i<intents.length; i++) { 5312 Intent intent = intents[i]; 5313 if (intent != null) { 5314 if (intent.hasFileDescriptors()) { 5315 throw new IllegalArgumentException("File descriptors passed in Intent"); 5316 } 5317 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5318 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5319 throw new IllegalArgumentException( 5320 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5321 } 5322 intents[i] = new Intent(intent); 5323 } 5324 } 5325 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5326 throw new IllegalArgumentException( 5327 "Intent array length does not match resolvedTypes length"); 5328 } 5329 } 5330 if (options != null) { 5331 if (options.hasFileDescriptors()) { 5332 throw new IllegalArgumentException("File descriptors passed in options"); 5333 } 5334 } 5335 5336 synchronized(this) { 5337 int callingUid = Binder.getCallingUid(); 5338 int origUserId = userId; 5339 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5340 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5341 "getIntentSender", null); 5342 if (origUserId == UserHandle.USER_CURRENT) { 5343 // We don't want to evaluate this until the pending intent is 5344 // actually executed. However, we do want to always do the 5345 // security checking for it above. 5346 userId = UserHandle.USER_CURRENT; 5347 } 5348 try { 5349 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5350 int uid = AppGlobals.getPackageManager() 5351 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5352 if (!UserHandle.isSameApp(callingUid, uid)) { 5353 String msg = "Permission Denial: getIntentSender() from pid=" 5354 + Binder.getCallingPid() 5355 + ", uid=" + Binder.getCallingUid() 5356 + ", (need uid=" + uid + ")" 5357 + " is not allowed to send as package " + packageName; 5358 Slog.w(TAG, msg); 5359 throw new SecurityException(msg); 5360 } 5361 } 5362 5363 return getIntentSenderLocked(type, packageName, callingUid, userId, 5364 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5365 5366 } catch (RemoteException e) { 5367 throw new SecurityException(e); 5368 } 5369 } 5370 } 5371 5372 IIntentSender getIntentSenderLocked(int type, String packageName, 5373 int callingUid, int userId, IBinder token, String resultWho, 5374 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5375 Bundle options) { 5376 if (DEBUG_MU) 5377 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5378 ActivityRecord activity = null; 5379 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5380 activity = ActivityRecord.isInStackLocked(token); 5381 if (activity == null) { 5382 return null; 5383 } 5384 if (activity.finishing) { 5385 return null; 5386 } 5387 } 5388 5389 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5390 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5391 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5392 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5393 |PendingIntent.FLAG_UPDATE_CURRENT); 5394 5395 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5396 type, packageName, activity, resultWho, 5397 requestCode, intents, resolvedTypes, flags, options, userId); 5398 WeakReference<PendingIntentRecord> ref; 5399 ref = mIntentSenderRecords.get(key); 5400 PendingIntentRecord rec = ref != null ? ref.get() : null; 5401 if (rec != null) { 5402 if (!cancelCurrent) { 5403 if (updateCurrent) { 5404 if (rec.key.requestIntent != null) { 5405 rec.key.requestIntent.replaceExtras(intents != null ? 5406 intents[intents.length - 1] : null); 5407 } 5408 if (intents != null) { 5409 intents[intents.length-1] = rec.key.requestIntent; 5410 rec.key.allIntents = intents; 5411 rec.key.allResolvedTypes = resolvedTypes; 5412 } else { 5413 rec.key.allIntents = null; 5414 rec.key.allResolvedTypes = null; 5415 } 5416 } 5417 return rec; 5418 } 5419 rec.canceled = true; 5420 mIntentSenderRecords.remove(key); 5421 } 5422 if (noCreate) { 5423 return rec; 5424 } 5425 rec = new PendingIntentRecord(this, key, callingUid); 5426 mIntentSenderRecords.put(key, rec.ref); 5427 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5428 if (activity.pendingResults == null) { 5429 activity.pendingResults 5430 = new HashSet<WeakReference<PendingIntentRecord>>(); 5431 } 5432 activity.pendingResults.add(rec.ref); 5433 } 5434 return rec; 5435 } 5436 5437 @Override 5438 public void cancelIntentSender(IIntentSender sender) { 5439 if (!(sender instanceof PendingIntentRecord)) { 5440 return; 5441 } 5442 synchronized(this) { 5443 PendingIntentRecord rec = (PendingIntentRecord)sender; 5444 try { 5445 int uid = AppGlobals.getPackageManager() 5446 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5447 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5448 String msg = "Permission Denial: cancelIntentSender() from pid=" 5449 + Binder.getCallingPid() 5450 + ", uid=" + Binder.getCallingUid() 5451 + " is not allowed to cancel packges " 5452 + rec.key.packageName; 5453 Slog.w(TAG, msg); 5454 throw new SecurityException(msg); 5455 } 5456 } catch (RemoteException e) { 5457 throw new SecurityException(e); 5458 } 5459 cancelIntentSenderLocked(rec, true); 5460 } 5461 } 5462 5463 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5464 rec.canceled = true; 5465 mIntentSenderRecords.remove(rec.key); 5466 if (cleanActivity && rec.key.activity != null) { 5467 rec.key.activity.pendingResults.remove(rec.ref); 5468 } 5469 } 5470 5471 @Override 5472 public String getPackageForIntentSender(IIntentSender pendingResult) { 5473 if (!(pendingResult instanceof PendingIntentRecord)) { 5474 return null; 5475 } 5476 try { 5477 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5478 return res.key.packageName; 5479 } catch (ClassCastException e) { 5480 } 5481 return null; 5482 } 5483 5484 @Override 5485 public int getUidForIntentSender(IIntentSender sender) { 5486 if (sender instanceof PendingIntentRecord) { 5487 try { 5488 PendingIntentRecord res = (PendingIntentRecord)sender; 5489 return res.uid; 5490 } catch (ClassCastException e) { 5491 } 5492 } 5493 return -1; 5494 } 5495 5496 @Override 5497 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5498 if (!(pendingResult instanceof PendingIntentRecord)) { 5499 return false; 5500 } 5501 try { 5502 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5503 if (res.key.allIntents == null) { 5504 return false; 5505 } 5506 for (int i=0; i<res.key.allIntents.length; i++) { 5507 Intent intent = res.key.allIntents[i]; 5508 if (intent.getPackage() != null && intent.getComponent() != null) { 5509 return false; 5510 } 5511 } 5512 return true; 5513 } catch (ClassCastException e) { 5514 } 5515 return false; 5516 } 5517 5518 @Override 5519 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5520 if (!(pendingResult instanceof PendingIntentRecord)) { 5521 return false; 5522 } 5523 try { 5524 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5525 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5526 return true; 5527 } 5528 return false; 5529 } catch (ClassCastException e) { 5530 } 5531 return false; 5532 } 5533 5534 @Override 5535 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5536 if (!(pendingResult instanceof PendingIntentRecord)) { 5537 return null; 5538 } 5539 try { 5540 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5541 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5542 } catch (ClassCastException e) { 5543 } 5544 return null; 5545 } 5546 5547 @Override 5548 public void setProcessLimit(int max) { 5549 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5550 "setProcessLimit()"); 5551 synchronized (this) { 5552 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5553 mProcessLimitOverride = max; 5554 } 5555 trimApplications(); 5556 } 5557 5558 @Override 5559 public int getProcessLimit() { 5560 synchronized (this) { 5561 return mProcessLimitOverride; 5562 } 5563 } 5564 5565 void foregroundTokenDied(ForegroundToken token) { 5566 synchronized (ActivityManagerService.this) { 5567 synchronized (mPidsSelfLocked) { 5568 ForegroundToken cur 5569 = mForegroundProcesses.get(token.pid); 5570 if (cur != token) { 5571 return; 5572 } 5573 mForegroundProcesses.remove(token.pid); 5574 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5575 if (pr == null) { 5576 return; 5577 } 5578 pr.forcingToForeground = null; 5579 pr.foregroundServices = false; 5580 } 5581 updateOomAdjLocked(); 5582 } 5583 } 5584 5585 @Override 5586 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5587 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5588 "setProcessForeground()"); 5589 synchronized(this) { 5590 boolean changed = false; 5591 5592 synchronized (mPidsSelfLocked) { 5593 ProcessRecord pr = mPidsSelfLocked.get(pid); 5594 if (pr == null && isForeground) { 5595 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5596 return; 5597 } 5598 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5599 if (oldToken != null) { 5600 oldToken.token.unlinkToDeath(oldToken, 0); 5601 mForegroundProcesses.remove(pid); 5602 if (pr != null) { 5603 pr.forcingToForeground = null; 5604 } 5605 changed = true; 5606 } 5607 if (isForeground && token != null) { 5608 ForegroundToken newToken = new ForegroundToken() { 5609 @Override 5610 public void binderDied() { 5611 foregroundTokenDied(this); 5612 } 5613 }; 5614 newToken.pid = pid; 5615 newToken.token = token; 5616 try { 5617 token.linkToDeath(newToken, 0); 5618 mForegroundProcesses.put(pid, newToken); 5619 pr.forcingToForeground = token; 5620 changed = true; 5621 } catch (RemoteException e) { 5622 // If the process died while doing this, we will later 5623 // do the cleanup with the process death link. 5624 } 5625 } 5626 } 5627 5628 if (changed) { 5629 updateOomAdjLocked(); 5630 } 5631 } 5632 } 5633 5634 // ========================================================= 5635 // PERMISSIONS 5636 // ========================================================= 5637 5638 static class PermissionController extends IPermissionController.Stub { 5639 ActivityManagerService mActivityManagerService; 5640 PermissionController(ActivityManagerService activityManagerService) { 5641 mActivityManagerService = activityManagerService; 5642 } 5643 5644 @Override 5645 public boolean checkPermission(String permission, int pid, int uid) { 5646 return mActivityManagerService.checkPermission(permission, pid, 5647 uid) == PackageManager.PERMISSION_GRANTED; 5648 } 5649 } 5650 5651 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5652 @Override 5653 public int checkComponentPermission(String permission, int pid, int uid, 5654 int owningUid, boolean exported) { 5655 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5656 owningUid, exported); 5657 } 5658 5659 @Override 5660 public Object getAMSLock() { 5661 return ActivityManagerService.this; 5662 } 5663 } 5664 5665 /** 5666 * This can be called with or without the global lock held. 5667 */ 5668 int checkComponentPermission(String permission, int pid, int uid, 5669 int owningUid, boolean exported) { 5670 // We might be performing an operation on behalf of an indirect binder 5671 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5672 // client identity accordingly before proceeding. 5673 Identity tlsIdentity = sCallerIdentity.get(); 5674 if (tlsIdentity != null) { 5675 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5676 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5677 uid = tlsIdentity.uid; 5678 pid = tlsIdentity.pid; 5679 } 5680 5681 if (pid == MY_PID) { 5682 return PackageManager.PERMISSION_GRANTED; 5683 } 5684 5685 return ActivityManager.checkComponentPermission(permission, uid, 5686 owningUid, exported); 5687 } 5688 5689 /** 5690 * As the only public entry point for permissions checking, this method 5691 * can enforce the semantic that requesting a check on a null global 5692 * permission is automatically denied. (Internally a null permission 5693 * string is used when calling {@link #checkComponentPermission} in cases 5694 * when only uid-based security is needed.) 5695 * 5696 * This can be called with or without the global lock held. 5697 */ 5698 @Override 5699 public int checkPermission(String permission, int pid, int uid) { 5700 if (permission == null) { 5701 return PackageManager.PERMISSION_DENIED; 5702 } 5703 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5704 } 5705 5706 /** 5707 * Binder IPC calls go through the public entry point. 5708 * This can be called with or without the global lock held. 5709 */ 5710 int checkCallingPermission(String permission) { 5711 return checkPermission(permission, 5712 Binder.getCallingPid(), 5713 UserHandle.getAppId(Binder.getCallingUid())); 5714 } 5715 5716 /** 5717 * This can be called with or without the global lock held. 5718 */ 5719 void enforceCallingPermission(String permission, String func) { 5720 if (checkCallingPermission(permission) 5721 == PackageManager.PERMISSION_GRANTED) { 5722 return; 5723 } 5724 5725 String msg = "Permission Denial: " + func + " from pid=" 5726 + Binder.getCallingPid() 5727 + ", uid=" + Binder.getCallingUid() 5728 + " requires " + permission; 5729 Slog.w(TAG, msg); 5730 throw new SecurityException(msg); 5731 } 5732 5733 /** 5734 * Determine if UID is holding permissions required to access {@link Uri} in 5735 * the given {@link ProviderInfo}. Final permission checking is always done 5736 * in {@link ContentProvider}. 5737 */ 5738 private final boolean checkHoldingPermissionsLocked( 5739 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5740 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5741 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5742 5743 if (pi.applicationInfo.uid == uid) { 5744 return true; 5745 } else if (!pi.exported) { 5746 return false; 5747 } 5748 5749 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5750 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5751 try { 5752 // check if target holds top-level <provider> permissions 5753 if (!readMet && pi.readPermission != null 5754 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5755 readMet = true; 5756 } 5757 if (!writeMet && pi.writePermission != null 5758 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5759 writeMet = true; 5760 } 5761 5762 // track if unprotected read/write is allowed; any denied 5763 // <path-permission> below removes this ability 5764 boolean allowDefaultRead = pi.readPermission == null; 5765 boolean allowDefaultWrite = pi.writePermission == null; 5766 5767 // check if target holds any <path-permission> that match uri 5768 final PathPermission[] pps = pi.pathPermissions; 5769 if (pps != null) { 5770 final String path = uri.getPath(); 5771 int i = pps.length; 5772 while (i > 0 && (!readMet || !writeMet)) { 5773 i--; 5774 PathPermission pp = pps[i]; 5775 if (pp.match(path)) { 5776 if (!readMet) { 5777 final String pprperm = pp.getReadPermission(); 5778 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5779 + pprperm + " for " + pp.getPath() 5780 + ": match=" + pp.match(path) 5781 + " check=" + pm.checkUidPermission(pprperm, uid)); 5782 if (pprperm != null) { 5783 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5784 readMet = true; 5785 } else { 5786 allowDefaultRead = false; 5787 } 5788 } 5789 } 5790 if (!writeMet) { 5791 final String ppwperm = pp.getWritePermission(); 5792 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5793 + ppwperm + " for " + pp.getPath() 5794 + ": match=" + pp.match(path) 5795 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5796 if (ppwperm != null) { 5797 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5798 writeMet = true; 5799 } else { 5800 allowDefaultWrite = false; 5801 } 5802 } 5803 } 5804 } 5805 } 5806 } 5807 5808 // grant unprotected <provider> read/write, if not blocked by 5809 // <path-permission> above 5810 if (allowDefaultRead) readMet = true; 5811 if (allowDefaultWrite) writeMet = true; 5812 5813 } catch (RemoteException e) { 5814 return false; 5815 } 5816 5817 return readMet && writeMet; 5818 } 5819 5820 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5821 ProviderInfo pi = null; 5822 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5823 if (cpr != null) { 5824 pi = cpr.info; 5825 } else { 5826 try { 5827 pi = AppGlobals.getPackageManager().resolveContentProvider( 5828 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5829 } catch (RemoteException ex) { 5830 } 5831 } 5832 return pi; 5833 } 5834 5835 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5836 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5837 if (targetUris != null) { 5838 return targetUris.get(uri); 5839 } else { 5840 return null; 5841 } 5842 } 5843 5844 private UriPermission findOrCreateUriPermissionLocked( 5845 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5846 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5847 if (targetUris == null) { 5848 targetUris = Maps.newArrayMap(); 5849 mGrantedUriPermissions.put(targetUid, targetUris); 5850 } 5851 5852 UriPermission perm = targetUris.get(uri); 5853 if (perm == null) { 5854 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5855 targetUris.put(uri, perm); 5856 } 5857 5858 return perm; 5859 } 5860 5861 private final boolean checkUriPermissionLocked( 5862 Uri uri, int uid, int modeFlags, int minStrength) { 5863 // Root gets to do everything. 5864 if (uid == 0) { 5865 return true; 5866 } 5867 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5868 if (perms == null) return false; 5869 UriPermission perm = perms.get(uri); 5870 if (perm == null) return false; 5871 return perm.getStrength(modeFlags) >= minStrength; 5872 } 5873 5874 @Override 5875 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5876 enforceNotIsolatedCaller("checkUriPermission"); 5877 5878 // Another redirected-binder-call permissions check as in 5879 // {@link checkComponentPermission}. 5880 Identity tlsIdentity = sCallerIdentity.get(); 5881 if (tlsIdentity != null) { 5882 uid = tlsIdentity.uid; 5883 pid = tlsIdentity.pid; 5884 } 5885 5886 // Our own process gets to do everything. 5887 if (pid == MY_PID) { 5888 return PackageManager.PERMISSION_GRANTED; 5889 } 5890 synchronized(this) { 5891 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5892 ? PackageManager.PERMISSION_GRANTED 5893 : PackageManager.PERMISSION_DENIED; 5894 } 5895 } 5896 5897 /** 5898 * Check if the targetPkg can be granted permission to access uri by 5899 * the callingUid using the given modeFlags. Throws a security exception 5900 * if callingUid is not allowed to do this. Returns the uid of the target 5901 * if the URI permission grant should be performed; returns -1 if it is not 5902 * needed (for example targetPkg already has permission to access the URI). 5903 * If you already know the uid of the target, you can supply it in 5904 * lastTargetUid else set that to -1. 5905 */ 5906 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5907 Uri uri, int modeFlags, int lastTargetUid) { 5908 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5909 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5910 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5911 if (modeFlags == 0) { 5912 return -1; 5913 } 5914 5915 if (targetPkg != null) { 5916 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5917 "Checking grant " + targetPkg + " permission to " + uri); 5918 } 5919 5920 final IPackageManager pm = AppGlobals.getPackageManager(); 5921 5922 // If this is not a content: uri, we can't do anything with it. 5923 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5924 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5925 "Can't grant URI permission for non-content URI: " + uri); 5926 return -1; 5927 } 5928 5929 final String authority = uri.getAuthority(); 5930 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 5931 if (pi == null) { 5932 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5933 return -1; 5934 } 5935 5936 int targetUid = lastTargetUid; 5937 if (targetUid < 0 && targetPkg != null) { 5938 try { 5939 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5940 if (targetUid < 0) { 5941 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5942 "Can't grant URI permission no uid for: " + targetPkg); 5943 return -1; 5944 } 5945 } catch (RemoteException ex) { 5946 return -1; 5947 } 5948 } 5949 5950 if (targetUid >= 0) { 5951 // First... does the target actually need this permission? 5952 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5953 // No need to grant the target this permission. 5954 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5955 "Target " + targetPkg + " already has full permission to " + uri); 5956 return -1; 5957 } 5958 } else { 5959 // First... there is no target package, so can anyone access it? 5960 boolean allowed = pi.exported; 5961 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5962 if (pi.readPermission != null) { 5963 allowed = false; 5964 } 5965 } 5966 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5967 if (pi.writePermission != null) { 5968 allowed = false; 5969 } 5970 } 5971 if (allowed) { 5972 return -1; 5973 } 5974 } 5975 5976 // Second... is the provider allowing granting of URI permissions? 5977 if (!pi.grantUriPermissions) { 5978 throw new SecurityException("Provider " + pi.packageName 5979 + "/" + pi.name 5980 + " does not allow granting of Uri permissions (uri " 5981 + uri + ")"); 5982 } 5983 if (pi.uriPermissionPatterns != null) { 5984 final int N = pi.uriPermissionPatterns.length; 5985 boolean allowed = false; 5986 for (int i=0; i<N; i++) { 5987 if (pi.uriPermissionPatterns[i] != null 5988 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5989 allowed = true; 5990 break; 5991 } 5992 } 5993 if (!allowed) { 5994 throw new SecurityException("Provider " + pi.packageName 5995 + "/" + pi.name 5996 + " does not allow granting of permission to path of Uri " 5997 + uri); 5998 } 5999 } 6000 6001 // Third... does the caller itself have permission to access 6002 // this uri? 6003 if (callingUid != Process.myUid()) { 6004 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6005 // Require they hold a strong enough Uri permission 6006 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6007 : UriPermission.STRENGTH_OWNED; 6008 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6009 throw new SecurityException("Uid " + callingUid 6010 + " does not have permission to uri " + uri); 6011 } 6012 } 6013 } 6014 6015 return targetUid; 6016 } 6017 6018 @Override 6019 public int checkGrantUriPermission(int callingUid, String targetPkg, 6020 Uri uri, int modeFlags) { 6021 enforceNotIsolatedCaller("checkGrantUriPermission"); 6022 synchronized(this) { 6023 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6024 } 6025 } 6026 6027 void grantUriPermissionUncheckedLocked( 6028 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6029 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6030 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6031 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6032 if (modeFlags == 0) { 6033 return; 6034 } 6035 6036 // So here we are: the caller has the assumed permission 6037 // to the uri, and the target doesn't. Let's now give this to 6038 // the target. 6039 6040 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6041 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6042 6043 final String authority = uri.getAuthority(); 6044 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6045 if (pi == null) { 6046 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6047 return; 6048 } 6049 6050 final UriPermission perm = findOrCreateUriPermissionLocked( 6051 pi.packageName, targetPkg, targetUid, uri); 6052 perm.grantModes(modeFlags, persistable, owner); 6053 } 6054 6055 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6056 int modeFlags, UriPermissionOwner owner) { 6057 if (targetPkg == null) { 6058 throw new NullPointerException("targetPkg"); 6059 } 6060 6061 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6062 if (targetUid < 0) { 6063 return; 6064 } 6065 6066 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6067 } 6068 6069 static class NeededUriGrants extends ArrayList<Uri> { 6070 final String targetPkg; 6071 final int targetUid; 6072 final int flags; 6073 6074 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6075 this.targetPkg = targetPkg; 6076 this.targetUid = targetUid; 6077 this.flags = flags; 6078 } 6079 } 6080 6081 /** 6082 * Like checkGrantUriPermissionLocked, but takes an Intent. 6083 */ 6084 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6085 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6086 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6087 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6088 + " clip=" + (intent != null ? intent.getClipData() : null) 6089 + " from " + intent + "; flags=0x" 6090 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6091 6092 if (targetPkg == null) { 6093 throw new NullPointerException("targetPkg"); 6094 } 6095 6096 if (intent == null) { 6097 return null; 6098 } 6099 Uri data = intent.getData(); 6100 ClipData clip = intent.getClipData(); 6101 if (data == null && clip == null) { 6102 return null; 6103 } 6104 6105 if (data != null) { 6106 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6107 mode, needed != null ? needed.targetUid : -1); 6108 if (targetUid > 0) { 6109 if (needed == null) { 6110 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6111 } 6112 needed.add(data); 6113 } 6114 } 6115 if (clip != null) { 6116 for (int i=0; i<clip.getItemCount(); i++) { 6117 Uri uri = clip.getItemAt(i).getUri(); 6118 if (uri != null) { 6119 int targetUid = -1; 6120 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6121 mode, needed != null ? needed.targetUid : -1); 6122 if (targetUid > 0) { 6123 if (needed == null) { 6124 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6125 } 6126 needed.add(uri); 6127 } 6128 } else { 6129 Intent clipIntent = clip.getItemAt(i).getIntent(); 6130 if (clipIntent != null) { 6131 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6132 callingUid, targetPkg, clipIntent, mode, needed); 6133 if (newNeeded != null) { 6134 needed = newNeeded; 6135 } 6136 } 6137 } 6138 } 6139 } 6140 6141 return needed; 6142 } 6143 6144 /** 6145 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6146 */ 6147 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6148 UriPermissionOwner owner) { 6149 if (needed != null) { 6150 for (int i=0; i<needed.size(); i++) { 6151 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6152 needed.get(i), needed.flags, owner); 6153 } 6154 } 6155 } 6156 6157 void grantUriPermissionFromIntentLocked(int callingUid, 6158 String targetPkg, Intent intent, UriPermissionOwner owner) { 6159 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6160 intent, intent != null ? intent.getFlags() : 0, null); 6161 if (needed == null) { 6162 return; 6163 } 6164 6165 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6166 } 6167 6168 @Override 6169 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6170 Uri uri, int modeFlags) { 6171 enforceNotIsolatedCaller("grantUriPermission"); 6172 synchronized(this) { 6173 final ProcessRecord r = getRecordForAppLocked(caller); 6174 if (r == null) { 6175 throw new SecurityException("Unable to find app for caller " 6176 + caller 6177 + " when granting permission to uri " + uri); 6178 } 6179 if (targetPkg == null) { 6180 throw new IllegalArgumentException("null target"); 6181 } 6182 if (uri == null) { 6183 throw new IllegalArgumentException("null uri"); 6184 } 6185 6186 // Persistable only supported through Intents 6187 Preconditions.checkFlagsArgument(modeFlags, 6188 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6189 6190 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6191 null); 6192 } 6193 } 6194 6195 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6196 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6197 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6198 ArrayMap<Uri, UriPermission> perms 6199 = mGrantedUriPermissions.get(perm.targetUid); 6200 if (perms != null) { 6201 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6202 "Removing " + perm.targetUid + " permission to " + perm.uri); 6203 perms.remove(perm.uri); 6204 if (perms.size() == 0) { 6205 mGrantedUriPermissions.remove(perm.targetUid); 6206 } 6207 } 6208 } 6209 } 6210 6211 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6212 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6213 6214 final IPackageManager pm = AppGlobals.getPackageManager(); 6215 final String authority = uri.getAuthority(); 6216 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6217 if (pi == null) { 6218 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6219 return; 6220 } 6221 6222 // Does the caller have this permission on the URI? 6223 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6224 // Right now, if you are not the original owner of the permission, 6225 // you are not allowed to revoke it. 6226 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6227 throw new SecurityException("Uid " + callingUid 6228 + " does not have permission to uri " + uri); 6229 //} 6230 } 6231 6232 boolean persistChanged = false; 6233 6234 // Go through all of the permissions and remove any that match. 6235 final List<String> SEGMENTS = uri.getPathSegments(); 6236 if (SEGMENTS != null) { 6237 final int NS = SEGMENTS.size(); 6238 int N = mGrantedUriPermissions.size(); 6239 for (int i=0; i<N; i++) { 6240 ArrayMap<Uri, UriPermission> perms 6241 = mGrantedUriPermissions.valueAt(i); 6242 Iterator<UriPermission> it = perms.values().iterator(); 6243 toploop: 6244 while (it.hasNext()) { 6245 UriPermission perm = it.next(); 6246 Uri targetUri = perm.uri; 6247 if (!authority.equals(targetUri.getAuthority())) { 6248 continue; 6249 } 6250 List<String> targetSegments = targetUri.getPathSegments(); 6251 if (targetSegments == null) { 6252 continue; 6253 } 6254 if (targetSegments.size() < NS) { 6255 continue; 6256 } 6257 for (int j=0; j<NS; j++) { 6258 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6259 continue toploop; 6260 } 6261 } 6262 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6263 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6264 persistChanged |= perm.clearModes(modeFlags, true); 6265 if (perm.modeFlags == 0) { 6266 it.remove(); 6267 } 6268 } 6269 if (perms.size() == 0) { 6270 mGrantedUriPermissions.remove( 6271 mGrantedUriPermissions.keyAt(i)); 6272 N--; 6273 i--; 6274 } 6275 } 6276 } 6277 6278 if (persistChanged) { 6279 schedulePersistUriGrants(); 6280 } 6281 } 6282 6283 @Override 6284 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6285 int modeFlags) { 6286 enforceNotIsolatedCaller("revokeUriPermission"); 6287 synchronized(this) { 6288 final ProcessRecord r = getRecordForAppLocked(caller); 6289 if (r == null) { 6290 throw new SecurityException("Unable to find app for caller " 6291 + caller 6292 + " when revoking permission to uri " + uri); 6293 } 6294 if (uri == null) { 6295 Slog.w(TAG, "revokeUriPermission: null uri"); 6296 return; 6297 } 6298 6299 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6300 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6301 if (modeFlags == 0) { 6302 return; 6303 } 6304 6305 final IPackageManager pm = AppGlobals.getPackageManager(); 6306 final String authority = uri.getAuthority(); 6307 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6308 if (pi == null) { 6309 Slog.w(TAG, "No content provider found for permission revoke: " 6310 + uri.toSafeString()); 6311 return; 6312 } 6313 6314 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6315 } 6316 } 6317 6318 /** 6319 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6320 * given package. 6321 * 6322 * @param packageName Package name to match, or {@code null} to apply to all 6323 * packages. 6324 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6325 * to all users. 6326 * @param persistable If persistable grants should be removed. 6327 */ 6328 private void removeUriPermissionsForPackageLocked( 6329 String packageName, int userHandle, boolean persistable) { 6330 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6331 throw new IllegalArgumentException("Must narrow by either package or user"); 6332 } 6333 6334 boolean persistChanged = false; 6335 6336 final int size = mGrantedUriPermissions.size(); 6337 for (int i = 0; i < size; i++) { 6338 // Only inspect grants matching user 6339 if (userHandle == UserHandle.USER_ALL 6340 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6341 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6342 .values().iterator(); 6343 while (it.hasNext()) { 6344 final UriPermission perm = it.next(); 6345 6346 // Only inspect grants matching package 6347 if (packageName == null || perm.sourcePkg.equals(packageName) 6348 || perm.targetPkg.equals(packageName)) { 6349 persistChanged |= perm.clearModes(~0, persistable); 6350 6351 // Only remove when no modes remain; any persisted grants 6352 // will keep this alive. 6353 if (perm.modeFlags == 0) { 6354 it.remove(); 6355 } 6356 } 6357 } 6358 } 6359 } 6360 6361 if (persistChanged) { 6362 schedulePersistUriGrants(); 6363 } 6364 } 6365 6366 @Override 6367 public IBinder newUriPermissionOwner(String name) { 6368 enforceNotIsolatedCaller("newUriPermissionOwner"); 6369 synchronized(this) { 6370 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6371 return owner.getExternalTokenLocked(); 6372 } 6373 } 6374 6375 @Override 6376 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6377 Uri uri, int modeFlags) { 6378 synchronized(this) { 6379 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6380 if (owner == null) { 6381 throw new IllegalArgumentException("Unknown owner: " + token); 6382 } 6383 if (fromUid != Binder.getCallingUid()) { 6384 if (Binder.getCallingUid() != Process.myUid()) { 6385 // Only system code can grant URI permissions on behalf 6386 // of other users. 6387 throw new SecurityException("nice try"); 6388 } 6389 } 6390 if (targetPkg == null) { 6391 throw new IllegalArgumentException("null target"); 6392 } 6393 if (uri == null) { 6394 throw new IllegalArgumentException("null uri"); 6395 } 6396 6397 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6398 } 6399 } 6400 6401 @Override 6402 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6403 synchronized(this) { 6404 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6405 if (owner == null) { 6406 throw new IllegalArgumentException("Unknown owner: " + token); 6407 } 6408 6409 if (uri == null) { 6410 owner.removeUriPermissionsLocked(mode); 6411 } else { 6412 owner.removeUriPermissionLocked(uri, mode); 6413 } 6414 } 6415 } 6416 6417 private void schedulePersistUriGrants() { 6418 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6419 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6420 10 * DateUtils.SECOND_IN_MILLIS); 6421 } 6422 } 6423 6424 private void writeGrantedUriPermissions() { 6425 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6426 6427 // Snapshot permissions so we can persist without lock 6428 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6429 synchronized (this) { 6430 final int size = mGrantedUriPermissions.size(); 6431 for (int i = 0 ; i < size; i++) { 6432 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6433 if (perm.persistedModeFlags != 0) { 6434 persist.add(perm.snapshot()); 6435 } 6436 } 6437 } 6438 } 6439 6440 FileOutputStream fos = null; 6441 try { 6442 fos = mGrantFile.startWrite(); 6443 6444 XmlSerializer out = new FastXmlSerializer(); 6445 out.setOutput(fos, "utf-8"); 6446 out.startDocument(null, true); 6447 out.startTag(null, TAG_URI_GRANTS); 6448 for (UriPermission.Snapshot perm : persist) { 6449 out.startTag(null, TAG_URI_GRANT); 6450 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6451 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6452 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6453 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6454 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6455 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6456 out.endTag(null, TAG_URI_GRANT); 6457 } 6458 out.endTag(null, TAG_URI_GRANTS); 6459 out.endDocument(); 6460 6461 mGrantFile.finishWrite(fos); 6462 } catch (IOException e) { 6463 if (fos != null) { 6464 mGrantFile.failWrite(fos); 6465 } 6466 } 6467 } 6468 6469 private void readGrantedUriPermissionsLocked() { 6470 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6471 6472 final long now = System.currentTimeMillis(); 6473 6474 FileInputStream fis = null; 6475 try { 6476 fis = mGrantFile.openRead(); 6477 final XmlPullParser in = Xml.newPullParser(); 6478 in.setInput(fis, null); 6479 6480 int type; 6481 while ((type = in.next()) != END_DOCUMENT) { 6482 final String tag = in.getName(); 6483 if (type == START_TAG) { 6484 if (TAG_URI_GRANT.equals(tag)) { 6485 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6486 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6487 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6488 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6489 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6490 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6491 6492 // Sanity check that provider still belongs to source package 6493 final ProviderInfo pi = getProviderInfoLocked( 6494 uri.getAuthority(), userHandle); 6495 if (pi != null && sourcePkg.equals(pi.packageName)) { 6496 int targetUid = -1; 6497 try { 6498 targetUid = AppGlobals.getPackageManager() 6499 .getPackageUid(targetPkg, userHandle); 6500 } catch (RemoteException e) { 6501 } 6502 if (targetUid != -1) { 6503 final UriPermission perm = findOrCreateUriPermissionLocked( 6504 sourcePkg, targetPkg, targetUid, uri); 6505 perm.initPersistedModes(modeFlags, createdTime); 6506 } 6507 } else { 6508 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6509 + " but instead found " + pi); 6510 } 6511 } 6512 } 6513 } 6514 } catch (FileNotFoundException e) { 6515 // Missing grants is okay 6516 } catch (IOException e) { 6517 Log.wtf(TAG, "Failed reading Uri grants", e); 6518 } catch (XmlPullParserException e) { 6519 Log.wtf(TAG, "Failed reading Uri grants", e); 6520 } finally { 6521 IoUtils.closeQuietly(fis); 6522 } 6523 } 6524 6525 @Override 6526 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6527 enforceNotIsolatedCaller("takePersistableUriPermission"); 6528 6529 Preconditions.checkFlagsArgument(modeFlags, 6530 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6531 6532 synchronized (this) { 6533 final int callingUid = Binder.getCallingUid(); 6534 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6535 if (perm == null) { 6536 throw new SecurityException("No permission grant found for UID " + callingUid 6537 + " and Uri " + uri.toSafeString()); 6538 } 6539 6540 boolean persistChanged = perm.takePersistableModes(modeFlags); 6541 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6542 6543 if (persistChanged) { 6544 schedulePersistUriGrants(); 6545 } 6546 } 6547 } 6548 6549 @Override 6550 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6551 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6552 6553 Preconditions.checkFlagsArgument(modeFlags, 6554 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6555 6556 synchronized (this) { 6557 final int callingUid = Binder.getCallingUid(); 6558 6559 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6560 if (perm == null) { 6561 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6562 + uri.toSafeString()); 6563 return; 6564 } 6565 6566 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6567 removeUriPermissionIfNeededLocked(perm); 6568 if (persistChanged) { 6569 schedulePersistUriGrants(); 6570 } 6571 } 6572 } 6573 6574 /** 6575 * Prune any older {@link UriPermission} for the given UID until outstanding 6576 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6577 * 6578 * @return if any mutations occured that require persisting. 6579 */ 6580 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6581 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6582 if (perms == null) return false; 6583 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6584 6585 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6586 for (UriPermission perm : perms.values()) { 6587 if (perm.persistedModeFlags != 0) { 6588 persisted.add(perm); 6589 } 6590 } 6591 6592 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6593 if (trimCount <= 0) return false; 6594 6595 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6596 for (int i = 0; i < trimCount; i++) { 6597 final UriPermission perm = persisted.get(i); 6598 6599 if (DEBUG_URI_PERMISSION) { 6600 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6601 } 6602 6603 perm.releasePersistableModes(~0); 6604 removeUriPermissionIfNeededLocked(perm); 6605 } 6606 6607 return true; 6608 } 6609 6610 @Override 6611 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6612 String packageName, boolean incoming) { 6613 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6614 Preconditions.checkNotNull(packageName, "packageName"); 6615 6616 final int callingUid = Binder.getCallingUid(); 6617 final IPackageManager pm = AppGlobals.getPackageManager(); 6618 try { 6619 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6620 if (packageUid != callingUid) { 6621 throw new SecurityException( 6622 "Package " + packageName + " does not belong to calling UID " + callingUid); 6623 } 6624 } catch (RemoteException e) { 6625 throw new SecurityException("Failed to verify package name ownership"); 6626 } 6627 6628 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6629 synchronized (this) { 6630 if (incoming) { 6631 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6632 if (perms == null) { 6633 Slog.w(TAG, "No permission grants found for " + packageName); 6634 } else { 6635 final int size = perms.size(); 6636 for (int i = 0; i < size; i++) { 6637 final UriPermission perm = perms.valueAt(i); 6638 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6639 result.add(perm.buildPersistedPublicApiObject()); 6640 } 6641 } 6642 } 6643 } else { 6644 final int size = mGrantedUriPermissions.size(); 6645 for (int i = 0; i < size; i++) { 6646 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6647 final int permsSize = perms.size(); 6648 for (int j = 0; j < permsSize; j++) { 6649 final UriPermission perm = perms.valueAt(j); 6650 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6651 result.add(perm.buildPersistedPublicApiObject()); 6652 } 6653 } 6654 } 6655 } 6656 } 6657 return new ParceledListSlice<android.content.UriPermission>(result); 6658 } 6659 6660 @Override 6661 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6662 synchronized (this) { 6663 ProcessRecord app = 6664 who != null ? getRecordForAppLocked(who) : null; 6665 if (app == null) return; 6666 6667 Message msg = Message.obtain(); 6668 msg.what = WAIT_FOR_DEBUGGER_MSG; 6669 msg.obj = app; 6670 msg.arg1 = waiting ? 1 : 0; 6671 mHandler.sendMessage(msg); 6672 } 6673 } 6674 6675 @Override 6676 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6677 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6678 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6679 outInfo.availMem = Process.getFreeMemory(); 6680 outInfo.totalMem = Process.getTotalMemory(); 6681 outInfo.threshold = homeAppMem; 6682 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6683 outInfo.hiddenAppThreshold = cachedAppMem; 6684 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6685 ProcessList.SERVICE_ADJ); 6686 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6687 ProcessList.VISIBLE_APP_ADJ); 6688 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6689 ProcessList.FOREGROUND_APP_ADJ); 6690 } 6691 6692 // ========================================================= 6693 // TASK MANAGEMENT 6694 // ========================================================= 6695 6696 @Override 6697 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6698 IThumbnailReceiver receiver) { 6699 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6700 6701 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6702 ActivityRecord topRecord = null; 6703 6704 synchronized(this) { 6705 if (localLOGV) Slog.v( 6706 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6707 + ", receiver=" + receiver); 6708 6709 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6710 != PackageManager.PERMISSION_GRANTED) { 6711 if (receiver != null) { 6712 // If the caller wants to wait for pending thumbnails, 6713 // it ain't gonna get them. 6714 try { 6715 receiver.finished(); 6716 } catch (RemoteException ex) { 6717 } 6718 } 6719 String msg = "Permission Denial: getTasks() from pid=" 6720 + Binder.getCallingPid() 6721 + ", uid=" + Binder.getCallingUid() 6722 + " requires " + android.Manifest.permission.GET_TASKS; 6723 Slog.w(TAG, msg); 6724 throw new SecurityException(msg); 6725 } 6726 6727 // TODO: Improve with MRU list from all ActivityStacks. 6728 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6729 6730 if (!pending.pendingRecords.isEmpty()) { 6731 mPendingThumbnails.add(pending); 6732 } 6733 } 6734 6735 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6736 6737 if (topRecord != null) { 6738 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6739 try { 6740 IApplicationThread topThumbnail = topRecord.app.thread; 6741 topThumbnail.requestThumbnail(topRecord.appToken); 6742 } catch (Exception e) { 6743 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6744 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6745 } 6746 } 6747 6748 if (pending == null && receiver != null) { 6749 // In this case all thumbnails were available and the client 6750 // is being asked to be told when the remaining ones come in... 6751 // which is unusually, since the top-most currently running 6752 // activity should never have a canned thumbnail! Oh well. 6753 try { 6754 receiver.finished(); 6755 } catch (RemoteException ex) { 6756 } 6757 } 6758 6759 return list; 6760 } 6761 6762 TaskRecord getMostRecentTask() { 6763 return mRecentTasks.get(0); 6764 } 6765 6766 @Override 6767 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6768 int flags, int userId) { 6769 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6770 false, true, "getRecentTasks", null); 6771 6772 synchronized (this) { 6773 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6774 "getRecentTasks()"); 6775 final boolean detailed = checkCallingPermission( 6776 android.Manifest.permission.GET_DETAILED_TASKS) 6777 == PackageManager.PERMISSION_GRANTED; 6778 6779 IPackageManager pm = AppGlobals.getPackageManager(); 6780 6781 final int N = mRecentTasks.size(); 6782 ArrayList<ActivityManager.RecentTaskInfo> res 6783 = new ArrayList<ActivityManager.RecentTaskInfo>( 6784 maxNum < N ? maxNum : N); 6785 for (int i=0; i<N && maxNum > 0; i++) { 6786 TaskRecord tr = mRecentTasks.get(i); 6787 // Only add calling user's recent tasks 6788 if (tr.userId != userId) continue; 6789 // Return the entry if desired by the caller. We always return 6790 // the first entry, because callers always expect this to be the 6791 // foreground app. We may filter others if the caller has 6792 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6793 // we should exclude the entry. 6794 6795 if (i == 0 6796 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6797 || (tr.intent == null) 6798 || ((tr.intent.getFlags() 6799 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6800 ActivityManager.RecentTaskInfo rti 6801 = new ActivityManager.RecentTaskInfo(); 6802 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6803 rti.persistentId = tr.taskId; 6804 rti.baseIntent = new Intent( 6805 tr.intent != null ? tr.intent : tr.affinityIntent); 6806 if (!detailed) { 6807 rti.baseIntent.replaceExtras((Bundle)null); 6808 } 6809 rti.origActivity = tr.origActivity; 6810 rti.description = tr.lastDescription; 6811 rti.stackId = tr.stack.mStackId; 6812 6813 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6814 // Check whether this activity is currently available. 6815 try { 6816 if (rti.origActivity != null) { 6817 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6818 == null) { 6819 continue; 6820 } 6821 } else if (rti.baseIntent != null) { 6822 if (pm.queryIntentActivities(rti.baseIntent, 6823 null, 0, userId) == null) { 6824 continue; 6825 } 6826 } 6827 } catch (RemoteException e) { 6828 // Will never happen. 6829 } 6830 } 6831 6832 res.add(rti); 6833 maxNum--; 6834 } 6835 } 6836 return res; 6837 } 6838 } 6839 6840 private TaskRecord recentTaskForIdLocked(int id) { 6841 final int N = mRecentTasks.size(); 6842 for (int i=0; i<N; i++) { 6843 TaskRecord tr = mRecentTasks.get(i); 6844 if (tr.taskId == id) { 6845 return tr; 6846 } 6847 } 6848 return null; 6849 } 6850 6851 @Override 6852 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6853 synchronized (this) { 6854 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6855 "getTaskThumbnails()"); 6856 TaskRecord tr = recentTaskForIdLocked(id); 6857 if (tr != null) { 6858 return tr.getTaskThumbnailsLocked(); 6859 } 6860 } 6861 return null; 6862 } 6863 6864 @Override 6865 public Bitmap getTaskTopThumbnail(int id) { 6866 synchronized (this) { 6867 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6868 "getTaskTopThumbnail()"); 6869 TaskRecord tr = recentTaskForIdLocked(id); 6870 if (tr != null) { 6871 return tr.getTaskTopThumbnailLocked(); 6872 } 6873 } 6874 return null; 6875 } 6876 6877 @Override 6878 public boolean removeSubTask(int taskId, int subTaskIndex) { 6879 synchronized (this) { 6880 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6881 "removeSubTask()"); 6882 long ident = Binder.clearCallingIdentity(); 6883 try { 6884 TaskRecord tr = recentTaskForIdLocked(taskId); 6885 if (tr != null) { 6886 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6887 } 6888 return false; 6889 } finally { 6890 Binder.restoreCallingIdentity(ident); 6891 } 6892 } 6893 } 6894 6895 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6896 if (!pr.killedByAm) { 6897 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6898 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6899 pr.processName, pr.setAdj, reason); 6900 pr.killedByAm = true; 6901 Process.killProcessQuiet(pr.pid); 6902 } 6903 } 6904 6905 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6906 tr.disposeThumbnail(); 6907 mRecentTasks.remove(tr); 6908 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6909 Intent baseIntent = new Intent( 6910 tr.intent != null ? tr.intent : tr.affinityIntent); 6911 ComponentName component = baseIntent.getComponent(); 6912 if (component == null) { 6913 Slog.w(TAG, "Now component for base intent of task: " + tr); 6914 return; 6915 } 6916 6917 // Find any running services associated with this app. 6918 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6919 6920 if (killProcesses) { 6921 // Find any running processes associated with this app. 6922 final String pkg = component.getPackageName(); 6923 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6924 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 6925 for (int i=0; i<pmap.size(); i++) { 6926 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 6927 for (int j=0; j<uids.size(); j++) { 6928 ProcessRecord proc = uids.valueAt(j); 6929 if (proc.userId != tr.userId) { 6930 continue; 6931 } 6932 if (!proc.pkgList.containsKey(pkg)) { 6933 continue; 6934 } 6935 procs.add(proc); 6936 } 6937 } 6938 6939 // Kill the running processes. 6940 for (int i=0; i<procs.size(); i++) { 6941 ProcessRecord pr = procs.get(i); 6942 if (pr == mHomeProcess) { 6943 // Don't kill the home process along with tasks from the same package. 6944 continue; 6945 } 6946 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 6947 killUnneededProcessLocked(pr, "remove task"); 6948 } else { 6949 pr.waitingToKill = "remove task"; 6950 } 6951 } 6952 } 6953 } 6954 6955 @Override 6956 public boolean removeTask(int taskId, int flags) { 6957 synchronized (this) { 6958 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6959 "removeTask()"); 6960 long ident = Binder.clearCallingIdentity(); 6961 try { 6962 TaskRecord tr = recentTaskForIdLocked(taskId); 6963 if (tr != null) { 6964 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 6965 if (r != null) { 6966 cleanUpRemovedTaskLocked(tr, flags); 6967 return true; 6968 } 6969 if (tr.mActivities.size() == 0) { 6970 // Caller is just removing a recent task that is 6971 // not actively running. That is easy! 6972 cleanUpRemovedTaskLocked(tr, flags); 6973 return true; 6974 } 6975 Slog.w(TAG, "removeTask: task " + taskId 6976 + " does not have activities to remove, " 6977 + " but numActivities=" + tr.numActivities 6978 + ": " + tr); 6979 } 6980 } finally { 6981 Binder.restoreCallingIdentity(ident); 6982 } 6983 } 6984 return false; 6985 } 6986 6987 /** 6988 * TODO: Add mController hook 6989 */ 6990 @Override 6991 public void moveTaskToFront(int task, int flags, Bundle options) { 6992 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6993 "moveTaskToFront()"); 6994 6995 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task); 6996 synchronized(this) { 6997 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6998 Binder.getCallingUid(), "Task to front")) { 6999 ActivityOptions.abort(options); 7000 return; 7001 } 7002 final long origId = Binder.clearCallingIdentity(); 7003 try { 7004 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7005 } finally { 7006 Binder.restoreCallingIdentity(origId); 7007 } 7008 ActivityOptions.abort(options); 7009 } 7010 } 7011 7012 @Override 7013 public void moveTaskToBack(int taskId) { 7014 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7015 "moveTaskToBack()"); 7016 7017 synchronized(this) { 7018 TaskRecord tr = recentTaskForIdLocked(taskId); 7019 if (tr != null) { 7020 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7021 ActivityStack stack = tr.stack; 7022 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7023 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7024 Binder.getCallingUid(), "Task to back")) { 7025 return; 7026 } 7027 } 7028 final long origId = Binder.clearCallingIdentity(); 7029 try { 7030 stack.moveTaskToBackLocked(taskId, null); 7031 } finally { 7032 Binder.restoreCallingIdentity(origId); 7033 } 7034 } 7035 } 7036 } 7037 7038 /** 7039 * Moves an activity, and all of the other activities within the same task, to the bottom 7040 * of the history stack. The activity's order within the task is unchanged. 7041 * 7042 * @param token A reference to the activity we wish to move 7043 * @param nonRoot If false then this only works if the activity is the root 7044 * of a task; if true it will work for any activity in a task. 7045 * @return Returns true if the move completed, false if not. 7046 */ 7047 @Override 7048 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7049 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7050 synchronized(this) { 7051 final long origId = Binder.clearCallingIdentity(); 7052 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7053 if (taskId >= 0) { 7054 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7055 } 7056 Binder.restoreCallingIdentity(origId); 7057 } 7058 return false; 7059 } 7060 7061 @Override 7062 public void moveTaskBackwards(int task) { 7063 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7064 "moveTaskBackwards()"); 7065 7066 synchronized(this) { 7067 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7068 Binder.getCallingUid(), "Task backwards")) { 7069 return; 7070 } 7071 final long origId = Binder.clearCallingIdentity(); 7072 moveTaskBackwardsLocked(task); 7073 Binder.restoreCallingIdentity(origId); 7074 } 7075 } 7076 7077 private final void moveTaskBackwardsLocked(int task) { 7078 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7079 } 7080 7081 @Override 7082 public IBinder getHomeActivityToken() throws RemoteException { 7083 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7084 "getHomeActivityToken()"); 7085 synchronized (this) { 7086 return mStackSupervisor.getHomeActivityToken(); 7087 } 7088 } 7089 7090 @Override 7091 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7092 IActivityContainerCallback callback) throws RemoteException { 7093 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7094 "createActivityContainer()"); 7095 synchronized (this) { 7096 if (parentActivityToken == null) { 7097 throw new IllegalArgumentException("parent token must not be null"); 7098 } 7099 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7100 if (r == null) { 7101 return null; 7102 } 7103 return mStackSupervisor.createActivityContainer(r, callback); 7104 } 7105 } 7106 7107 @Override 7108 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7109 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7110 "deleteActivityContainer()"); 7111 synchronized (this) { 7112 mStackSupervisor.deleteActivityContainer(container); 7113 } 7114 } 7115 7116 @Override 7117 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7118 throws RemoteException { 7119 synchronized (this) { 7120 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7121 if (stack != null) { 7122 return stack.mActivityContainer; 7123 } 7124 return null; 7125 } 7126 } 7127 7128 @Override 7129 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7130 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7131 "moveTaskToStack()"); 7132 if (stackId == HOME_STACK_ID) { 7133 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7134 new RuntimeException("here").fillInStackTrace()); 7135 } 7136 synchronized (this) { 7137 long ident = Binder.clearCallingIdentity(); 7138 try { 7139 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7140 + stackId + " toTop=" + toTop); 7141 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7142 } finally { 7143 Binder.restoreCallingIdentity(ident); 7144 } 7145 } 7146 } 7147 7148 @Override 7149 public void resizeStack(int stackBoxId, Rect bounds) { 7150 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7151 "resizeStackBox()"); 7152 long ident = Binder.clearCallingIdentity(); 7153 try { 7154 mWindowManager.resizeStack(stackBoxId, bounds); 7155 } finally { 7156 Binder.restoreCallingIdentity(ident); 7157 } 7158 } 7159 7160 @Override 7161 public List<StackInfo> getAllStackInfos() { 7162 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7163 "getAllStackInfos()"); 7164 long ident = Binder.clearCallingIdentity(); 7165 try { 7166 synchronized (this) { 7167 return mStackSupervisor.getAllStackInfosLocked(); 7168 } 7169 } finally { 7170 Binder.restoreCallingIdentity(ident); 7171 } 7172 } 7173 7174 @Override 7175 public StackInfo getStackInfo(int stackId) { 7176 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7177 "getStackInfo()"); 7178 long ident = Binder.clearCallingIdentity(); 7179 try { 7180 synchronized (this) { 7181 return mStackSupervisor.getStackInfoLocked(stackId); 7182 } 7183 } finally { 7184 Binder.restoreCallingIdentity(ident); 7185 } 7186 } 7187 7188 @Override 7189 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7190 synchronized(this) { 7191 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7192 } 7193 } 7194 7195 // ========================================================= 7196 // THUMBNAILS 7197 // ========================================================= 7198 7199 public void reportThumbnail(IBinder token, 7200 Bitmap thumbnail, CharSequence description) { 7201 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7202 final long origId = Binder.clearCallingIdentity(); 7203 sendPendingThumbnail(null, token, thumbnail, description, true); 7204 Binder.restoreCallingIdentity(origId); 7205 } 7206 7207 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7208 Bitmap thumbnail, CharSequence description, boolean always) { 7209 TaskRecord task; 7210 ArrayList<PendingThumbnailsRecord> receivers = null; 7211 7212 //System.out.println("Send pending thumbnail: " + r); 7213 7214 synchronized(this) { 7215 if (r == null) { 7216 r = ActivityRecord.isInStackLocked(token); 7217 if (r == null) { 7218 return; 7219 } 7220 } 7221 if (thumbnail == null && r.thumbHolder != null) { 7222 thumbnail = r.thumbHolder.lastThumbnail; 7223 description = r.thumbHolder.lastDescription; 7224 } 7225 if (thumbnail == null && !always) { 7226 // If there is no thumbnail, and this entry is not actually 7227 // going away, then abort for now and pick up the next 7228 // thumbnail we get. 7229 return; 7230 } 7231 task = r.task; 7232 7233 int N = mPendingThumbnails.size(); 7234 int i=0; 7235 while (i<N) { 7236 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7237 //System.out.println("Looking in " + pr.pendingRecords); 7238 if (pr.pendingRecords.remove(r)) { 7239 if (receivers == null) { 7240 receivers = new ArrayList<PendingThumbnailsRecord>(); 7241 } 7242 receivers.add(pr); 7243 if (pr.pendingRecords.size() == 0) { 7244 pr.finished = true; 7245 mPendingThumbnails.remove(i); 7246 N--; 7247 continue; 7248 } 7249 } 7250 i++; 7251 } 7252 } 7253 7254 if (receivers != null) { 7255 final int N = receivers.size(); 7256 for (int i=0; i<N; i++) { 7257 try { 7258 PendingThumbnailsRecord pr = receivers.get(i); 7259 pr.receiver.newThumbnail( 7260 task != null ? task.taskId : -1, thumbnail, description); 7261 if (pr.finished) { 7262 pr.receiver.finished(); 7263 } 7264 } catch (Exception e) { 7265 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7266 } 7267 } 7268 } 7269 } 7270 7271 // ========================================================= 7272 // CONTENT PROVIDERS 7273 // ========================================================= 7274 7275 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7276 List<ProviderInfo> providers = null; 7277 try { 7278 providers = AppGlobals.getPackageManager(). 7279 queryContentProviders(app.processName, app.uid, 7280 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7281 } catch (RemoteException ex) { 7282 } 7283 if (DEBUG_MU) 7284 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7285 int userId = app.userId; 7286 if (providers != null) { 7287 int N = providers.size(); 7288 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7289 for (int i=0; i<N; i++) { 7290 ProviderInfo cpi = 7291 (ProviderInfo)providers.get(i); 7292 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7293 cpi.name, cpi.flags); 7294 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7295 // This is a singleton provider, but a user besides the 7296 // default user is asking to initialize a process it runs 7297 // in... well, no, it doesn't actually run in this process, 7298 // it runs in the process of the default user. Get rid of it. 7299 providers.remove(i); 7300 N--; 7301 i--; 7302 continue; 7303 } 7304 7305 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7306 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7307 if (cpr == null) { 7308 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7309 mProviderMap.putProviderByClass(comp, cpr); 7310 } 7311 if (DEBUG_MU) 7312 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7313 app.pubProviders.put(cpi.name, cpr); 7314 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7315 // Don't add this if it is a platform component that is marked 7316 // to run in multiple processes, because this is actually 7317 // part of the framework so doesn't make sense to track as a 7318 // separate apk in the process. 7319 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7320 } 7321 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7322 } 7323 } 7324 return providers; 7325 } 7326 7327 /** 7328 * Check if {@link ProcessRecord} has a possible chance at accessing the 7329 * given {@link ProviderInfo}. Final permission checking is always done 7330 * in {@link ContentProvider}. 7331 */ 7332 private final String checkContentProviderPermissionLocked( 7333 ProviderInfo cpi, ProcessRecord r) { 7334 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7335 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7336 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7337 cpi.applicationInfo.uid, cpi.exported) 7338 == PackageManager.PERMISSION_GRANTED) { 7339 return null; 7340 } 7341 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7342 cpi.applicationInfo.uid, cpi.exported) 7343 == PackageManager.PERMISSION_GRANTED) { 7344 return null; 7345 } 7346 7347 PathPermission[] pps = cpi.pathPermissions; 7348 if (pps != null) { 7349 int i = pps.length; 7350 while (i > 0) { 7351 i--; 7352 PathPermission pp = pps[i]; 7353 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7354 cpi.applicationInfo.uid, cpi.exported) 7355 == PackageManager.PERMISSION_GRANTED) { 7356 return null; 7357 } 7358 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7359 cpi.applicationInfo.uid, cpi.exported) 7360 == PackageManager.PERMISSION_GRANTED) { 7361 return null; 7362 } 7363 } 7364 } 7365 7366 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7367 if (perms != null) { 7368 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7369 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7370 return null; 7371 } 7372 } 7373 } 7374 7375 String msg; 7376 if (!cpi.exported) { 7377 msg = "Permission Denial: opening provider " + cpi.name 7378 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7379 + ", uid=" + callingUid + ") that is not exported from uid " 7380 + cpi.applicationInfo.uid; 7381 } else { 7382 msg = "Permission Denial: opening provider " + cpi.name 7383 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7384 + ", uid=" + callingUid + ") requires " 7385 + cpi.readPermission + " or " + cpi.writePermission; 7386 } 7387 Slog.w(TAG, msg); 7388 return msg; 7389 } 7390 7391 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7392 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7393 if (r != null) { 7394 for (int i=0; i<r.conProviders.size(); i++) { 7395 ContentProviderConnection conn = r.conProviders.get(i); 7396 if (conn.provider == cpr) { 7397 if (DEBUG_PROVIDER) Slog.v(TAG, 7398 "Adding provider requested by " 7399 + r.processName + " from process " 7400 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7401 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7402 if (stable) { 7403 conn.stableCount++; 7404 conn.numStableIncs++; 7405 } else { 7406 conn.unstableCount++; 7407 conn.numUnstableIncs++; 7408 } 7409 return conn; 7410 } 7411 } 7412 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7413 if (stable) { 7414 conn.stableCount = 1; 7415 conn.numStableIncs = 1; 7416 } else { 7417 conn.unstableCount = 1; 7418 conn.numUnstableIncs = 1; 7419 } 7420 cpr.connections.add(conn); 7421 r.conProviders.add(conn); 7422 return conn; 7423 } 7424 cpr.addExternalProcessHandleLocked(externalProcessToken); 7425 return null; 7426 } 7427 7428 boolean decProviderCountLocked(ContentProviderConnection conn, 7429 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7430 if (conn != null) { 7431 cpr = conn.provider; 7432 if (DEBUG_PROVIDER) Slog.v(TAG, 7433 "Removing provider requested by " 7434 + conn.client.processName + " from process " 7435 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7436 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7437 if (stable) { 7438 conn.stableCount--; 7439 } else { 7440 conn.unstableCount--; 7441 } 7442 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7443 cpr.connections.remove(conn); 7444 conn.client.conProviders.remove(conn); 7445 return true; 7446 } 7447 return false; 7448 } 7449 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7450 return false; 7451 } 7452 7453 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7454 String name, IBinder token, boolean stable, int userId) { 7455 ContentProviderRecord cpr; 7456 ContentProviderConnection conn = null; 7457 ProviderInfo cpi = null; 7458 7459 synchronized(this) { 7460 ProcessRecord r = null; 7461 if (caller != null) { 7462 r = getRecordForAppLocked(caller); 7463 if (r == null) { 7464 throw new SecurityException( 7465 "Unable to find app for caller " + caller 7466 + " (pid=" + Binder.getCallingPid() 7467 + ") when getting content provider " + name); 7468 } 7469 } 7470 7471 // First check if this content provider has been published... 7472 cpr = mProviderMap.getProviderByName(name, userId); 7473 boolean providerRunning = cpr != null; 7474 if (providerRunning) { 7475 cpi = cpr.info; 7476 String msg; 7477 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7478 throw new SecurityException(msg); 7479 } 7480 7481 if (r != null && cpr.canRunHere(r)) { 7482 // This provider has been published or is in the process 7483 // of being published... but it is also allowed to run 7484 // in the caller's process, so don't make a connection 7485 // and just let the caller instantiate its own instance. 7486 ContentProviderHolder holder = cpr.newHolder(null); 7487 // don't give caller the provider object, it needs 7488 // to make its own. 7489 holder.provider = null; 7490 return holder; 7491 } 7492 7493 final long origId = Binder.clearCallingIdentity(); 7494 7495 // In this case the provider instance already exists, so we can 7496 // return it right away. 7497 conn = incProviderCountLocked(r, cpr, token, stable); 7498 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7499 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7500 // If this is a perceptible app accessing the provider, 7501 // make sure to count it as being accessed and thus 7502 // back up on the LRU list. This is good because 7503 // content providers are often expensive to start. 7504 updateLruProcessLocked(cpr.proc, false, null); 7505 } 7506 } 7507 7508 if (cpr.proc != null) { 7509 if (false) { 7510 if (cpr.name.flattenToShortString().equals( 7511 "com.android.providers.calendar/.CalendarProvider2")) { 7512 Slog.v(TAG, "****************** KILLING " 7513 + cpr.name.flattenToShortString()); 7514 Process.killProcess(cpr.proc.pid); 7515 } 7516 } 7517 boolean success = updateOomAdjLocked(cpr.proc); 7518 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7519 // NOTE: there is still a race here where a signal could be 7520 // pending on the process even though we managed to update its 7521 // adj level. Not sure what to do about this, but at least 7522 // the race is now smaller. 7523 if (!success) { 7524 // Uh oh... it looks like the provider's process 7525 // has been killed on us. We need to wait for a new 7526 // process to be started, and make sure its death 7527 // doesn't kill our process. 7528 Slog.i(TAG, 7529 "Existing provider " + cpr.name.flattenToShortString() 7530 + " is crashing; detaching " + r); 7531 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7532 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7533 if (!lastRef) { 7534 // This wasn't the last ref our process had on 7535 // the provider... we have now been killed, bail. 7536 return null; 7537 } 7538 providerRunning = false; 7539 conn = null; 7540 } 7541 } 7542 7543 Binder.restoreCallingIdentity(origId); 7544 } 7545 7546 boolean singleton; 7547 if (!providerRunning) { 7548 try { 7549 cpi = AppGlobals.getPackageManager(). 7550 resolveContentProvider(name, 7551 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7552 } catch (RemoteException ex) { 7553 } 7554 if (cpi == null) { 7555 return null; 7556 } 7557 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7558 cpi.name, cpi.flags); 7559 if (singleton) { 7560 userId = 0; 7561 } 7562 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7563 7564 String msg; 7565 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7566 throw new SecurityException(msg); 7567 } 7568 7569 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7570 && !cpi.processName.equals("system")) { 7571 // If this content provider does not run in the system 7572 // process, and the system is not yet ready to run other 7573 // processes, then fail fast instead of hanging. 7574 throw new IllegalArgumentException( 7575 "Attempt to launch content provider before system ready"); 7576 } 7577 7578 // Make sure that the user who owns this provider is started. If not, 7579 // we don't want to allow it to run. 7580 if (mStartedUsers.get(userId) == null) { 7581 Slog.w(TAG, "Unable to launch app " 7582 + cpi.applicationInfo.packageName + "/" 7583 + cpi.applicationInfo.uid + " for provider " 7584 + name + ": user " + userId + " is stopped"); 7585 return null; 7586 } 7587 7588 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7589 cpr = mProviderMap.getProviderByClass(comp, userId); 7590 final boolean firstClass = cpr == null; 7591 if (firstClass) { 7592 try { 7593 ApplicationInfo ai = 7594 AppGlobals.getPackageManager(). 7595 getApplicationInfo( 7596 cpi.applicationInfo.packageName, 7597 STOCK_PM_FLAGS, userId); 7598 if (ai == null) { 7599 Slog.w(TAG, "No package info for content provider " 7600 + cpi.name); 7601 return null; 7602 } 7603 ai = getAppInfoForUser(ai, userId); 7604 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7605 } catch (RemoteException ex) { 7606 // pm is in same process, this will never happen. 7607 } 7608 } 7609 7610 if (r != null && cpr.canRunHere(r)) { 7611 // If this is a multiprocess provider, then just return its 7612 // info and allow the caller to instantiate it. Only do 7613 // this if the provider is the same user as the caller's 7614 // process, or can run as root (so can be in any process). 7615 return cpr.newHolder(null); 7616 } 7617 7618 if (DEBUG_PROVIDER) { 7619 RuntimeException e = new RuntimeException("here"); 7620 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7621 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7622 } 7623 7624 // This is single process, and our app is now connecting to it. 7625 // See if we are already in the process of launching this 7626 // provider. 7627 final int N = mLaunchingProviders.size(); 7628 int i; 7629 for (i=0; i<N; i++) { 7630 if (mLaunchingProviders.get(i) == cpr) { 7631 break; 7632 } 7633 } 7634 7635 // If the provider is not already being launched, then get it 7636 // started. 7637 if (i >= N) { 7638 final long origId = Binder.clearCallingIdentity(); 7639 7640 try { 7641 // Content provider is now in use, its package can't be stopped. 7642 try { 7643 AppGlobals.getPackageManager().setPackageStoppedState( 7644 cpr.appInfo.packageName, false, userId); 7645 } catch (RemoteException e) { 7646 } catch (IllegalArgumentException e) { 7647 Slog.w(TAG, "Failed trying to unstop package " 7648 + cpr.appInfo.packageName + ": " + e); 7649 } 7650 7651 // Use existing process if already started 7652 ProcessRecord proc = getProcessRecordLocked( 7653 cpi.processName, cpr.appInfo.uid, false); 7654 if (proc != null && proc.thread != null) { 7655 if (DEBUG_PROVIDER) { 7656 Slog.d(TAG, "Installing in existing process " + proc); 7657 } 7658 proc.pubProviders.put(cpi.name, cpr); 7659 try { 7660 proc.thread.scheduleInstallProvider(cpi); 7661 } catch (RemoteException e) { 7662 } 7663 } else { 7664 proc = startProcessLocked(cpi.processName, 7665 cpr.appInfo, false, 0, "content provider", 7666 new ComponentName(cpi.applicationInfo.packageName, 7667 cpi.name), false, false, false); 7668 if (proc == null) { 7669 Slog.w(TAG, "Unable to launch app " 7670 + cpi.applicationInfo.packageName + "/" 7671 + cpi.applicationInfo.uid + " for provider " 7672 + name + ": process is bad"); 7673 return null; 7674 } 7675 } 7676 cpr.launchingApp = proc; 7677 mLaunchingProviders.add(cpr); 7678 } finally { 7679 Binder.restoreCallingIdentity(origId); 7680 } 7681 } 7682 7683 // Make sure the provider is published (the same provider class 7684 // may be published under multiple names). 7685 if (firstClass) { 7686 mProviderMap.putProviderByClass(comp, cpr); 7687 } 7688 7689 mProviderMap.putProviderByName(name, cpr); 7690 conn = incProviderCountLocked(r, cpr, token, stable); 7691 if (conn != null) { 7692 conn.waiting = true; 7693 } 7694 } 7695 } 7696 7697 // Wait for the provider to be published... 7698 synchronized (cpr) { 7699 while (cpr.provider == null) { 7700 if (cpr.launchingApp == null) { 7701 Slog.w(TAG, "Unable to launch app " 7702 + cpi.applicationInfo.packageName + "/" 7703 + cpi.applicationInfo.uid + " for provider " 7704 + name + ": launching app became null"); 7705 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7706 UserHandle.getUserId(cpi.applicationInfo.uid), 7707 cpi.applicationInfo.packageName, 7708 cpi.applicationInfo.uid, name); 7709 return null; 7710 } 7711 try { 7712 if (DEBUG_MU) { 7713 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7714 + cpr.launchingApp); 7715 } 7716 if (conn != null) { 7717 conn.waiting = true; 7718 } 7719 cpr.wait(); 7720 } catch (InterruptedException ex) { 7721 } finally { 7722 if (conn != null) { 7723 conn.waiting = false; 7724 } 7725 } 7726 } 7727 } 7728 return cpr != null ? cpr.newHolder(conn) : null; 7729 } 7730 7731 public final ContentProviderHolder getContentProvider( 7732 IApplicationThread caller, String name, int userId, boolean stable) { 7733 enforceNotIsolatedCaller("getContentProvider"); 7734 if (caller == null) { 7735 String msg = "null IApplicationThread when getting content provider " 7736 + name; 7737 Slog.w(TAG, msg); 7738 throw new SecurityException(msg); 7739 } 7740 7741 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7742 false, true, "getContentProvider", null); 7743 return getContentProviderImpl(caller, name, null, stable, userId); 7744 } 7745 7746 public ContentProviderHolder getContentProviderExternal( 7747 String name, int userId, IBinder token) { 7748 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7749 "Do not have permission in call getContentProviderExternal()"); 7750 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7751 false, true, "getContentProvider", null); 7752 return getContentProviderExternalUnchecked(name, token, userId); 7753 } 7754 7755 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7756 IBinder token, int userId) { 7757 return getContentProviderImpl(null, name, token, true, userId); 7758 } 7759 7760 /** 7761 * Drop a content provider from a ProcessRecord's bookkeeping 7762 */ 7763 public void removeContentProvider(IBinder connection, boolean stable) { 7764 enforceNotIsolatedCaller("removeContentProvider"); 7765 synchronized (this) { 7766 ContentProviderConnection conn; 7767 try { 7768 conn = (ContentProviderConnection)connection; 7769 } catch (ClassCastException e) { 7770 String msg ="removeContentProvider: " + connection 7771 + " not a ContentProviderConnection"; 7772 Slog.w(TAG, msg); 7773 throw new IllegalArgumentException(msg); 7774 } 7775 if (conn == null) { 7776 throw new NullPointerException("connection is null"); 7777 } 7778 if (decProviderCountLocked(conn, null, null, stable)) { 7779 updateOomAdjLocked(); 7780 } 7781 } 7782 } 7783 7784 public void removeContentProviderExternal(String name, IBinder token) { 7785 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7786 "Do not have permission in call removeContentProviderExternal()"); 7787 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7788 } 7789 7790 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7791 synchronized (this) { 7792 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7793 if(cpr == null) { 7794 //remove from mProvidersByClass 7795 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7796 return; 7797 } 7798 7799 //update content provider record entry info 7800 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7801 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7802 if (localCpr.hasExternalProcessHandles()) { 7803 if (localCpr.removeExternalProcessHandleLocked(token)) { 7804 updateOomAdjLocked(); 7805 } else { 7806 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7807 + " with no external reference for token: " 7808 + token + "."); 7809 } 7810 } else { 7811 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7812 + " with no external references."); 7813 } 7814 } 7815 } 7816 7817 public final void publishContentProviders(IApplicationThread caller, 7818 List<ContentProviderHolder> providers) { 7819 if (providers == null) { 7820 return; 7821 } 7822 7823 enforceNotIsolatedCaller("publishContentProviders"); 7824 synchronized (this) { 7825 final ProcessRecord r = getRecordForAppLocked(caller); 7826 if (DEBUG_MU) 7827 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 7828 if (r == null) { 7829 throw new SecurityException( 7830 "Unable to find app for caller " + caller 7831 + " (pid=" + Binder.getCallingPid() 7832 + ") when publishing content providers"); 7833 } 7834 7835 final long origId = Binder.clearCallingIdentity(); 7836 7837 final int N = providers.size(); 7838 for (int i=0; i<N; i++) { 7839 ContentProviderHolder src = providers.get(i); 7840 if (src == null || src.info == null || src.provider == null) { 7841 continue; 7842 } 7843 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 7844 if (DEBUG_MU) 7845 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 7846 if (dst != null) { 7847 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 7848 mProviderMap.putProviderByClass(comp, dst); 7849 String names[] = dst.info.authority.split(";"); 7850 for (int j = 0; j < names.length; j++) { 7851 mProviderMap.putProviderByName(names[j], dst); 7852 } 7853 7854 int NL = mLaunchingProviders.size(); 7855 int j; 7856 for (j=0; j<NL; j++) { 7857 if (mLaunchingProviders.get(j) == dst) { 7858 mLaunchingProviders.remove(j); 7859 j--; 7860 NL--; 7861 } 7862 } 7863 synchronized (dst) { 7864 dst.provider = src.provider; 7865 dst.proc = r; 7866 dst.notifyAll(); 7867 } 7868 updateOomAdjLocked(r); 7869 } 7870 } 7871 7872 Binder.restoreCallingIdentity(origId); 7873 } 7874 } 7875 7876 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 7877 ContentProviderConnection conn; 7878 try { 7879 conn = (ContentProviderConnection)connection; 7880 } catch (ClassCastException e) { 7881 String msg ="refContentProvider: " + connection 7882 + " not a ContentProviderConnection"; 7883 Slog.w(TAG, msg); 7884 throw new IllegalArgumentException(msg); 7885 } 7886 if (conn == null) { 7887 throw new NullPointerException("connection is null"); 7888 } 7889 7890 synchronized (this) { 7891 if (stable > 0) { 7892 conn.numStableIncs += stable; 7893 } 7894 stable = conn.stableCount + stable; 7895 if (stable < 0) { 7896 throw new IllegalStateException("stableCount < 0: " + stable); 7897 } 7898 7899 if (unstable > 0) { 7900 conn.numUnstableIncs += unstable; 7901 } 7902 unstable = conn.unstableCount + unstable; 7903 if (unstable < 0) { 7904 throw new IllegalStateException("unstableCount < 0: " + unstable); 7905 } 7906 7907 if ((stable+unstable) <= 0) { 7908 throw new IllegalStateException("ref counts can't go to zero here: stable=" 7909 + stable + " unstable=" + unstable); 7910 } 7911 conn.stableCount = stable; 7912 conn.unstableCount = unstable; 7913 return !conn.dead; 7914 } 7915 } 7916 7917 public void unstableProviderDied(IBinder connection) { 7918 ContentProviderConnection conn; 7919 try { 7920 conn = (ContentProviderConnection)connection; 7921 } catch (ClassCastException e) { 7922 String msg ="refContentProvider: " + connection 7923 + " not a ContentProviderConnection"; 7924 Slog.w(TAG, msg); 7925 throw new IllegalArgumentException(msg); 7926 } 7927 if (conn == null) { 7928 throw new NullPointerException("connection is null"); 7929 } 7930 7931 // Safely retrieve the content provider associated with the connection. 7932 IContentProvider provider; 7933 synchronized (this) { 7934 provider = conn.provider.provider; 7935 } 7936 7937 if (provider == null) { 7938 // Um, yeah, we're way ahead of you. 7939 return; 7940 } 7941 7942 // Make sure the caller is being honest with us. 7943 if (provider.asBinder().pingBinder()) { 7944 // Er, no, still looks good to us. 7945 synchronized (this) { 7946 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 7947 + " says " + conn + " died, but we don't agree"); 7948 return; 7949 } 7950 } 7951 7952 // Well look at that! It's dead! 7953 synchronized (this) { 7954 if (conn.provider.provider != provider) { 7955 // But something changed... good enough. 7956 return; 7957 } 7958 7959 ProcessRecord proc = conn.provider.proc; 7960 if (proc == null || proc.thread == null) { 7961 // Seems like the process is already cleaned up. 7962 return; 7963 } 7964 7965 // As far as we're concerned, this is just like receiving a 7966 // death notification... just a bit prematurely. 7967 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 7968 + ") early provider death"); 7969 final long ident = Binder.clearCallingIdentity(); 7970 try { 7971 appDiedLocked(proc, proc.pid, proc.thread); 7972 } finally { 7973 Binder.restoreCallingIdentity(ident); 7974 } 7975 } 7976 } 7977 7978 @Override 7979 public void appNotRespondingViaProvider(IBinder connection) { 7980 enforceCallingPermission( 7981 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 7982 7983 final ContentProviderConnection conn = (ContentProviderConnection) connection; 7984 if (conn == null) { 7985 Slog.w(TAG, "ContentProviderConnection is null"); 7986 return; 7987 } 7988 7989 final ProcessRecord host = conn.provider.proc; 7990 if (host == null) { 7991 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 7992 return; 7993 } 7994 7995 final long token = Binder.clearCallingIdentity(); 7996 try { 7997 appNotResponding(host, null, null, false, "ContentProvider not responding"); 7998 } finally { 7999 Binder.restoreCallingIdentity(token); 8000 } 8001 } 8002 8003 public final void installSystemProviders() { 8004 List<ProviderInfo> providers; 8005 synchronized (this) { 8006 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8007 providers = generateApplicationProvidersLocked(app); 8008 if (providers != null) { 8009 for (int i=providers.size()-1; i>=0; i--) { 8010 ProviderInfo pi = (ProviderInfo)providers.get(i); 8011 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8012 Slog.w(TAG, "Not installing system proc provider " + pi.name 8013 + ": not system .apk"); 8014 providers.remove(i); 8015 } 8016 } 8017 } 8018 } 8019 if (providers != null) { 8020 mSystemThread.installSystemProviders(providers); 8021 } 8022 8023 mCoreSettingsObserver = new CoreSettingsObserver(this); 8024 8025 mUsageStatsService.monitorPackages(); 8026 } 8027 8028 /** 8029 * Allows app to retrieve the MIME type of a URI without having permission 8030 * to access its content provider. 8031 * 8032 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8033 * 8034 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8035 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8036 */ 8037 public String getProviderMimeType(Uri uri, int userId) { 8038 enforceNotIsolatedCaller("getProviderMimeType"); 8039 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8040 userId, false, true, "getProviderMimeType", null); 8041 final String name = uri.getAuthority(); 8042 final long ident = Binder.clearCallingIdentity(); 8043 ContentProviderHolder holder = null; 8044 8045 try { 8046 holder = getContentProviderExternalUnchecked(name, null, userId); 8047 if (holder != null) { 8048 return holder.provider.getType(uri); 8049 } 8050 } catch (RemoteException e) { 8051 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8052 return null; 8053 } finally { 8054 if (holder != null) { 8055 removeContentProviderExternalUnchecked(name, null, userId); 8056 } 8057 Binder.restoreCallingIdentity(ident); 8058 } 8059 8060 return null; 8061 } 8062 8063 // ========================================================= 8064 // GLOBAL MANAGEMENT 8065 // ========================================================= 8066 8067 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8068 boolean isolated) { 8069 String proc = customProcess != null ? customProcess : info.processName; 8070 BatteryStatsImpl.Uid.Proc ps = null; 8071 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8072 int uid = info.uid; 8073 if (isolated) { 8074 int userId = UserHandle.getUserId(uid); 8075 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8076 while (true) { 8077 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8078 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8079 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8080 } 8081 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8082 mNextIsolatedProcessUid++; 8083 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8084 // No process for this uid, use it. 8085 break; 8086 } 8087 stepsLeft--; 8088 if (stepsLeft <= 0) { 8089 return null; 8090 } 8091 } 8092 } 8093 return new ProcessRecord(stats, info, proc, uid); 8094 } 8095 8096 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8097 ProcessRecord app; 8098 if (!isolated) { 8099 app = getProcessRecordLocked(info.processName, info.uid, true); 8100 } else { 8101 app = null; 8102 } 8103 8104 if (app == null) { 8105 app = newProcessRecordLocked(info, null, isolated); 8106 mProcessNames.put(info.processName, app.uid, app); 8107 if (isolated) { 8108 mIsolatedProcesses.put(app.uid, app); 8109 } 8110 updateLruProcessLocked(app, false, null); 8111 updateOomAdjLocked(); 8112 } 8113 8114 // This package really, really can not be stopped. 8115 try { 8116 AppGlobals.getPackageManager().setPackageStoppedState( 8117 info.packageName, false, UserHandle.getUserId(app.uid)); 8118 } catch (RemoteException e) { 8119 } catch (IllegalArgumentException e) { 8120 Slog.w(TAG, "Failed trying to unstop package " 8121 + info.packageName + ": " + e); 8122 } 8123 8124 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8125 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8126 app.persistent = true; 8127 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8128 } 8129 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8130 mPersistentStartingProcesses.add(app); 8131 startProcessLocked(app, "added application", app.processName); 8132 } 8133 8134 return app; 8135 } 8136 8137 public void unhandledBack() { 8138 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8139 "unhandledBack()"); 8140 8141 synchronized(this) { 8142 final long origId = Binder.clearCallingIdentity(); 8143 try { 8144 getFocusedStack().unhandledBackLocked(); 8145 } finally { 8146 Binder.restoreCallingIdentity(origId); 8147 } 8148 } 8149 } 8150 8151 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8152 enforceNotIsolatedCaller("openContentUri"); 8153 final int userId = UserHandle.getCallingUserId(); 8154 String name = uri.getAuthority(); 8155 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8156 ParcelFileDescriptor pfd = null; 8157 if (cph != null) { 8158 // We record the binder invoker's uid in thread-local storage before 8159 // going to the content provider to open the file. Later, in the code 8160 // that handles all permissions checks, we look for this uid and use 8161 // that rather than the Activity Manager's own uid. The effect is that 8162 // we do the check against the caller's permissions even though it looks 8163 // to the content provider like the Activity Manager itself is making 8164 // the request. 8165 sCallerIdentity.set(new Identity( 8166 Binder.getCallingPid(), Binder.getCallingUid())); 8167 try { 8168 pfd = cph.provider.openFile(null, uri, "r", null); 8169 } catch (FileNotFoundException e) { 8170 // do nothing; pfd will be returned null 8171 } finally { 8172 // Ensure that whatever happens, we clean up the identity state 8173 sCallerIdentity.remove(); 8174 } 8175 8176 // We've got the fd now, so we're done with the provider. 8177 removeContentProviderExternalUnchecked(name, null, userId); 8178 } else { 8179 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8180 } 8181 return pfd; 8182 } 8183 8184 // Actually is sleeping or shutting down or whatever else in the future 8185 // is an inactive state. 8186 public boolean isSleepingOrShuttingDown() { 8187 return mSleeping || mShuttingDown; 8188 } 8189 8190 void goingToSleep() { 8191 synchronized(this) { 8192 mWentToSleep = true; 8193 updateEventDispatchingLocked(); 8194 8195 if (!mSleeping) { 8196 mSleeping = true; 8197 mStackSupervisor.goingToSleepLocked(); 8198 8199 // Initialize the wake times of all processes. 8200 checkExcessivePowerUsageLocked(false); 8201 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8202 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8203 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8204 } 8205 } 8206 } 8207 8208 @Override 8209 public boolean shutdown(int timeout) { 8210 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8211 != PackageManager.PERMISSION_GRANTED) { 8212 throw new SecurityException("Requires permission " 8213 + android.Manifest.permission.SHUTDOWN); 8214 } 8215 8216 boolean timedout = false; 8217 8218 synchronized(this) { 8219 mShuttingDown = true; 8220 updateEventDispatchingLocked(); 8221 timedout = mStackSupervisor.shutdownLocked(timeout); 8222 } 8223 8224 mAppOpsService.shutdown(); 8225 mUsageStatsService.shutdown(); 8226 mBatteryStatsService.shutdown(); 8227 synchronized (this) { 8228 mProcessStats.shutdownLocked(); 8229 } 8230 8231 return timedout; 8232 } 8233 8234 public final void activitySlept(IBinder token) { 8235 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8236 8237 final long origId = Binder.clearCallingIdentity(); 8238 8239 synchronized (this) { 8240 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8241 if (r != null) { 8242 mStackSupervisor.activitySleptLocked(r); 8243 } 8244 } 8245 8246 Binder.restoreCallingIdentity(origId); 8247 } 8248 8249 void logLockScreen(String msg) { 8250 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8251 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8252 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8253 mStackSupervisor.mDismissKeyguardOnNextActivity); 8254 } 8255 8256 private void comeOutOfSleepIfNeededLocked() { 8257 if (!mWentToSleep && !mLockScreenShown) { 8258 if (mSleeping) { 8259 mSleeping = false; 8260 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8261 } 8262 } 8263 } 8264 8265 void wakingUp() { 8266 synchronized(this) { 8267 mWentToSleep = false; 8268 updateEventDispatchingLocked(); 8269 comeOutOfSleepIfNeededLocked(); 8270 } 8271 } 8272 8273 private void updateEventDispatchingLocked() { 8274 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8275 } 8276 8277 public void setLockScreenShown(boolean shown) { 8278 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8279 != PackageManager.PERMISSION_GRANTED) { 8280 throw new SecurityException("Requires permission " 8281 + android.Manifest.permission.DEVICE_POWER); 8282 } 8283 8284 synchronized(this) { 8285 long ident = Binder.clearCallingIdentity(); 8286 try { 8287 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8288 mLockScreenShown = shown; 8289 comeOutOfSleepIfNeededLocked(); 8290 } finally { 8291 Binder.restoreCallingIdentity(ident); 8292 } 8293 } 8294 } 8295 8296 public void stopAppSwitches() { 8297 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8298 != PackageManager.PERMISSION_GRANTED) { 8299 throw new SecurityException("Requires permission " 8300 + android.Manifest.permission.STOP_APP_SWITCHES); 8301 } 8302 8303 synchronized(this) { 8304 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8305 + APP_SWITCH_DELAY_TIME; 8306 mDidAppSwitch = false; 8307 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8308 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8309 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8310 } 8311 } 8312 8313 public void resumeAppSwitches() { 8314 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8315 != PackageManager.PERMISSION_GRANTED) { 8316 throw new SecurityException("Requires permission " 8317 + android.Manifest.permission.STOP_APP_SWITCHES); 8318 } 8319 8320 synchronized(this) { 8321 // Note that we don't execute any pending app switches... we will 8322 // let those wait until either the timeout, or the next start 8323 // activity request. 8324 mAppSwitchesAllowedTime = 0; 8325 } 8326 } 8327 8328 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8329 String name) { 8330 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8331 return true; 8332 } 8333 8334 final int perm = checkComponentPermission( 8335 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8336 callingUid, -1, true); 8337 if (perm == PackageManager.PERMISSION_GRANTED) { 8338 return true; 8339 } 8340 8341 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8342 return false; 8343 } 8344 8345 public void setDebugApp(String packageName, boolean waitForDebugger, 8346 boolean persistent) { 8347 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8348 "setDebugApp()"); 8349 8350 long ident = Binder.clearCallingIdentity(); 8351 try { 8352 // Note that this is not really thread safe if there are multiple 8353 // callers into it at the same time, but that's not a situation we 8354 // care about. 8355 if (persistent) { 8356 final ContentResolver resolver = mContext.getContentResolver(); 8357 Settings.Global.putString( 8358 resolver, Settings.Global.DEBUG_APP, 8359 packageName); 8360 Settings.Global.putInt( 8361 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8362 waitForDebugger ? 1 : 0); 8363 } 8364 8365 synchronized (this) { 8366 if (!persistent) { 8367 mOrigDebugApp = mDebugApp; 8368 mOrigWaitForDebugger = mWaitForDebugger; 8369 } 8370 mDebugApp = packageName; 8371 mWaitForDebugger = waitForDebugger; 8372 mDebugTransient = !persistent; 8373 if (packageName != null) { 8374 forceStopPackageLocked(packageName, -1, false, false, true, true, 8375 UserHandle.USER_ALL, "set debug app"); 8376 } 8377 } 8378 } finally { 8379 Binder.restoreCallingIdentity(ident); 8380 } 8381 } 8382 8383 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8384 synchronized (this) { 8385 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8386 if (!isDebuggable) { 8387 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8388 throw new SecurityException("Process not debuggable: " + app.packageName); 8389 } 8390 } 8391 8392 mOpenGlTraceApp = processName; 8393 } 8394 } 8395 8396 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8397 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8398 synchronized (this) { 8399 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8400 if (!isDebuggable) { 8401 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8402 throw new SecurityException("Process not debuggable: " + app.packageName); 8403 } 8404 } 8405 mProfileApp = processName; 8406 mProfileFile = profileFile; 8407 if (mProfileFd != null) { 8408 try { 8409 mProfileFd.close(); 8410 } catch (IOException e) { 8411 } 8412 mProfileFd = null; 8413 } 8414 mProfileFd = profileFd; 8415 mProfileType = 0; 8416 mAutoStopProfiler = autoStopProfiler; 8417 } 8418 } 8419 8420 @Override 8421 public void setAlwaysFinish(boolean enabled) { 8422 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8423 "setAlwaysFinish()"); 8424 8425 Settings.Global.putInt( 8426 mContext.getContentResolver(), 8427 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8428 8429 synchronized (this) { 8430 mAlwaysFinishActivities = enabled; 8431 } 8432 } 8433 8434 @Override 8435 public void setActivityController(IActivityController controller) { 8436 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8437 "setActivityController()"); 8438 synchronized (this) { 8439 mController = controller; 8440 Watchdog.getInstance().setActivityController(controller); 8441 } 8442 } 8443 8444 @Override 8445 public void setUserIsMonkey(boolean userIsMonkey) { 8446 synchronized (this) { 8447 synchronized (mPidsSelfLocked) { 8448 final int callingPid = Binder.getCallingPid(); 8449 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8450 if (precessRecord == null) { 8451 throw new SecurityException("Unknown process: " + callingPid); 8452 } 8453 if (precessRecord.instrumentationUiAutomationConnection == null) { 8454 throw new SecurityException("Only an instrumentation process " 8455 + "with a UiAutomation can call setUserIsMonkey"); 8456 } 8457 } 8458 mUserIsMonkey = userIsMonkey; 8459 } 8460 } 8461 8462 @Override 8463 public boolean isUserAMonkey() { 8464 synchronized (this) { 8465 // If there is a controller also implies the user is a monkey. 8466 return (mUserIsMonkey || mController != null); 8467 } 8468 } 8469 8470 public void requestBugReport() { 8471 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8472 SystemProperties.set("ctl.start", "bugreport"); 8473 } 8474 8475 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8476 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8477 } 8478 8479 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8480 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8481 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8482 } 8483 return KEY_DISPATCHING_TIMEOUT; 8484 } 8485 8486 @Override 8487 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8488 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8489 != PackageManager.PERMISSION_GRANTED) { 8490 throw new SecurityException("Requires permission " 8491 + android.Manifest.permission.FILTER_EVENTS); 8492 } 8493 ProcessRecord proc; 8494 long timeout; 8495 synchronized (this) { 8496 synchronized (mPidsSelfLocked) { 8497 proc = mPidsSelfLocked.get(pid); 8498 } 8499 timeout = getInputDispatchingTimeoutLocked(proc); 8500 } 8501 8502 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8503 return -1; 8504 } 8505 8506 return timeout; 8507 } 8508 8509 /** 8510 * Handle input dispatching timeouts. 8511 * Returns whether input dispatching should be aborted or not. 8512 */ 8513 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8514 final ActivityRecord activity, final ActivityRecord parent, 8515 final boolean aboveSystem, String reason) { 8516 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8517 != PackageManager.PERMISSION_GRANTED) { 8518 throw new SecurityException("Requires permission " 8519 + android.Manifest.permission.FILTER_EVENTS); 8520 } 8521 8522 final String annotation; 8523 if (reason == null) { 8524 annotation = "Input dispatching timed out"; 8525 } else { 8526 annotation = "Input dispatching timed out (" + reason + ")"; 8527 } 8528 8529 if (proc != null) { 8530 synchronized (this) { 8531 if (proc.debugging) { 8532 return false; 8533 } 8534 8535 if (mDidDexOpt) { 8536 // Give more time since we were dexopting. 8537 mDidDexOpt = false; 8538 return false; 8539 } 8540 8541 if (proc.instrumentationClass != null) { 8542 Bundle info = new Bundle(); 8543 info.putString("shortMsg", "keyDispatchingTimedOut"); 8544 info.putString("longMsg", annotation); 8545 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8546 return true; 8547 } 8548 } 8549 mHandler.post(new Runnable() { 8550 @Override 8551 public void run() { 8552 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8553 } 8554 }); 8555 } 8556 8557 return true; 8558 } 8559 8560 public Bundle getAssistContextExtras(int requestType) { 8561 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8562 "getAssistContextExtras()"); 8563 PendingAssistExtras pae; 8564 Bundle extras = new Bundle(); 8565 synchronized (this) { 8566 ActivityRecord activity = getFocusedStack().mResumedActivity; 8567 if (activity == null) { 8568 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8569 return null; 8570 } 8571 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8572 if (activity.app == null || activity.app.thread == null) { 8573 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8574 return extras; 8575 } 8576 if (activity.app.pid == Binder.getCallingPid()) { 8577 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8578 return extras; 8579 } 8580 pae = new PendingAssistExtras(activity); 8581 try { 8582 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8583 requestType); 8584 mPendingAssistExtras.add(pae); 8585 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8586 } catch (RemoteException e) { 8587 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8588 return extras; 8589 } 8590 } 8591 synchronized (pae) { 8592 while (!pae.haveResult) { 8593 try { 8594 pae.wait(); 8595 } catch (InterruptedException e) { 8596 } 8597 } 8598 if (pae.result != null) { 8599 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8600 } 8601 } 8602 synchronized (this) { 8603 mPendingAssistExtras.remove(pae); 8604 mHandler.removeCallbacks(pae); 8605 } 8606 return extras; 8607 } 8608 8609 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8610 PendingAssistExtras pae = (PendingAssistExtras)token; 8611 synchronized (pae) { 8612 pae.result = extras; 8613 pae.haveResult = true; 8614 pae.notifyAll(); 8615 } 8616 } 8617 8618 public void registerProcessObserver(IProcessObserver observer) { 8619 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8620 "registerProcessObserver()"); 8621 synchronized (this) { 8622 mProcessObservers.register(observer); 8623 } 8624 } 8625 8626 @Override 8627 public void unregisterProcessObserver(IProcessObserver observer) { 8628 synchronized (this) { 8629 mProcessObservers.unregister(observer); 8630 } 8631 } 8632 8633 @Override 8634 public boolean convertFromTranslucent(IBinder token) { 8635 final long origId = Binder.clearCallingIdentity(); 8636 try { 8637 synchronized (this) { 8638 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8639 if (r == null) { 8640 return false; 8641 } 8642 if (r.changeWindowTranslucency(true)) { 8643 mWindowManager.setAppFullscreen(token, true); 8644 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8645 return true; 8646 } 8647 return false; 8648 } 8649 } finally { 8650 Binder.restoreCallingIdentity(origId); 8651 } 8652 } 8653 8654 @Override 8655 public boolean convertToTranslucent(IBinder token) { 8656 final long origId = Binder.clearCallingIdentity(); 8657 try { 8658 synchronized (this) { 8659 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8660 if (r == null) { 8661 return false; 8662 } 8663 if (r.changeWindowTranslucency(false)) { 8664 r.task.stack.convertToTranslucent(r); 8665 mWindowManager.setAppFullscreen(token, false); 8666 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8667 return true; 8668 } 8669 return false; 8670 } 8671 } finally { 8672 Binder.restoreCallingIdentity(origId); 8673 } 8674 } 8675 8676 @Override 8677 public void setImmersive(IBinder token, boolean immersive) { 8678 synchronized(this) { 8679 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8680 if (r == null) { 8681 throw new IllegalArgumentException(); 8682 } 8683 r.immersive = immersive; 8684 8685 // update associated state if we're frontmost 8686 if (r == mFocusedActivity) { 8687 if (DEBUG_IMMERSIVE) { 8688 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8689 } 8690 applyUpdateLockStateLocked(r); 8691 } 8692 } 8693 } 8694 8695 @Override 8696 public boolean isImmersive(IBinder token) { 8697 synchronized (this) { 8698 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8699 if (r == null) { 8700 throw new IllegalArgumentException(); 8701 } 8702 return r.immersive; 8703 } 8704 } 8705 8706 public boolean isTopActivityImmersive() { 8707 enforceNotIsolatedCaller("startActivity"); 8708 synchronized (this) { 8709 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8710 return (r != null) ? r.immersive : false; 8711 } 8712 } 8713 8714 public final void enterSafeMode() { 8715 synchronized(this) { 8716 // It only makes sense to do this before the system is ready 8717 // and started launching other packages. 8718 if (!mSystemReady) { 8719 try { 8720 AppGlobals.getPackageManager().enterSafeMode(); 8721 } catch (RemoteException e) { 8722 } 8723 } 8724 8725 mSafeMode = true; 8726 } 8727 } 8728 8729 public final void showSafeModeOverlay() { 8730 View v = LayoutInflater.from(mContext).inflate( 8731 com.android.internal.R.layout.safe_mode, null); 8732 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8733 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8734 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8735 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8736 lp.gravity = Gravity.BOTTOM | Gravity.START; 8737 lp.format = v.getBackground().getOpacity(); 8738 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8739 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8740 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8741 ((WindowManager)mContext.getSystemService( 8742 Context.WINDOW_SERVICE)).addView(v, lp); 8743 } 8744 8745 public void noteWakeupAlarm(IIntentSender sender) { 8746 if (!(sender instanceof PendingIntentRecord)) { 8747 return; 8748 } 8749 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8750 synchronized (stats) { 8751 if (mBatteryStatsService.isOnBattery()) { 8752 mBatteryStatsService.enforceCallingPermission(); 8753 PendingIntentRecord rec = (PendingIntentRecord)sender; 8754 int MY_UID = Binder.getCallingUid(); 8755 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8756 BatteryStatsImpl.Uid.Pkg pkg = 8757 stats.getPackageStatsLocked(uid, rec.key.packageName); 8758 pkg.incWakeupsLocked(); 8759 } 8760 } 8761 } 8762 8763 public boolean killPids(int[] pids, String pReason, boolean secure) { 8764 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8765 throw new SecurityException("killPids only available to the system"); 8766 } 8767 String reason = (pReason == null) ? "Unknown" : pReason; 8768 // XXX Note: don't acquire main activity lock here, because the window 8769 // manager calls in with its locks held. 8770 8771 boolean killed = false; 8772 synchronized (mPidsSelfLocked) { 8773 int[] types = new int[pids.length]; 8774 int worstType = 0; 8775 for (int i=0; i<pids.length; i++) { 8776 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8777 if (proc != null) { 8778 int type = proc.setAdj; 8779 types[i] = type; 8780 if (type > worstType) { 8781 worstType = type; 8782 } 8783 } 8784 } 8785 8786 // If the worst oom_adj is somewhere in the cached proc LRU range, 8787 // then constrain it so we will kill all cached procs. 8788 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8789 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8790 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8791 } 8792 8793 // If this is not a secure call, don't let it kill processes that 8794 // are important. 8795 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8796 worstType = ProcessList.SERVICE_ADJ; 8797 } 8798 8799 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8800 for (int i=0; i<pids.length; i++) { 8801 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8802 if (proc == null) { 8803 continue; 8804 } 8805 int adj = proc.setAdj; 8806 if (adj >= worstType && !proc.killedByAm) { 8807 killUnneededProcessLocked(proc, reason); 8808 killed = true; 8809 } 8810 } 8811 } 8812 return killed; 8813 } 8814 8815 @Override 8816 public void killUid(int uid, String reason) { 8817 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8818 throw new SecurityException("killUid only available to the system"); 8819 } 8820 synchronized (this) { 8821 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 8822 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 8823 reason != null ? reason : "kill uid"); 8824 } 8825 } 8826 8827 @Override 8828 public boolean killProcessesBelowForeground(String reason) { 8829 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8830 throw new SecurityException("killProcessesBelowForeground() only available to system"); 8831 } 8832 8833 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 8834 } 8835 8836 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 8837 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8838 throw new SecurityException("killProcessesBelowAdj() only available to system"); 8839 } 8840 8841 boolean killed = false; 8842 synchronized (mPidsSelfLocked) { 8843 final int size = mPidsSelfLocked.size(); 8844 for (int i = 0; i < size; i++) { 8845 final int pid = mPidsSelfLocked.keyAt(i); 8846 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8847 if (proc == null) continue; 8848 8849 final int adj = proc.setAdj; 8850 if (adj > belowAdj && !proc.killedByAm) { 8851 killUnneededProcessLocked(proc, reason); 8852 killed = true; 8853 } 8854 } 8855 } 8856 return killed; 8857 } 8858 8859 @Override 8860 public void hang(final IBinder who, boolean allowRestart) { 8861 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8862 != PackageManager.PERMISSION_GRANTED) { 8863 throw new SecurityException("Requires permission " 8864 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8865 } 8866 8867 final IBinder.DeathRecipient death = new DeathRecipient() { 8868 @Override 8869 public void binderDied() { 8870 synchronized (this) { 8871 notifyAll(); 8872 } 8873 } 8874 }; 8875 8876 try { 8877 who.linkToDeath(death, 0); 8878 } catch (RemoteException e) { 8879 Slog.w(TAG, "hang: given caller IBinder is already dead."); 8880 return; 8881 } 8882 8883 synchronized (this) { 8884 Watchdog.getInstance().setAllowRestart(allowRestart); 8885 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 8886 synchronized (death) { 8887 while (who.isBinderAlive()) { 8888 try { 8889 death.wait(); 8890 } catch (InterruptedException e) { 8891 } 8892 } 8893 } 8894 Watchdog.getInstance().setAllowRestart(true); 8895 } 8896 } 8897 8898 @Override 8899 public void restart() { 8900 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8901 != PackageManager.PERMISSION_GRANTED) { 8902 throw new SecurityException("Requires permission " 8903 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8904 } 8905 8906 Log.i(TAG, "Sending shutdown broadcast..."); 8907 8908 BroadcastReceiver br = new BroadcastReceiver() { 8909 @Override public void onReceive(Context context, Intent intent) { 8910 // Now the broadcast is done, finish up the low-level shutdown. 8911 Log.i(TAG, "Shutting down activity manager..."); 8912 shutdown(10000); 8913 Log.i(TAG, "Shutdown complete, restarting!"); 8914 Process.killProcess(Process.myPid()); 8915 System.exit(10); 8916 } 8917 }; 8918 8919 // First send the high-level shut down broadcast. 8920 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 8921 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 8922 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 8923 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 8924 mContext.sendOrderedBroadcastAsUser(intent, 8925 UserHandle.ALL, null, br, mHandler, 0, null, null); 8926 */ 8927 br.onReceive(mContext, intent); 8928 } 8929 8930 private long getLowRamTimeSinceIdle(long now) { 8931 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 8932 } 8933 8934 @Override 8935 public void performIdleMaintenance() { 8936 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8937 != PackageManager.PERMISSION_GRANTED) { 8938 throw new SecurityException("Requires permission " 8939 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8940 } 8941 8942 synchronized (this) { 8943 final long now = SystemClock.uptimeMillis(); 8944 final long timeSinceLastIdle = now - mLastIdleTime; 8945 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 8946 mLastIdleTime = now; 8947 mLowRamTimeSinceLastIdle = 0; 8948 if (mLowRamStartTime != 0) { 8949 mLowRamStartTime = now; 8950 } 8951 8952 StringBuilder sb = new StringBuilder(128); 8953 sb.append("Idle maintenance over "); 8954 TimeUtils.formatDuration(timeSinceLastIdle, sb); 8955 sb.append(" low RAM for "); 8956 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 8957 Slog.i(TAG, sb.toString()); 8958 8959 // If at least 1/3 of our time since the last idle period has been spent 8960 // with RAM low, then we want to kill processes. 8961 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 8962 8963 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 8964 ProcessRecord proc = mLruProcesses.get(i); 8965 if (proc.notCachedSinceIdle) { 8966 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 8967 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 8968 if (doKilling && proc.initialIdlePss != 0 8969 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 8970 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 8971 + " from " + proc.initialIdlePss + ")"); 8972 } 8973 } 8974 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 8975 proc.notCachedSinceIdle = true; 8976 proc.initialIdlePss = 0; 8977 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 8978 mSleeping, now); 8979 } 8980 } 8981 8982 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 8983 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 8984 } 8985 } 8986 8987 private void retrieveSettings() { 8988 final ContentResolver resolver = mContext.getContentResolver(); 8989 String debugApp = Settings.Global.getString( 8990 resolver, Settings.Global.DEBUG_APP); 8991 boolean waitForDebugger = Settings.Global.getInt( 8992 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 8993 boolean alwaysFinishActivities = Settings.Global.getInt( 8994 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 8995 boolean forceRtl = Settings.Global.getInt( 8996 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 8997 // Transfer any global setting for forcing RTL layout, into a System Property 8998 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 8999 9000 Configuration configuration = new Configuration(); 9001 Settings.System.getConfiguration(resolver, configuration); 9002 if (forceRtl) { 9003 // This will take care of setting the correct layout direction flags 9004 configuration.setLayoutDirection(configuration.locale); 9005 } 9006 9007 synchronized (this) { 9008 mDebugApp = mOrigDebugApp = debugApp; 9009 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9010 mAlwaysFinishActivities = alwaysFinishActivities; 9011 // This happens before any activities are started, so we can 9012 // change mConfiguration in-place. 9013 updateConfigurationLocked(configuration, null, false, true); 9014 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9015 } 9016 } 9017 9018 public boolean testIsSystemReady() { 9019 // no need to synchronize(this) just to read & return the value 9020 return mSystemReady; 9021 } 9022 9023 private static File getCalledPreBootReceiversFile() { 9024 File dataDir = Environment.getDataDirectory(); 9025 File systemDir = new File(dataDir, "system"); 9026 File fname = new File(systemDir, "called_pre_boots.dat"); 9027 return fname; 9028 } 9029 9030 static final int LAST_DONE_VERSION = 10000; 9031 9032 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9033 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9034 File file = getCalledPreBootReceiversFile(); 9035 FileInputStream fis = null; 9036 try { 9037 fis = new FileInputStream(file); 9038 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9039 int fvers = dis.readInt(); 9040 if (fvers == LAST_DONE_VERSION) { 9041 String vers = dis.readUTF(); 9042 String codename = dis.readUTF(); 9043 String build = dis.readUTF(); 9044 if (android.os.Build.VERSION.RELEASE.equals(vers) 9045 && android.os.Build.VERSION.CODENAME.equals(codename) 9046 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9047 int num = dis.readInt(); 9048 while (num > 0) { 9049 num--; 9050 String pkg = dis.readUTF(); 9051 String cls = dis.readUTF(); 9052 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9053 } 9054 } 9055 } 9056 } catch (FileNotFoundException e) { 9057 } catch (IOException e) { 9058 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9059 } finally { 9060 if (fis != null) { 9061 try { 9062 fis.close(); 9063 } catch (IOException e) { 9064 } 9065 } 9066 } 9067 return lastDoneReceivers; 9068 } 9069 9070 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9071 File file = getCalledPreBootReceiversFile(); 9072 FileOutputStream fos = null; 9073 DataOutputStream dos = null; 9074 try { 9075 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9076 fos = new FileOutputStream(file); 9077 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9078 dos.writeInt(LAST_DONE_VERSION); 9079 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9080 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9081 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9082 dos.writeInt(list.size()); 9083 for (int i=0; i<list.size(); i++) { 9084 dos.writeUTF(list.get(i).getPackageName()); 9085 dos.writeUTF(list.get(i).getClassName()); 9086 } 9087 } catch (IOException e) { 9088 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9089 file.delete(); 9090 } finally { 9091 FileUtils.sync(fos); 9092 if (dos != null) { 9093 try { 9094 dos.close(); 9095 } catch (IOException e) { 9096 // TODO Auto-generated catch block 9097 e.printStackTrace(); 9098 } 9099 } 9100 } 9101 } 9102 9103 public void systemReady(final Runnable goingCallback) { 9104 synchronized(this) { 9105 if (mSystemReady) { 9106 if (goingCallback != null) goingCallback.run(); 9107 return; 9108 } 9109 9110 // Check to see if there are any update receivers to run. 9111 if (!mDidUpdate) { 9112 if (mWaitingUpdate) { 9113 return; 9114 } 9115 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9116 List<ResolveInfo> ris = null; 9117 try { 9118 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9119 intent, null, 0, 0); 9120 } catch (RemoteException e) { 9121 } 9122 if (ris != null) { 9123 for (int i=ris.size()-1; i>=0; i--) { 9124 if ((ris.get(i).activityInfo.applicationInfo.flags 9125 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9126 ris.remove(i); 9127 } 9128 } 9129 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9130 9131 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9132 9133 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9134 for (int i=0; i<ris.size(); i++) { 9135 ActivityInfo ai = ris.get(i).activityInfo; 9136 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9137 if (lastDoneReceivers.contains(comp)) { 9138 // We already did the pre boot receiver for this app with the current 9139 // platform version, so don't do it again... 9140 ris.remove(i); 9141 i--; 9142 // ...however, do keep it as one that has been done, so we don't 9143 // forget about it when rewriting the file of last done receivers. 9144 doneReceivers.add(comp); 9145 } 9146 } 9147 9148 final int[] users = getUsersLocked(); 9149 for (int i=0; i<ris.size(); i++) { 9150 ActivityInfo ai = ris.get(i).activityInfo; 9151 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9152 doneReceivers.add(comp); 9153 intent.setComponent(comp); 9154 for (int j=0; j<users.length; j++) { 9155 IIntentReceiver finisher = null; 9156 if (i == ris.size()-1 && j == users.length-1) { 9157 finisher = new IIntentReceiver.Stub() { 9158 public void performReceive(Intent intent, int resultCode, 9159 String data, Bundle extras, boolean ordered, 9160 boolean sticky, int sendingUser) { 9161 // The raw IIntentReceiver interface is called 9162 // with the AM lock held, so redispatch to 9163 // execute our code without the lock. 9164 mHandler.post(new Runnable() { 9165 public void run() { 9166 synchronized (ActivityManagerService.this) { 9167 mDidUpdate = true; 9168 } 9169 writeLastDonePreBootReceivers(doneReceivers); 9170 showBootMessage(mContext.getText( 9171 R.string.android_upgrading_complete), 9172 false); 9173 systemReady(goingCallback); 9174 } 9175 }); 9176 } 9177 }; 9178 } 9179 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9180 + " for user " + users[j]); 9181 broadcastIntentLocked(null, null, intent, null, finisher, 9182 0, null, null, null, AppOpsManager.OP_NONE, 9183 true, false, MY_PID, Process.SYSTEM_UID, 9184 users[j]); 9185 if (finisher != null) { 9186 mWaitingUpdate = true; 9187 } 9188 } 9189 } 9190 } 9191 if (mWaitingUpdate) { 9192 return; 9193 } 9194 mDidUpdate = true; 9195 } 9196 9197 mAppOpsService.systemReady(); 9198 mSystemReady = true; 9199 } 9200 9201 ArrayList<ProcessRecord> procsToKill = null; 9202 synchronized(mPidsSelfLocked) { 9203 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9204 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9205 if (!isAllowedWhileBooting(proc.info)){ 9206 if (procsToKill == null) { 9207 procsToKill = new ArrayList<ProcessRecord>(); 9208 } 9209 procsToKill.add(proc); 9210 } 9211 } 9212 } 9213 9214 synchronized(this) { 9215 if (procsToKill != null) { 9216 for (int i=procsToKill.size()-1; i>=0; i--) { 9217 ProcessRecord proc = procsToKill.get(i); 9218 Slog.i(TAG, "Removing system update proc: " + proc); 9219 removeProcessLocked(proc, true, false, "system update done"); 9220 } 9221 } 9222 9223 // Now that we have cleaned up any update processes, we 9224 // are ready to start launching real processes and know that 9225 // we won't trample on them any more. 9226 mProcessesReady = true; 9227 } 9228 9229 Slog.i(TAG, "System now ready"); 9230 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9231 SystemClock.uptimeMillis()); 9232 9233 synchronized(this) { 9234 // Make sure we have no pre-ready processes sitting around. 9235 9236 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9237 ResolveInfo ri = mContext.getPackageManager() 9238 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9239 STOCK_PM_FLAGS); 9240 CharSequence errorMsg = null; 9241 if (ri != null) { 9242 ActivityInfo ai = ri.activityInfo; 9243 ApplicationInfo app = ai.applicationInfo; 9244 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9245 mTopAction = Intent.ACTION_FACTORY_TEST; 9246 mTopData = null; 9247 mTopComponent = new ComponentName(app.packageName, 9248 ai.name); 9249 } else { 9250 errorMsg = mContext.getResources().getText( 9251 com.android.internal.R.string.factorytest_not_system); 9252 } 9253 } else { 9254 errorMsg = mContext.getResources().getText( 9255 com.android.internal.R.string.factorytest_no_action); 9256 } 9257 if (errorMsg != null) { 9258 mTopAction = null; 9259 mTopData = null; 9260 mTopComponent = null; 9261 Message msg = Message.obtain(); 9262 msg.what = SHOW_FACTORY_ERROR_MSG; 9263 msg.getData().putCharSequence("msg", errorMsg); 9264 mHandler.sendMessage(msg); 9265 } 9266 } 9267 } 9268 9269 retrieveSettings(); 9270 9271 synchronized (this) { 9272 readGrantedUriPermissionsLocked(); 9273 } 9274 9275 if (goingCallback != null) goingCallback.run(); 9276 9277 synchronized (this) { 9278 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9279 try { 9280 List apps = AppGlobals.getPackageManager(). 9281 getPersistentApplications(STOCK_PM_FLAGS); 9282 if (apps != null) { 9283 int N = apps.size(); 9284 int i; 9285 for (i=0; i<N; i++) { 9286 ApplicationInfo info 9287 = (ApplicationInfo)apps.get(i); 9288 if (info != null && 9289 !info.packageName.equals("android")) { 9290 addAppLocked(info, false); 9291 } 9292 } 9293 } 9294 } catch (RemoteException ex) { 9295 // pm is in same process, this will never happen. 9296 } 9297 } 9298 9299 // Start up initial activity. 9300 mBooting = true; 9301 9302 try { 9303 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9304 Message msg = Message.obtain(); 9305 msg.what = SHOW_UID_ERROR_MSG; 9306 mHandler.sendMessage(msg); 9307 } 9308 } catch (RemoteException e) { 9309 } 9310 9311 long ident = Binder.clearCallingIdentity(); 9312 try { 9313 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9314 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9315 | Intent.FLAG_RECEIVER_FOREGROUND); 9316 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9317 broadcastIntentLocked(null, null, intent, 9318 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9319 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9320 intent = new Intent(Intent.ACTION_USER_STARTING); 9321 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9322 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9323 broadcastIntentLocked(null, null, intent, 9324 null, new IIntentReceiver.Stub() { 9325 @Override 9326 public void performReceive(Intent intent, int resultCode, String data, 9327 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9328 throws RemoteException { 9329 } 9330 }, 0, null, null, 9331 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9332 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9333 } finally { 9334 Binder.restoreCallingIdentity(ident); 9335 } 9336 mStackSupervisor.resumeTopActivitiesLocked(); 9337 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9338 } 9339 } 9340 9341 private boolean makeAppCrashingLocked(ProcessRecord app, 9342 String shortMsg, String longMsg, String stackTrace) { 9343 app.crashing = true; 9344 app.crashingReport = generateProcessError(app, 9345 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9346 startAppProblemLocked(app); 9347 app.stopFreezingAllLocked(); 9348 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9349 } 9350 9351 private void makeAppNotRespondingLocked(ProcessRecord app, 9352 String activity, String shortMsg, String longMsg) { 9353 app.notResponding = true; 9354 app.notRespondingReport = generateProcessError(app, 9355 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9356 activity, shortMsg, longMsg, null); 9357 startAppProblemLocked(app); 9358 app.stopFreezingAllLocked(); 9359 } 9360 9361 /** 9362 * Generate a process error record, suitable for attachment to a ProcessRecord. 9363 * 9364 * @param app The ProcessRecord in which the error occurred. 9365 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9366 * ActivityManager.AppErrorStateInfo 9367 * @param activity The activity associated with the crash, if known. 9368 * @param shortMsg Short message describing the crash. 9369 * @param longMsg Long message describing the crash. 9370 * @param stackTrace Full crash stack trace, may be null. 9371 * 9372 * @return Returns a fully-formed AppErrorStateInfo record. 9373 */ 9374 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9375 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9376 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9377 9378 report.condition = condition; 9379 report.processName = app.processName; 9380 report.pid = app.pid; 9381 report.uid = app.info.uid; 9382 report.tag = activity; 9383 report.shortMsg = shortMsg; 9384 report.longMsg = longMsg; 9385 report.stackTrace = stackTrace; 9386 9387 return report; 9388 } 9389 9390 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9391 synchronized (this) { 9392 app.crashing = false; 9393 app.crashingReport = null; 9394 app.notResponding = false; 9395 app.notRespondingReport = null; 9396 if (app.anrDialog == fromDialog) { 9397 app.anrDialog = null; 9398 } 9399 if (app.waitDialog == fromDialog) { 9400 app.waitDialog = null; 9401 } 9402 if (app.pid > 0 && app.pid != MY_PID) { 9403 handleAppCrashLocked(app, null, null, null); 9404 killUnneededProcessLocked(app, "user request after error"); 9405 } 9406 } 9407 } 9408 9409 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9410 String stackTrace) { 9411 long now = SystemClock.uptimeMillis(); 9412 9413 Long crashTime; 9414 if (!app.isolated) { 9415 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9416 } else { 9417 crashTime = null; 9418 } 9419 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9420 // This process loses! 9421 Slog.w(TAG, "Process " + app.info.processName 9422 + " has crashed too many times: killing!"); 9423 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9424 app.userId, app.info.processName, app.uid); 9425 mStackSupervisor.handleAppCrashLocked(app); 9426 if (!app.persistent) { 9427 // We don't want to start this process again until the user 9428 // explicitly does so... but for persistent process, we really 9429 // need to keep it running. If a persistent process is actually 9430 // repeatedly crashing, then badness for everyone. 9431 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9432 app.info.processName); 9433 if (!app.isolated) { 9434 // XXX We don't have a way to mark isolated processes 9435 // as bad, since they don't have a peristent identity. 9436 mBadProcesses.put(app.info.processName, app.uid, 9437 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9438 mProcessCrashTimes.remove(app.info.processName, app.uid); 9439 } 9440 app.bad = true; 9441 app.removed = true; 9442 // Don't let services in this process be restarted and potentially 9443 // annoy the user repeatedly. Unless it is persistent, since those 9444 // processes run critical code. 9445 removeProcessLocked(app, false, false, "crash"); 9446 mStackSupervisor.resumeTopActivitiesLocked(); 9447 return false; 9448 } 9449 mStackSupervisor.resumeTopActivitiesLocked(); 9450 } else { 9451 mStackSupervisor.finishTopRunningActivityLocked(app); 9452 } 9453 9454 // Bump up the crash count of any services currently running in the proc. 9455 for (int i=app.services.size()-1; i>=0; i--) { 9456 // Any services running in the application need to be placed 9457 // back in the pending list. 9458 ServiceRecord sr = app.services.valueAt(i); 9459 sr.crashCount++; 9460 } 9461 9462 // If the crashing process is what we consider to be the "home process" and it has been 9463 // replaced by a third-party app, clear the package preferred activities from packages 9464 // with a home activity running in the process to prevent a repeatedly crashing app 9465 // from blocking the user to manually clear the list. 9466 final ArrayList<ActivityRecord> activities = app.activities; 9467 if (app == mHomeProcess && activities.size() > 0 9468 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9469 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9470 final ActivityRecord r = activities.get(activityNdx); 9471 if (r.isHomeActivity()) { 9472 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9473 try { 9474 ActivityThread.getPackageManager() 9475 .clearPackagePreferredActivities(r.packageName); 9476 } catch (RemoteException c) { 9477 // pm is in same process, this will never happen. 9478 } 9479 } 9480 } 9481 } 9482 9483 if (!app.isolated) { 9484 // XXX Can't keep track of crash times for isolated processes, 9485 // because they don't have a perisistent identity. 9486 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9487 } 9488 9489 return true; 9490 } 9491 9492 void startAppProblemLocked(ProcessRecord app) { 9493 if (app.userId == mCurrentUserId) { 9494 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9495 mContext, app.info.packageName, app.info.flags); 9496 } else { 9497 // If this app is not running under the current user, then we 9498 // can't give it a report button because that would require 9499 // launching the report UI under a different user. 9500 app.errorReportReceiver = null; 9501 } 9502 skipCurrentReceiverLocked(app); 9503 } 9504 9505 void skipCurrentReceiverLocked(ProcessRecord app) { 9506 for (BroadcastQueue queue : mBroadcastQueues) { 9507 queue.skipCurrentReceiverLocked(app); 9508 } 9509 } 9510 9511 /** 9512 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9513 * The application process will exit immediately after this call returns. 9514 * @param app object of the crashing app, null for the system server 9515 * @param crashInfo describing the exception 9516 */ 9517 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9518 ProcessRecord r = findAppProcess(app, "Crash"); 9519 final String processName = app == null ? "system_server" 9520 : (r == null ? "unknown" : r.processName); 9521 9522 handleApplicationCrashInner("crash", r, processName, crashInfo); 9523 } 9524 9525 /* Native crash reporting uses this inner version because it needs to be somewhat 9526 * decoupled from the AM-managed cleanup lifecycle 9527 */ 9528 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9529 ApplicationErrorReport.CrashInfo crashInfo) { 9530 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9531 UserHandle.getUserId(Binder.getCallingUid()), processName, 9532 r == null ? -1 : r.info.flags, 9533 crashInfo.exceptionClassName, 9534 crashInfo.exceptionMessage, 9535 crashInfo.throwFileName, 9536 crashInfo.throwLineNumber); 9537 9538 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9539 9540 crashApplication(r, crashInfo); 9541 } 9542 9543 public void handleApplicationStrictModeViolation( 9544 IBinder app, 9545 int violationMask, 9546 StrictMode.ViolationInfo info) { 9547 ProcessRecord r = findAppProcess(app, "StrictMode"); 9548 if (r == null) { 9549 return; 9550 } 9551 9552 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9553 Integer stackFingerprint = info.hashCode(); 9554 boolean logIt = true; 9555 synchronized (mAlreadyLoggedViolatedStacks) { 9556 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9557 logIt = false; 9558 // TODO: sub-sample into EventLog for these, with 9559 // the info.durationMillis? Then we'd get 9560 // the relative pain numbers, without logging all 9561 // the stack traces repeatedly. We'd want to do 9562 // likewise in the client code, which also does 9563 // dup suppression, before the Binder call. 9564 } else { 9565 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9566 mAlreadyLoggedViolatedStacks.clear(); 9567 } 9568 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9569 } 9570 } 9571 if (logIt) { 9572 logStrictModeViolationToDropBox(r, info); 9573 } 9574 } 9575 9576 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9577 AppErrorResult result = new AppErrorResult(); 9578 synchronized (this) { 9579 final long origId = Binder.clearCallingIdentity(); 9580 9581 Message msg = Message.obtain(); 9582 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9583 HashMap<String, Object> data = new HashMap<String, Object>(); 9584 data.put("result", result); 9585 data.put("app", r); 9586 data.put("violationMask", violationMask); 9587 data.put("info", info); 9588 msg.obj = data; 9589 mHandler.sendMessage(msg); 9590 9591 Binder.restoreCallingIdentity(origId); 9592 } 9593 int res = result.get(); 9594 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9595 } 9596 } 9597 9598 // Depending on the policy in effect, there could be a bunch of 9599 // these in quick succession so we try to batch these together to 9600 // minimize disk writes, number of dropbox entries, and maximize 9601 // compression, by having more fewer, larger records. 9602 private void logStrictModeViolationToDropBox( 9603 ProcessRecord process, 9604 StrictMode.ViolationInfo info) { 9605 if (info == null) { 9606 return; 9607 } 9608 final boolean isSystemApp = process == null || 9609 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9610 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9611 final String processName = process == null ? "unknown" : process.processName; 9612 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9613 final DropBoxManager dbox = (DropBoxManager) 9614 mContext.getSystemService(Context.DROPBOX_SERVICE); 9615 9616 // Exit early if the dropbox isn't configured to accept this report type. 9617 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9618 9619 boolean bufferWasEmpty; 9620 boolean needsFlush; 9621 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9622 synchronized (sb) { 9623 bufferWasEmpty = sb.length() == 0; 9624 appendDropBoxProcessHeaders(process, processName, sb); 9625 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9626 sb.append("System-App: ").append(isSystemApp).append("\n"); 9627 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9628 if (info.violationNumThisLoop != 0) { 9629 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9630 } 9631 if (info.numAnimationsRunning != 0) { 9632 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9633 } 9634 if (info.broadcastIntentAction != null) { 9635 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9636 } 9637 if (info.durationMillis != -1) { 9638 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9639 } 9640 if (info.numInstances != -1) { 9641 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9642 } 9643 if (info.tags != null) { 9644 for (String tag : info.tags) { 9645 sb.append("Span-Tag: ").append(tag).append("\n"); 9646 } 9647 } 9648 sb.append("\n"); 9649 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9650 sb.append(info.crashInfo.stackTrace); 9651 } 9652 sb.append("\n"); 9653 9654 // Only buffer up to ~64k. Various logging bits truncate 9655 // things at 128k. 9656 needsFlush = (sb.length() > 64 * 1024); 9657 } 9658 9659 // Flush immediately if the buffer's grown too large, or this 9660 // is a non-system app. Non-system apps are isolated with a 9661 // different tag & policy and not batched. 9662 // 9663 // Batching is useful during internal testing with 9664 // StrictMode settings turned up high. Without batching, 9665 // thousands of separate files could be created on boot. 9666 if (!isSystemApp || needsFlush) { 9667 new Thread("Error dump: " + dropboxTag) { 9668 @Override 9669 public void run() { 9670 String report; 9671 synchronized (sb) { 9672 report = sb.toString(); 9673 sb.delete(0, sb.length()); 9674 sb.trimToSize(); 9675 } 9676 if (report.length() != 0) { 9677 dbox.addText(dropboxTag, report); 9678 } 9679 } 9680 }.start(); 9681 return; 9682 } 9683 9684 // System app batching: 9685 if (!bufferWasEmpty) { 9686 // An existing dropbox-writing thread is outstanding, so 9687 // we don't need to start it up. The existing thread will 9688 // catch the buffer appends we just did. 9689 return; 9690 } 9691 9692 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9693 // (After this point, we shouldn't access AMS internal data structures.) 9694 new Thread("Error dump: " + dropboxTag) { 9695 @Override 9696 public void run() { 9697 // 5 second sleep to let stacks arrive and be batched together 9698 try { 9699 Thread.sleep(5000); // 5 seconds 9700 } catch (InterruptedException e) {} 9701 9702 String errorReport; 9703 synchronized (mStrictModeBuffer) { 9704 errorReport = mStrictModeBuffer.toString(); 9705 if (errorReport.length() == 0) { 9706 return; 9707 } 9708 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9709 mStrictModeBuffer.trimToSize(); 9710 } 9711 dbox.addText(dropboxTag, errorReport); 9712 } 9713 }.start(); 9714 } 9715 9716 /** 9717 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9718 * @param app object of the crashing app, null for the system server 9719 * @param tag reported by the caller 9720 * @param crashInfo describing the context of the error 9721 * @return true if the process should exit immediately (WTF is fatal) 9722 */ 9723 public boolean handleApplicationWtf(IBinder app, String tag, 9724 ApplicationErrorReport.CrashInfo crashInfo) { 9725 ProcessRecord r = findAppProcess(app, "WTF"); 9726 final String processName = app == null ? "system_server" 9727 : (r == null ? "unknown" : r.processName); 9728 9729 EventLog.writeEvent(EventLogTags.AM_WTF, 9730 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9731 processName, 9732 r == null ? -1 : r.info.flags, 9733 tag, crashInfo.exceptionMessage); 9734 9735 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9736 9737 if (r != null && r.pid != Process.myPid() && 9738 Settings.Global.getInt(mContext.getContentResolver(), 9739 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9740 crashApplication(r, crashInfo); 9741 return true; 9742 } else { 9743 return false; 9744 } 9745 } 9746 9747 /** 9748 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9749 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9750 */ 9751 private ProcessRecord findAppProcess(IBinder app, String reason) { 9752 if (app == null) { 9753 return null; 9754 } 9755 9756 synchronized (this) { 9757 final int NP = mProcessNames.getMap().size(); 9758 for (int ip=0; ip<NP; ip++) { 9759 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9760 final int NA = apps.size(); 9761 for (int ia=0; ia<NA; ia++) { 9762 ProcessRecord p = apps.valueAt(ia); 9763 if (p.thread != null && p.thread.asBinder() == app) { 9764 return p; 9765 } 9766 } 9767 } 9768 9769 Slog.w(TAG, "Can't find mystery application for " + reason 9770 + " from pid=" + Binder.getCallingPid() 9771 + " uid=" + Binder.getCallingUid() + ": " + app); 9772 return null; 9773 } 9774 } 9775 9776 /** 9777 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9778 * to append various headers to the dropbox log text. 9779 */ 9780 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9781 StringBuilder sb) { 9782 // Watchdog thread ends up invoking this function (with 9783 // a null ProcessRecord) to add the stack file to dropbox. 9784 // Do not acquire a lock on this (am) in such cases, as it 9785 // could cause a potential deadlock, if and when watchdog 9786 // is invoked due to unavailability of lock on am and it 9787 // would prevent watchdog from killing system_server. 9788 if (process == null) { 9789 sb.append("Process: ").append(processName).append("\n"); 9790 return; 9791 } 9792 // Note: ProcessRecord 'process' is guarded by the service 9793 // instance. (notably process.pkgList, which could otherwise change 9794 // concurrently during execution of this method) 9795 synchronized (this) { 9796 sb.append("Process: ").append(processName).append("\n"); 9797 int flags = process.info.flags; 9798 IPackageManager pm = AppGlobals.getPackageManager(); 9799 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 9800 for (int ip=0; ip<process.pkgList.size(); ip++) { 9801 String pkg = process.pkgList.keyAt(ip); 9802 sb.append("Package: ").append(pkg); 9803 try { 9804 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 9805 if (pi != null) { 9806 sb.append(" v").append(pi.versionCode); 9807 if (pi.versionName != null) { 9808 sb.append(" (").append(pi.versionName).append(")"); 9809 } 9810 } 9811 } catch (RemoteException e) { 9812 Slog.e(TAG, "Error getting package info: " + pkg, e); 9813 } 9814 sb.append("\n"); 9815 } 9816 } 9817 } 9818 9819 private static String processClass(ProcessRecord process) { 9820 if (process == null || process.pid == MY_PID) { 9821 return "system_server"; 9822 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9823 return "system_app"; 9824 } else { 9825 return "data_app"; 9826 } 9827 } 9828 9829 /** 9830 * Write a description of an error (crash, WTF, ANR) to the drop box. 9831 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 9832 * @param process which caused the error, null means the system server 9833 * @param activity which triggered the error, null if unknown 9834 * @param parent activity related to the error, null if unknown 9835 * @param subject line related to the error, null if absent 9836 * @param report in long form describing the error, null if absent 9837 * @param logFile to include in the report, null if none 9838 * @param crashInfo giving an application stack trace, null if absent 9839 */ 9840 public void addErrorToDropBox(String eventType, 9841 ProcessRecord process, String processName, ActivityRecord activity, 9842 ActivityRecord parent, String subject, 9843 final String report, final File logFile, 9844 final ApplicationErrorReport.CrashInfo crashInfo) { 9845 // NOTE -- this must never acquire the ActivityManagerService lock, 9846 // otherwise the watchdog may be prevented from resetting the system. 9847 9848 final String dropboxTag = processClass(process) + "_" + eventType; 9849 final DropBoxManager dbox = (DropBoxManager) 9850 mContext.getSystemService(Context.DROPBOX_SERVICE); 9851 9852 // Exit early if the dropbox isn't configured to accept this report type. 9853 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9854 9855 final StringBuilder sb = new StringBuilder(1024); 9856 appendDropBoxProcessHeaders(process, processName, sb); 9857 if (activity != null) { 9858 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 9859 } 9860 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 9861 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 9862 } 9863 if (parent != null && parent != activity) { 9864 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 9865 } 9866 if (subject != null) { 9867 sb.append("Subject: ").append(subject).append("\n"); 9868 } 9869 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9870 if (Debug.isDebuggerConnected()) { 9871 sb.append("Debugger: Connected\n"); 9872 } 9873 sb.append("\n"); 9874 9875 // Do the rest in a worker thread to avoid blocking the caller on I/O 9876 // (After this point, we shouldn't access AMS internal data structures.) 9877 Thread worker = new Thread("Error dump: " + dropboxTag) { 9878 @Override 9879 public void run() { 9880 if (report != null) { 9881 sb.append(report); 9882 } 9883 if (logFile != null) { 9884 try { 9885 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 9886 "\n\n[[TRUNCATED]]")); 9887 } catch (IOException e) { 9888 Slog.e(TAG, "Error reading " + logFile, e); 9889 } 9890 } 9891 if (crashInfo != null && crashInfo.stackTrace != null) { 9892 sb.append(crashInfo.stackTrace); 9893 } 9894 9895 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 9896 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 9897 if (lines > 0) { 9898 sb.append("\n"); 9899 9900 // Merge several logcat streams, and take the last N lines 9901 InputStreamReader input = null; 9902 try { 9903 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 9904 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 9905 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 9906 9907 try { logcat.getOutputStream().close(); } catch (IOException e) {} 9908 try { logcat.getErrorStream().close(); } catch (IOException e) {} 9909 input = new InputStreamReader(logcat.getInputStream()); 9910 9911 int num; 9912 char[] buf = new char[8192]; 9913 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 9914 } catch (IOException e) { 9915 Slog.e(TAG, "Error running logcat", e); 9916 } finally { 9917 if (input != null) try { input.close(); } catch (IOException e) {} 9918 } 9919 } 9920 9921 dbox.addText(dropboxTag, sb.toString()); 9922 } 9923 }; 9924 9925 if (process == null) { 9926 // If process is null, we are being called from some internal code 9927 // and may be about to die -- run this synchronously. 9928 worker.run(); 9929 } else { 9930 worker.start(); 9931 } 9932 } 9933 9934 /** 9935 * Bring up the "unexpected error" dialog box for a crashing app. 9936 * Deal with edge cases (intercepts from instrumented applications, 9937 * ActivityController, error intent receivers, that sort of thing). 9938 * @param r the application crashing 9939 * @param crashInfo describing the failure 9940 */ 9941 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 9942 long timeMillis = System.currentTimeMillis(); 9943 String shortMsg = crashInfo.exceptionClassName; 9944 String longMsg = crashInfo.exceptionMessage; 9945 String stackTrace = crashInfo.stackTrace; 9946 if (shortMsg != null && longMsg != null) { 9947 longMsg = shortMsg + ": " + longMsg; 9948 } else if (shortMsg != null) { 9949 longMsg = shortMsg; 9950 } 9951 9952 AppErrorResult result = new AppErrorResult(); 9953 synchronized (this) { 9954 if (mController != null) { 9955 try { 9956 String name = r != null ? r.processName : null; 9957 int pid = r != null ? r.pid : Binder.getCallingPid(); 9958 if (!mController.appCrashed(name, pid, 9959 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 9960 Slog.w(TAG, "Force-killing crashed app " + name 9961 + " at watcher's request"); 9962 Process.killProcess(pid); 9963 return; 9964 } 9965 } catch (RemoteException e) { 9966 mController = null; 9967 Watchdog.getInstance().setActivityController(null); 9968 } 9969 } 9970 9971 final long origId = Binder.clearCallingIdentity(); 9972 9973 // If this process is running instrumentation, finish it. 9974 if (r != null && r.instrumentationClass != null) { 9975 Slog.w(TAG, "Error in app " + r.processName 9976 + " running instrumentation " + r.instrumentationClass + ":"); 9977 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 9978 if (longMsg != null) Slog.w(TAG, " " + longMsg); 9979 Bundle info = new Bundle(); 9980 info.putString("shortMsg", shortMsg); 9981 info.putString("longMsg", longMsg); 9982 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 9983 Binder.restoreCallingIdentity(origId); 9984 return; 9985 } 9986 9987 // If we can't identify the process or it's already exceeded its crash quota, 9988 // quit right away without showing a crash dialog. 9989 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 9990 Binder.restoreCallingIdentity(origId); 9991 return; 9992 } 9993 9994 Message msg = Message.obtain(); 9995 msg.what = SHOW_ERROR_MSG; 9996 HashMap data = new HashMap(); 9997 data.put("result", result); 9998 data.put("app", r); 9999 msg.obj = data; 10000 mHandler.sendMessage(msg); 10001 10002 Binder.restoreCallingIdentity(origId); 10003 } 10004 10005 int res = result.get(); 10006 10007 Intent appErrorIntent = null; 10008 synchronized (this) { 10009 if (r != null && !r.isolated) { 10010 // XXX Can't keep track of crash time for isolated processes, 10011 // since they don't have a persistent identity. 10012 mProcessCrashTimes.put(r.info.processName, r.uid, 10013 SystemClock.uptimeMillis()); 10014 } 10015 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10016 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10017 } 10018 } 10019 10020 if (appErrorIntent != null) { 10021 try { 10022 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10023 } catch (ActivityNotFoundException e) { 10024 Slog.w(TAG, "bug report receiver dissappeared", e); 10025 } 10026 } 10027 } 10028 10029 Intent createAppErrorIntentLocked(ProcessRecord r, 10030 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10031 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10032 if (report == null) { 10033 return null; 10034 } 10035 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10036 result.setComponent(r.errorReportReceiver); 10037 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10038 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10039 return result; 10040 } 10041 10042 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10043 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10044 if (r.errorReportReceiver == null) { 10045 return null; 10046 } 10047 10048 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10049 return null; 10050 } 10051 10052 ApplicationErrorReport report = new ApplicationErrorReport(); 10053 report.packageName = r.info.packageName; 10054 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10055 report.processName = r.processName; 10056 report.time = timeMillis; 10057 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10058 10059 if (r.crashing || r.forceCrashReport) { 10060 report.type = ApplicationErrorReport.TYPE_CRASH; 10061 report.crashInfo = crashInfo; 10062 } else if (r.notResponding) { 10063 report.type = ApplicationErrorReport.TYPE_ANR; 10064 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10065 10066 report.anrInfo.activity = r.notRespondingReport.tag; 10067 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10068 report.anrInfo.info = r.notRespondingReport.longMsg; 10069 } 10070 10071 return report; 10072 } 10073 10074 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10075 enforceNotIsolatedCaller("getProcessesInErrorState"); 10076 // assume our apps are happy - lazy create the list 10077 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10078 10079 final boolean allUsers = ActivityManager.checkUidPermission( 10080 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10081 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10082 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10083 10084 synchronized (this) { 10085 10086 // iterate across all processes 10087 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10088 ProcessRecord app = mLruProcesses.get(i); 10089 if (!allUsers && app.userId != userId) { 10090 continue; 10091 } 10092 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10093 // This one's in trouble, so we'll generate a report for it 10094 // crashes are higher priority (in case there's a crash *and* an anr) 10095 ActivityManager.ProcessErrorStateInfo report = null; 10096 if (app.crashing) { 10097 report = app.crashingReport; 10098 } else if (app.notResponding) { 10099 report = app.notRespondingReport; 10100 } 10101 10102 if (report != null) { 10103 if (errList == null) { 10104 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10105 } 10106 errList.add(report); 10107 } else { 10108 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10109 " crashing = " + app.crashing + 10110 " notResponding = " + app.notResponding); 10111 } 10112 } 10113 } 10114 } 10115 10116 return errList; 10117 } 10118 10119 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10120 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10121 if (currApp != null) { 10122 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10123 } 10124 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10125 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10126 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10127 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10128 if (currApp != null) { 10129 currApp.lru = 0; 10130 } 10131 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10132 } else if (adj >= ProcessList.SERVICE_ADJ) { 10133 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10134 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10135 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10136 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10137 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10138 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10139 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10140 } else { 10141 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10142 } 10143 } 10144 10145 private void fillInProcMemInfo(ProcessRecord app, 10146 ActivityManager.RunningAppProcessInfo outInfo) { 10147 outInfo.pid = app.pid; 10148 outInfo.uid = app.info.uid; 10149 if (mHeavyWeightProcess == app) { 10150 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10151 } 10152 if (app.persistent) { 10153 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10154 } 10155 if (app.activities.size() > 0) { 10156 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10157 } 10158 outInfo.lastTrimLevel = app.trimMemoryLevel; 10159 int adj = app.curAdj; 10160 outInfo.importance = oomAdjToImportance(adj, outInfo); 10161 outInfo.importanceReasonCode = app.adjTypeCode; 10162 } 10163 10164 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10165 enforceNotIsolatedCaller("getRunningAppProcesses"); 10166 // Lazy instantiation of list 10167 List<ActivityManager.RunningAppProcessInfo> runList = null; 10168 final boolean allUsers = ActivityManager.checkUidPermission( 10169 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10170 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10171 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10172 synchronized (this) { 10173 // Iterate across all processes 10174 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10175 ProcessRecord app = mLruProcesses.get(i); 10176 if (!allUsers && app.userId != userId) { 10177 continue; 10178 } 10179 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10180 // Generate process state info for running application 10181 ActivityManager.RunningAppProcessInfo currApp = 10182 new ActivityManager.RunningAppProcessInfo(app.processName, 10183 app.pid, app.getPackageList()); 10184 fillInProcMemInfo(app, currApp); 10185 if (app.adjSource instanceof ProcessRecord) { 10186 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10187 currApp.importanceReasonImportance = oomAdjToImportance( 10188 app.adjSourceOom, null); 10189 } else if (app.adjSource instanceof ActivityRecord) { 10190 ActivityRecord r = (ActivityRecord)app.adjSource; 10191 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10192 } 10193 if (app.adjTarget instanceof ComponentName) { 10194 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10195 } 10196 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10197 // + " lru=" + currApp.lru); 10198 if (runList == null) { 10199 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10200 } 10201 runList.add(currApp); 10202 } 10203 } 10204 } 10205 return runList; 10206 } 10207 10208 public List<ApplicationInfo> getRunningExternalApplications() { 10209 enforceNotIsolatedCaller("getRunningExternalApplications"); 10210 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10211 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10212 if (runningApps != null && runningApps.size() > 0) { 10213 Set<String> extList = new HashSet<String>(); 10214 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10215 if (app.pkgList != null) { 10216 for (String pkg : app.pkgList) { 10217 extList.add(pkg); 10218 } 10219 } 10220 } 10221 IPackageManager pm = AppGlobals.getPackageManager(); 10222 for (String pkg : extList) { 10223 try { 10224 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10225 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10226 retList.add(info); 10227 } 10228 } catch (RemoteException e) { 10229 } 10230 } 10231 } 10232 return retList; 10233 } 10234 10235 @Override 10236 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10237 enforceNotIsolatedCaller("getMyMemoryState"); 10238 synchronized (this) { 10239 ProcessRecord proc; 10240 synchronized (mPidsSelfLocked) { 10241 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10242 } 10243 fillInProcMemInfo(proc, outInfo); 10244 } 10245 } 10246 10247 @Override 10248 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10249 if (checkCallingPermission(android.Manifest.permission.DUMP) 10250 != PackageManager.PERMISSION_GRANTED) { 10251 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10252 + Binder.getCallingPid() 10253 + ", uid=" + Binder.getCallingUid() 10254 + " without permission " 10255 + android.Manifest.permission.DUMP); 10256 return; 10257 } 10258 10259 boolean dumpAll = false; 10260 boolean dumpClient = false; 10261 String dumpPackage = null; 10262 10263 int opti = 0; 10264 while (opti < args.length) { 10265 String opt = args[opti]; 10266 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10267 break; 10268 } 10269 opti++; 10270 if ("-a".equals(opt)) { 10271 dumpAll = true; 10272 } else if ("-c".equals(opt)) { 10273 dumpClient = true; 10274 } else if ("-h".equals(opt)) { 10275 pw.println("Activity manager dump options:"); 10276 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10277 pw.println(" cmd may be one of:"); 10278 pw.println(" a[ctivities]: activity stack state"); 10279 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10280 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10281 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10282 pw.println(" o[om]: out of memory management"); 10283 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10284 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10285 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10286 pw.println(" service [COMP_SPEC]: service client-side state"); 10287 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10288 pw.println(" all: dump all activities"); 10289 pw.println(" top: dump the top activity"); 10290 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10291 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10292 pw.println(" a partial substring in a component name, a"); 10293 pw.println(" hex object identifier."); 10294 pw.println(" -a: include all available server state."); 10295 pw.println(" -c: include client state."); 10296 return; 10297 } else { 10298 pw.println("Unknown argument: " + opt + "; use -h for help"); 10299 } 10300 } 10301 10302 long origId = Binder.clearCallingIdentity(); 10303 boolean more = false; 10304 // Is the caller requesting to dump a particular piece of data? 10305 if (opti < args.length) { 10306 String cmd = args[opti]; 10307 opti++; 10308 if ("activities".equals(cmd) || "a".equals(cmd)) { 10309 synchronized (this) { 10310 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10311 } 10312 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10313 String[] newArgs; 10314 String name; 10315 if (opti >= args.length) { 10316 name = null; 10317 newArgs = EMPTY_STRING_ARRAY; 10318 } else { 10319 name = args[opti]; 10320 opti++; 10321 newArgs = new String[args.length - opti]; 10322 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10323 args.length - opti); 10324 } 10325 synchronized (this) { 10326 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10327 } 10328 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10329 String[] newArgs; 10330 String name; 10331 if (opti >= args.length) { 10332 name = null; 10333 newArgs = EMPTY_STRING_ARRAY; 10334 } else { 10335 name = args[opti]; 10336 opti++; 10337 newArgs = new String[args.length - opti]; 10338 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10339 args.length - opti); 10340 } 10341 synchronized (this) { 10342 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10343 } 10344 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10345 String[] newArgs; 10346 String name; 10347 if (opti >= args.length) { 10348 name = null; 10349 newArgs = EMPTY_STRING_ARRAY; 10350 } else { 10351 name = args[opti]; 10352 opti++; 10353 newArgs = new String[args.length - opti]; 10354 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10355 args.length - opti); 10356 } 10357 synchronized (this) { 10358 dumpProcessesLocked(fd, pw, args, opti, true, name); 10359 } 10360 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10361 synchronized (this) { 10362 dumpOomLocked(fd, pw, args, opti, true); 10363 } 10364 } else if ("provider".equals(cmd)) { 10365 String[] newArgs; 10366 String name; 10367 if (opti >= args.length) { 10368 name = null; 10369 newArgs = EMPTY_STRING_ARRAY; 10370 } else { 10371 name = args[opti]; 10372 opti++; 10373 newArgs = new String[args.length - opti]; 10374 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10375 } 10376 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10377 pw.println("No providers match: " + name); 10378 pw.println("Use -h for help."); 10379 } 10380 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10381 synchronized (this) { 10382 dumpProvidersLocked(fd, pw, args, opti, true, null); 10383 } 10384 } else if ("service".equals(cmd)) { 10385 String[] newArgs; 10386 String name; 10387 if (opti >= args.length) { 10388 name = null; 10389 newArgs = EMPTY_STRING_ARRAY; 10390 } else { 10391 name = args[opti]; 10392 opti++; 10393 newArgs = new String[args.length - opti]; 10394 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10395 args.length - opti); 10396 } 10397 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10398 pw.println("No services match: " + name); 10399 pw.println("Use -h for help."); 10400 } 10401 } else if ("package".equals(cmd)) { 10402 String[] newArgs; 10403 if (opti >= args.length) { 10404 pw.println("package: no package name specified"); 10405 pw.println("Use -h for help."); 10406 } else { 10407 dumpPackage = args[opti]; 10408 opti++; 10409 newArgs = new String[args.length - opti]; 10410 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10411 args.length - opti); 10412 args = newArgs; 10413 opti = 0; 10414 more = true; 10415 } 10416 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10417 synchronized (this) { 10418 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10419 } 10420 } else { 10421 // Dumping a single activity? 10422 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10423 pw.println("Bad activity command, or no activities match: " + cmd); 10424 pw.println("Use -h for help."); 10425 } 10426 } 10427 if (!more) { 10428 Binder.restoreCallingIdentity(origId); 10429 return; 10430 } 10431 } 10432 10433 // No piece of data specified, dump everything. 10434 synchronized (this) { 10435 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10436 pw.println(); 10437 if (dumpAll) { 10438 pw.println("-------------------------------------------------------------------------------"); 10439 } 10440 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10441 pw.println(); 10442 if (dumpAll) { 10443 pw.println("-------------------------------------------------------------------------------"); 10444 } 10445 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10446 pw.println(); 10447 if (dumpAll) { 10448 pw.println("-------------------------------------------------------------------------------"); 10449 } 10450 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10451 pw.println(); 10452 if (dumpAll) { 10453 pw.println("-------------------------------------------------------------------------------"); 10454 } 10455 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10456 pw.println(); 10457 if (dumpAll) { 10458 pw.println("-------------------------------------------------------------------------------"); 10459 } 10460 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10461 } 10462 Binder.restoreCallingIdentity(origId); 10463 } 10464 10465 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10466 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10467 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10468 10469 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10470 dumpPackage); 10471 boolean needSep = printedAnything; 10472 10473 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10474 dumpPackage, needSep, " mFocusedActivity: "); 10475 if (printed) { 10476 printedAnything = true; 10477 needSep = false; 10478 } 10479 10480 if (dumpPackage == null) { 10481 if (needSep) { 10482 pw.println(); 10483 } 10484 needSep = true; 10485 printedAnything = true; 10486 mStackSupervisor.dump(pw, " "); 10487 } 10488 10489 if (mRecentTasks.size() > 0) { 10490 boolean printedHeader = false; 10491 10492 final int N = mRecentTasks.size(); 10493 for (int i=0; i<N; i++) { 10494 TaskRecord tr = mRecentTasks.get(i); 10495 if (dumpPackage != null) { 10496 if (tr.realActivity == null || 10497 !dumpPackage.equals(tr.realActivity)) { 10498 continue; 10499 } 10500 } 10501 if (!printedHeader) { 10502 if (needSep) { 10503 pw.println(); 10504 } 10505 pw.println(" Recent tasks:"); 10506 printedHeader = true; 10507 printedAnything = true; 10508 } 10509 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10510 pw.println(tr); 10511 if (dumpAll) { 10512 mRecentTasks.get(i).dump(pw, " "); 10513 } 10514 } 10515 } 10516 10517 if (!printedAnything) { 10518 pw.println(" (nothing)"); 10519 } 10520 } 10521 10522 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10523 int opti, boolean dumpAll, String dumpPackage) { 10524 boolean needSep = false; 10525 boolean printedAnything = false; 10526 int numPers = 0; 10527 10528 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10529 10530 if (dumpAll) { 10531 final int NP = mProcessNames.getMap().size(); 10532 for (int ip=0; ip<NP; ip++) { 10533 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10534 final int NA = procs.size(); 10535 for (int ia=0; ia<NA; ia++) { 10536 ProcessRecord r = procs.valueAt(ia); 10537 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10538 continue; 10539 } 10540 if (!needSep) { 10541 pw.println(" All known processes:"); 10542 needSep = true; 10543 printedAnything = true; 10544 } 10545 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10546 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10547 pw.print(" "); pw.println(r); 10548 r.dump(pw, " "); 10549 if (r.persistent) { 10550 numPers++; 10551 } 10552 } 10553 } 10554 } 10555 10556 if (mIsolatedProcesses.size() > 0) { 10557 boolean printed = false; 10558 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10559 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10560 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10561 continue; 10562 } 10563 if (!printed) { 10564 if (needSep) { 10565 pw.println(); 10566 } 10567 pw.println(" Isolated process list (sorted by uid):"); 10568 printedAnything = true; 10569 printed = true; 10570 needSep = true; 10571 } 10572 pw.println(String.format("%sIsolated #%2d: %s", 10573 " ", i, r.toString())); 10574 } 10575 } 10576 10577 if (mLruProcesses.size() > 0) { 10578 if (needSep) { 10579 pw.println(); 10580 } 10581 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10582 pw.print(" total, non-act at "); 10583 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10584 pw.print(", non-svc at "); 10585 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10586 pw.println("):"); 10587 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10588 needSep = true; 10589 printedAnything = true; 10590 } 10591 10592 if (dumpAll || dumpPackage != null) { 10593 synchronized (mPidsSelfLocked) { 10594 boolean printed = false; 10595 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10596 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10597 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10598 continue; 10599 } 10600 if (!printed) { 10601 if (needSep) pw.println(); 10602 needSep = true; 10603 pw.println(" PID mappings:"); 10604 printed = true; 10605 printedAnything = true; 10606 } 10607 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10608 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10609 } 10610 } 10611 } 10612 10613 if (mForegroundProcesses.size() > 0) { 10614 synchronized (mPidsSelfLocked) { 10615 boolean printed = false; 10616 for (int i=0; i<mForegroundProcesses.size(); i++) { 10617 ProcessRecord r = mPidsSelfLocked.get( 10618 mForegroundProcesses.valueAt(i).pid); 10619 if (dumpPackage != null && (r == null 10620 || !r.pkgList.containsKey(dumpPackage))) { 10621 continue; 10622 } 10623 if (!printed) { 10624 if (needSep) pw.println(); 10625 needSep = true; 10626 pw.println(" Foreground Processes:"); 10627 printed = true; 10628 printedAnything = true; 10629 } 10630 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10631 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10632 } 10633 } 10634 } 10635 10636 if (mPersistentStartingProcesses.size() > 0) { 10637 if (needSep) pw.println(); 10638 needSep = true; 10639 printedAnything = true; 10640 pw.println(" Persisent processes that are starting:"); 10641 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10642 "Starting Norm", "Restarting PERS", dumpPackage); 10643 } 10644 10645 if (mRemovedProcesses.size() > 0) { 10646 if (needSep) pw.println(); 10647 needSep = true; 10648 printedAnything = true; 10649 pw.println(" Processes that are being removed:"); 10650 dumpProcessList(pw, this, mRemovedProcesses, " ", 10651 "Removed Norm", "Removed PERS", dumpPackage); 10652 } 10653 10654 if (mProcessesOnHold.size() > 0) { 10655 if (needSep) pw.println(); 10656 needSep = true; 10657 printedAnything = true; 10658 pw.println(" Processes that are on old until the system is ready:"); 10659 dumpProcessList(pw, this, mProcessesOnHold, " ", 10660 "OnHold Norm", "OnHold PERS", dumpPackage); 10661 } 10662 10663 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10664 10665 if (mProcessCrashTimes.getMap().size() > 0) { 10666 boolean printed = false; 10667 long now = SystemClock.uptimeMillis(); 10668 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10669 final int NP = pmap.size(); 10670 for (int ip=0; ip<NP; ip++) { 10671 String pname = pmap.keyAt(ip); 10672 SparseArray<Long> uids = pmap.valueAt(ip); 10673 final int N = uids.size(); 10674 for (int i=0; i<N; i++) { 10675 int puid = uids.keyAt(i); 10676 ProcessRecord r = mProcessNames.get(pname, puid); 10677 if (dumpPackage != null && (r == null 10678 || !r.pkgList.containsKey(dumpPackage))) { 10679 continue; 10680 } 10681 if (!printed) { 10682 if (needSep) pw.println(); 10683 needSep = true; 10684 pw.println(" Time since processes crashed:"); 10685 printed = true; 10686 printedAnything = true; 10687 } 10688 pw.print(" Process "); pw.print(pname); 10689 pw.print(" uid "); pw.print(puid); 10690 pw.print(": last crashed "); 10691 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10692 pw.println(" ago"); 10693 } 10694 } 10695 } 10696 10697 if (mBadProcesses.getMap().size() > 0) { 10698 boolean printed = false; 10699 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10700 final int NP = pmap.size(); 10701 for (int ip=0; ip<NP; ip++) { 10702 String pname = pmap.keyAt(ip); 10703 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10704 final int N = uids.size(); 10705 for (int i=0; i<N; i++) { 10706 int puid = uids.keyAt(i); 10707 ProcessRecord r = mProcessNames.get(pname, puid); 10708 if (dumpPackage != null && (r == null 10709 || !r.pkgList.containsKey(dumpPackage))) { 10710 continue; 10711 } 10712 if (!printed) { 10713 if (needSep) pw.println(); 10714 needSep = true; 10715 pw.println(" Bad processes:"); 10716 printedAnything = true; 10717 } 10718 BadProcessInfo info = uids.valueAt(i); 10719 pw.print(" Bad process "); pw.print(pname); 10720 pw.print(" uid "); pw.print(puid); 10721 pw.print(": crashed at time "); pw.println(info.time); 10722 if (info.shortMsg != null) { 10723 pw.print(" Short msg: "); pw.println(info.shortMsg); 10724 } 10725 if (info.longMsg != null) { 10726 pw.print(" Long msg: "); pw.println(info.longMsg); 10727 } 10728 if (info.stack != null) { 10729 pw.println(" Stack:"); 10730 int lastPos = 0; 10731 for (int pos=0; pos<info.stack.length(); pos++) { 10732 if (info.stack.charAt(pos) == '\n') { 10733 pw.print(" "); 10734 pw.write(info.stack, lastPos, pos-lastPos); 10735 pw.println(); 10736 lastPos = pos+1; 10737 } 10738 } 10739 if (lastPos < info.stack.length()) { 10740 pw.print(" "); 10741 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10742 pw.println(); 10743 } 10744 } 10745 } 10746 } 10747 } 10748 10749 if (dumpPackage == null) { 10750 pw.println(); 10751 needSep = false; 10752 pw.println(" mStartedUsers:"); 10753 for (int i=0; i<mStartedUsers.size(); i++) { 10754 UserStartedState uss = mStartedUsers.valueAt(i); 10755 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10756 pw.print(": "); uss.dump("", pw); 10757 } 10758 pw.print(" mStartedUserArray: ["); 10759 for (int i=0; i<mStartedUserArray.length; i++) { 10760 if (i > 0) pw.print(", "); 10761 pw.print(mStartedUserArray[i]); 10762 } 10763 pw.println("]"); 10764 pw.print(" mUserLru: ["); 10765 for (int i=0; i<mUserLru.size(); i++) { 10766 if (i > 0) pw.print(", "); 10767 pw.print(mUserLru.get(i)); 10768 } 10769 pw.println("]"); 10770 if (dumpAll) { 10771 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10772 } 10773 } 10774 if (mHomeProcess != null && (dumpPackage == null 10775 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10776 if (needSep) { 10777 pw.println(); 10778 needSep = false; 10779 } 10780 pw.println(" mHomeProcess: " + mHomeProcess); 10781 } 10782 if (mPreviousProcess != null && (dumpPackage == null 10783 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 10784 if (needSep) { 10785 pw.println(); 10786 needSep = false; 10787 } 10788 pw.println(" mPreviousProcess: " + mPreviousProcess); 10789 } 10790 if (dumpAll) { 10791 StringBuilder sb = new StringBuilder(128); 10792 sb.append(" mPreviousProcessVisibleTime: "); 10793 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 10794 pw.println(sb); 10795 } 10796 if (mHeavyWeightProcess != null && (dumpPackage == null 10797 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 10798 if (needSep) { 10799 pw.println(); 10800 needSep = false; 10801 } 10802 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10803 } 10804 if (dumpPackage == null) { 10805 pw.println(" mConfiguration: " + mConfiguration); 10806 } 10807 if (dumpAll) { 10808 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 10809 if (mCompatModePackages.getPackages().size() > 0) { 10810 boolean printed = false; 10811 for (Map.Entry<String, Integer> entry 10812 : mCompatModePackages.getPackages().entrySet()) { 10813 String pkg = entry.getKey(); 10814 int mode = entry.getValue(); 10815 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 10816 continue; 10817 } 10818 if (!printed) { 10819 pw.println(" mScreenCompatPackages:"); 10820 printed = true; 10821 } 10822 pw.print(" "); pw.print(pkg); pw.print(": "); 10823 pw.print(mode); pw.println(); 10824 } 10825 } 10826 } 10827 if (dumpPackage == null) { 10828 if (mSleeping || mWentToSleep || mLockScreenShown) { 10829 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 10830 + " mLockScreenShown " + mLockScreenShown); 10831 } 10832 if (mShuttingDown) { 10833 pw.println(" mShuttingDown=" + mShuttingDown); 10834 } 10835 } 10836 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 10837 || mOrigWaitForDebugger) { 10838 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 10839 || dumpPackage.equals(mOrigDebugApp)) { 10840 if (needSep) { 10841 pw.println(); 10842 needSep = false; 10843 } 10844 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 10845 + " mDebugTransient=" + mDebugTransient 10846 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 10847 } 10848 } 10849 if (mOpenGlTraceApp != null) { 10850 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 10851 if (needSep) { 10852 pw.println(); 10853 needSep = false; 10854 } 10855 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 10856 } 10857 } 10858 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 10859 || mProfileFd != null) { 10860 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 10861 if (needSep) { 10862 pw.println(); 10863 needSep = false; 10864 } 10865 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 10866 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 10867 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 10868 + mAutoStopProfiler); 10869 } 10870 } 10871 if (dumpPackage == null) { 10872 if (mAlwaysFinishActivities || mController != null) { 10873 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 10874 + " mController=" + mController); 10875 } 10876 if (dumpAll) { 10877 pw.println(" Total persistent processes: " + numPers); 10878 pw.println(" mProcessesReady=" + mProcessesReady 10879 + " mSystemReady=" + mSystemReady); 10880 pw.println(" mBooting=" + mBooting 10881 + " mBooted=" + mBooted 10882 + " mFactoryTest=" + mFactoryTest); 10883 pw.print(" mLastPowerCheckRealtime="); 10884 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 10885 pw.println(""); 10886 pw.print(" mLastPowerCheckUptime="); 10887 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 10888 pw.println(""); 10889 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 10890 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 10891 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 10892 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 10893 + " (" + mLruProcesses.size() + " total)" 10894 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 10895 + " mNumServiceProcs=" + mNumServiceProcs 10896 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 10897 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 10898 + " mLastMemoryLevel" + mLastMemoryLevel 10899 + " mLastNumProcesses" + mLastNumProcesses); 10900 long now = SystemClock.uptimeMillis(); 10901 pw.print(" mLastIdleTime="); 10902 TimeUtils.formatDuration(now, mLastIdleTime, pw); 10903 pw.print(" mLowRamSinceLastIdle="); 10904 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 10905 pw.println(); 10906 } 10907 } 10908 10909 if (!printedAnything) { 10910 pw.println(" (nothing)"); 10911 } 10912 } 10913 10914 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 10915 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 10916 if (mProcessesToGc.size() > 0) { 10917 boolean printed = false; 10918 long now = SystemClock.uptimeMillis(); 10919 for (int i=0; i<mProcessesToGc.size(); i++) { 10920 ProcessRecord proc = mProcessesToGc.get(i); 10921 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 10922 continue; 10923 } 10924 if (!printed) { 10925 if (needSep) pw.println(); 10926 needSep = true; 10927 pw.println(" Processes that are waiting to GC:"); 10928 printed = true; 10929 } 10930 pw.print(" Process "); pw.println(proc); 10931 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 10932 pw.print(", last gced="); 10933 pw.print(now-proc.lastRequestedGc); 10934 pw.print(" ms ago, last lowMem="); 10935 pw.print(now-proc.lastLowMemory); 10936 pw.println(" ms ago"); 10937 10938 } 10939 } 10940 return needSep; 10941 } 10942 10943 void printOomLevel(PrintWriter pw, String name, int adj) { 10944 pw.print(" "); 10945 if (adj >= 0) { 10946 pw.print(' '); 10947 if (adj < 10) pw.print(' '); 10948 } else { 10949 if (adj > -10) pw.print(' '); 10950 } 10951 pw.print(adj); 10952 pw.print(": "); 10953 pw.print(name); 10954 pw.print(" ("); 10955 pw.print(mProcessList.getMemLevel(adj)/1024); 10956 pw.println(" kB)"); 10957 } 10958 10959 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10960 int opti, boolean dumpAll) { 10961 boolean needSep = false; 10962 10963 if (mLruProcesses.size() > 0) { 10964 if (needSep) pw.println(); 10965 needSep = true; 10966 pw.println(" OOM levels:"); 10967 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 10968 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 10969 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 10970 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 10971 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 10972 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 10973 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 10974 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 10975 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 10976 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 10977 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 10978 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 10979 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 10980 10981 if (needSep) pw.println(); 10982 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 10983 pw.print(" total, non-act at "); 10984 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10985 pw.print(", non-svc at "); 10986 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10987 pw.println("):"); 10988 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 10989 needSep = true; 10990 } 10991 10992 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 10993 10994 pw.println(); 10995 pw.println(" mHomeProcess: " + mHomeProcess); 10996 pw.println(" mPreviousProcess: " + mPreviousProcess); 10997 if (mHeavyWeightProcess != null) { 10998 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10999 } 11000 11001 return true; 11002 } 11003 11004 /** 11005 * There are three ways to call this: 11006 * - no provider specified: dump all the providers 11007 * - a flattened component name that matched an existing provider was specified as the 11008 * first arg: dump that one provider 11009 * - the first arg isn't the flattened component name of an existing provider: 11010 * dump all providers whose component contains the first arg as a substring 11011 */ 11012 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11013 int opti, boolean dumpAll) { 11014 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11015 } 11016 11017 static class ItemMatcher { 11018 ArrayList<ComponentName> components; 11019 ArrayList<String> strings; 11020 ArrayList<Integer> objects; 11021 boolean all; 11022 11023 ItemMatcher() { 11024 all = true; 11025 } 11026 11027 void build(String name) { 11028 ComponentName componentName = ComponentName.unflattenFromString(name); 11029 if (componentName != null) { 11030 if (components == null) { 11031 components = new ArrayList<ComponentName>(); 11032 } 11033 components.add(componentName); 11034 all = false; 11035 } else { 11036 int objectId = 0; 11037 // Not a '/' separated full component name; maybe an object ID? 11038 try { 11039 objectId = Integer.parseInt(name, 16); 11040 if (objects == null) { 11041 objects = new ArrayList<Integer>(); 11042 } 11043 objects.add(objectId); 11044 all = false; 11045 } catch (RuntimeException e) { 11046 // Not an integer; just do string match. 11047 if (strings == null) { 11048 strings = new ArrayList<String>(); 11049 } 11050 strings.add(name); 11051 all = false; 11052 } 11053 } 11054 } 11055 11056 int build(String[] args, int opti) { 11057 for (; opti<args.length; opti++) { 11058 String name = args[opti]; 11059 if ("--".equals(name)) { 11060 return opti+1; 11061 } 11062 build(name); 11063 } 11064 return opti; 11065 } 11066 11067 boolean match(Object object, ComponentName comp) { 11068 if (all) { 11069 return true; 11070 } 11071 if (components != null) { 11072 for (int i=0; i<components.size(); i++) { 11073 if (components.get(i).equals(comp)) { 11074 return true; 11075 } 11076 } 11077 } 11078 if (objects != null) { 11079 for (int i=0; i<objects.size(); i++) { 11080 if (System.identityHashCode(object) == objects.get(i)) { 11081 return true; 11082 } 11083 } 11084 } 11085 if (strings != null) { 11086 String flat = comp.flattenToString(); 11087 for (int i=0; i<strings.size(); i++) { 11088 if (flat.contains(strings.get(i))) { 11089 return true; 11090 } 11091 } 11092 } 11093 return false; 11094 } 11095 } 11096 11097 /** 11098 * There are three things that cmd can be: 11099 * - a flattened component name that matches an existing activity 11100 * - the cmd arg isn't the flattened component name of an existing activity: 11101 * dump all activity whose component contains the cmd as a substring 11102 * - A hex number of the ActivityRecord object instance. 11103 */ 11104 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11105 int opti, boolean dumpAll) { 11106 ArrayList<ActivityRecord> activities; 11107 11108 synchronized (this) { 11109 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11110 } 11111 11112 if (activities.size() <= 0) { 11113 return false; 11114 } 11115 11116 String[] newArgs = new String[args.length - opti]; 11117 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11118 11119 TaskRecord lastTask = null; 11120 boolean needSep = false; 11121 for (int i=activities.size()-1; i>=0; i--) { 11122 ActivityRecord r = activities.get(i); 11123 if (needSep) { 11124 pw.println(); 11125 } 11126 needSep = true; 11127 synchronized (this) { 11128 if (lastTask != r.task) { 11129 lastTask = r.task; 11130 pw.print("TASK "); pw.print(lastTask.affinity); 11131 pw.print(" id="); pw.println(lastTask.taskId); 11132 if (dumpAll) { 11133 lastTask.dump(pw, " "); 11134 } 11135 } 11136 } 11137 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11138 } 11139 return true; 11140 } 11141 11142 /** 11143 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11144 * there is a thread associated with the activity. 11145 */ 11146 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11147 final ActivityRecord r, String[] args, boolean dumpAll) { 11148 String innerPrefix = prefix + " "; 11149 synchronized (this) { 11150 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11151 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11152 pw.print(" pid="); 11153 if (r.app != null) pw.println(r.app.pid); 11154 else pw.println("(not running)"); 11155 if (dumpAll) { 11156 r.dump(pw, innerPrefix); 11157 } 11158 } 11159 if (r.app != null && r.app.thread != null) { 11160 // flush anything that is already in the PrintWriter since the thread is going 11161 // to write to the file descriptor directly 11162 pw.flush(); 11163 try { 11164 TransferPipe tp = new TransferPipe(); 11165 try { 11166 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11167 r.appToken, innerPrefix, args); 11168 tp.go(fd); 11169 } finally { 11170 tp.kill(); 11171 } 11172 } catch (IOException e) { 11173 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11174 } catch (RemoteException e) { 11175 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11176 } 11177 } 11178 } 11179 11180 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11181 int opti, boolean dumpAll, String dumpPackage) { 11182 boolean needSep = false; 11183 boolean onlyHistory = false; 11184 boolean printedAnything = false; 11185 11186 if ("history".equals(dumpPackage)) { 11187 if (opti < args.length && "-s".equals(args[opti])) { 11188 dumpAll = false; 11189 } 11190 onlyHistory = true; 11191 dumpPackage = null; 11192 } 11193 11194 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11195 if (!onlyHistory && dumpAll) { 11196 if (mRegisteredReceivers.size() > 0) { 11197 boolean printed = false; 11198 Iterator it = mRegisteredReceivers.values().iterator(); 11199 while (it.hasNext()) { 11200 ReceiverList r = (ReceiverList)it.next(); 11201 if (dumpPackage != null && (r.app == null || 11202 !dumpPackage.equals(r.app.info.packageName))) { 11203 continue; 11204 } 11205 if (!printed) { 11206 pw.println(" Registered Receivers:"); 11207 needSep = true; 11208 printed = true; 11209 printedAnything = true; 11210 } 11211 pw.print(" * "); pw.println(r); 11212 r.dump(pw, " "); 11213 } 11214 } 11215 11216 if (mReceiverResolver.dump(pw, needSep ? 11217 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11218 " ", dumpPackage, false)) { 11219 needSep = true; 11220 printedAnything = true; 11221 } 11222 } 11223 11224 for (BroadcastQueue q : mBroadcastQueues) { 11225 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11226 printedAnything |= needSep; 11227 } 11228 11229 needSep = true; 11230 11231 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11232 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11233 if (needSep) { 11234 pw.println(); 11235 } 11236 needSep = true; 11237 printedAnything = true; 11238 pw.print(" Sticky broadcasts for user "); 11239 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11240 StringBuilder sb = new StringBuilder(128); 11241 for (Map.Entry<String, ArrayList<Intent>> ent 11242 : mStickyBroadcasts.valueAt(user).entrySet()) { 11243 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11244 if (dumpAll) { 11245 pw.println(":"); 11246 ArrayList<Intent> intents = ent.getValue(); 11247 final int N = intents.size(); 11248 for (int i=0; i<N; i++) { 11249 sb.setLength(0); 11250 sb.append(" Intent: "); 11251 intents.get(i).toShortString(sb, false, true, false, false); 11252 pw.println(sb.toString()); 11253 Bundle bundle = intents.get(i).getExtras(); 11254 if (bundle != null) { 11255 pw.print(" "); 11256 pw.println(bundle.toString()); 11257 } 11258 } 11259 } else { 11260 pw.println(""); 11261 } 11262 } 11263 } 11264 } 11265 11266 if (!onlyHistory && dumpAll) { 11267 pw.println(); 11268 for (BroadcastQueue queue : mBroadcastQueues) { 11269 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11270 + queue.mBroadcastsScheduled); 11271 } 11272 pw.println(" mHandler:"); 11273 mHandler.dump(new PrintWriterPrinter(pw), " "); 11274 needSep = true; 11275 printedAnything = true; 11276 } 11277 11278 if (!printedAnything) { 11279 pw.println(" (nothing)"); 11280 } 11281 } 11282 11283 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11284 int opti, boolean dumpAll, String dumpPackage) { 11285 boolean needSep; 11286 boolean printedAnything = false; 11287 11288 ItemMatcher matcher = new ItemMatcher(); 11289 matcher.build(args, opti); 11290 11291 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11292 11293 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11294 printedAnything |= needSep; 11295 11296 if (mLaunchingProviders.size() > 0) { 11297 boolean printed = false; 11298 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11299 ContentProviderRecord r = mLaunchingProviders.get(i); 11300 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11301 continue; 11302 } 11303 if (!printed) { 11304 if (needSep) pw.println(); 11305 needSep = true; 11306 pw.println(" Launching content providers:"); 11307 printed = true; 11308 printedAnything = true; 11309 } 11310 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11311 pw.println(r); 11312 } 11313 } 11314 11315 if (mGrantedUriPermissions.size() > 0) { 11316 boolean printed = false; 11317 int dumpUid = -2; 11318 if (dumpPackage != null) { 11319 try { 11320 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11321 } catch (NameNotFoundException e) { 11322 dumpUid = -1; 11323 } 11324 } 11325 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11326 int uid = mGrantedUriPermissions.keyAt(i); 11327 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11328 continue; 11329 } 11330 ArrayMap<Uri, UriPermission> perms 11331 = mGrantedUriPermissions.valueAt(i); 11332 if (!printed) { 11333 if (needSep) pw.println(); 11334 needSep = true; 11335 pw.println(" Granted Uri Permissions:"); 11336 printed = true; 11337 printedAnything = true; 11338 } 11339 pw.print(" * UID "); pw.print(uid); 11340 pw.println(" holds:"); 11341 for (UriPermission perm : perms.values()) { 11342 pw.print(" "); pw.println(perm); 11343 if (dumpAll) { 11344 perm.dump(pw, " "); 11345 } 11346 } 11347 } 11348 } 11349 11350 if (!printedAnything) { 11351 pw.println(" (nothing)"); 11352 } 11353 } 11354 11355 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11356 int opti, boolean dumpAll, String dumpPackage) { 11357 boolean printed = false; 11358 11359 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11360 11361 if (mIntentSenderRecords.size() > 0) { 11362 Iterator<WeakReference<PendingIntentRecord>> it 11363 = mIntentSenderRecords.values().iterator(); 11364 while (it.hasNext()) { 11365 WeakReference<PendingIntentRecord> ref = it.next(); 11366 PendingIntentRecord rec = ref != null ? ref.get(): null; 11367 if (dumpPackage != null && (rec == null 11368 || !dumpPackage.equals(rec.key.packageName))) { 11369 continue; 11370 } 11371 printed = true; 11372 if (rec != null) { 11373 pw.print(" * "); pw.println(rec); 11374 if (dumpAll) { 11375 rec.dump(pw, " "); 11376 } 11377 } else { 11378 pw.print(" * "); pw.println(ref); 11379 } 11380 } 11381 } 11382 11383 if (!printed) { 11384 pw.println(" (nothing)"); 11385 } 11386 } 11387 11388 private static final int dumpProcessList(PrintWriter pw, 11389 ActivityManagerService service, List list, 11390 String prefix, String normalLabel, String persistentLabel, 11391 String dumpPackage) { 11392 int numPers = 0; 11393 final int N = list.size()-1; 11394 for (int i=N; i>=0; i--) { 11395 ProcessRecord r = (ProcessRecord)list.get(i); 11396 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11397 continue; 11398 } 11399 pw.println(String.format("%s%s #%2d: %s", 11400 prefix, (r.persistent ? persistentLabel : normalLabel), 11401 i, r.toString())); 11402 if (r.persistent) { 11403 numPers++; 11404 } 11405 } 11406 return numPers; 11407 } 11408 11409 private static final boolean dumpProcessOomList(PrintWriter pw, 11410 ActivityManagerService service, List<ProcessRecord> origList, 11411 String prefix, String normalLabel, String persistentLabel, 11412 boolean inclDetails, String dumpPackage) { 11413 11414 ArrayList<Pair<ProcessRecord, Integer>> list 11415 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11416 for (int i=0; i<origList.size(); i++) { 11417 ProcessRecord r = origList.get(i); 11418 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11419 continue; 11420 } 11421 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11422 } 11423 11424 if (list.size() <= 0) { 11425 return false; 11426 } 11427 11428 Comparator<Pair<ProcessRecord, Integer>> comparator 11429 = new Comparator<Pair<ProcessRecord, Integer>>() { 11430 @Override 11431 public int compare(Pair<ProcessRecord, Integer> object1, 11432 Pair<ProcessRecord, Integer> object2) { 11433 if (object1.first.setAdj != object2.first.setAdj) { 11434 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11435 } 11436 if (object1.second.intValue() != object2.second.intValue()) { 11437 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11438 } 11439 return 0; 11440 } 11441 }; 11442 11443 Collections.sort(list, comparator); 11444 11445 final long curRealtime = SystemClock.elapsedRealtime(); 11446 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11447 final long curUptime = SystemClock.uptimeMillis(); 11448 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11449 11450 for (int i=list.size()-1; i>=0; i--) { 11451 ProcessRecord r = list.get(i).first; 11452 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11453 char schedGroup; 11454 switch (r.setSchedGroup) { 11455 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11456 schedGroup = 'B'; 11457 break; 11458 case Process.THREAD_GROUP_DEFAULT: 11459 schedGroup = 'F'; 11460 break; 11461 default: 11462 schedGroup = '?'; 11463 break; 11464 } 11465 char foreground; 11466 if (r.foregroundActivities) { 11467 foreground = 'A'; 11468 } else if (r.foregroundServices) { 11469 foreground = 'S'; 11470 } else { 11471 foreground = ' '; 11472 } 11473 String procState = ProcessList.makeProcStateString(r.curProcState); 11474 pw.print(prefix); 11475 pw.print(r.persistent ? persistentLabel : normalLabel); 11476 pw.print(" #"); 11477 int num = (origList.size()-1)-list.get(i).second; 11478 if (num < 10) pw.print(' '); 11479 pw.print(num); 11480 pw.print(": "); 11481 pw.print(oomAdj); 11482 pw.print(' '); 11483 pw.print(schedGroup); 11484 pw.print('/'); 11485 pw.print(foreground); 11486 pw.print('/'); 11487 pw.print(procState); 11488 pw.print(" trm:"); 11489 if (r.trimMemoryLevel < 10) pw.print(' '); 11490 pw.print(r.trimMemoryLevel); 11491 pw.print(' '); 11492 pw.print(r.toShortString()); 11493 pw.print(" ("); 11494 pw.print(r.adjType); 11495 pw.println(')'); 11496 if (r.adjSource != null || r.adjTarget != null) { 11497 pw.print(prefix); 11498 pw.print(" "); 11499 if (r.adjTarget instanceof ComponentName) { 11500 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11501 } else if (r.adjTarget != null) { 11502 pw.print(r.adjTarget.toString()); 11503 } else { 11504 pw.print("{null}"); 11505 } 11506 pw.print("<="); 11507 if (r.adjSource instanceof ProcessRecord) { 11508 pw.print("Proc{"); 11509 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11510 pw.println("}"); 11511 } else if (r.adjSource != null) { 11512 pw.println(r.adjSource.toString()); 11513 } else { 11514 pw.println("{null}"); 11515 } 11516 } 11517 if (inclDetails) { 11518 pw.print(prefix); 11519 pw.print(" "); 11520 pw.print("oom: max="); pw.print(r.maxAdj); 11521 pw.print(" curRaw="); pw.print(r.curRawAdj); 11522 pw.print(" setRaw="); pw.print(r.setRawAdj); 11523 pw.print(" cur="); pw.print(r.curAdj); 11524 pw.print(" set="); pw.println(r.setAdj); 11525 pw.print(prefix); 11526 pw.print(" "); 11527 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11528 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11529 pw.print(" lastPss="); pw.print(r.lastPss); 11530 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11531 pw.print(prefix); 11532 pw.print(" "); 11533 pw.print("keeping="); pw.print(r.keeping); 11534 pw.print(" cached="); pw.print(r.cached); 11535 pw.print(" empty="); pw.print(r.empty); 11536 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11537 11538 if (!r.keeping) { 11539 if (r.lastWakeTime != 0) { 11540 long wtime; 11541 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11542 synchronized (stats) { 11543 wtime = stats.getProcessWakeTime(r.info.uid, 11544 r.pid, curRealtime); 11545 } 11546 long timeUsed = wtime - r.lastWakeTime; 11547 pw.print(prefix); 11548 pw.print(" "); 11549 pw.print("keep awake over "); 11550 TimeUtils.formatDuration(realtimeSince, pw); 11551 pw.print(" used "); 11552 TimeUtils.formatDuration(timeUsed, pw); 11553 pw.print(" ("); 11554 pw.print((timeUsed*100)/realtimeSince); 11555 pw.println("%)"); 11556 } 11557 if (r.lastCpuTime != 0) { 11558 long timeUsed = r.curCpuTime - r.lastCpuTime; 11559 pw.print(prefix); 11560 pw.print(" "); 11561 pw.print("run cpu over "); 11562 TimeUtils.formatDuration(uptimeSince, pw); 11563 pw.print(" used "); 11564 TimeUtils.formatDuration(timeUsed, pw); 11565 pw.print(" ("); 11566 pw.print((timeUsed*100)/uptimeSince); 11567 pw.println("%)"); 11568 } 11569 } 11570 } 11571 } 11572 return true; 11573 } 11574 11575 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11576 ArrayList<ProcessRecord> procs; 11577 synchronized (this) { 11578 if (args != null && args.length > start 11579 && args[start].charAt(0) != '-') { 11580 procs = new ArrayList<ProcessRecord>(); 11581 int pid = -1; 11582 try { 11583 pid = Integer.parseInt(args[start]); 11584 } catch (NumberFormatException e) { 11585 } 11586 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11587 ProcessRecord proc = mLruProcesses.get(i); 11588 if (proc.pid == pid) { 11589 procs.add(proc); 11590 } else if (proc.processName.equals(args[start])) { 11591 procs.add(proc); 11592 } 11593 } 11594 if (procs.size() <= 0) { 11595 return null; 11596 } 11597 } else { 11598 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11599 } 11600 } 11601 return procs; 11602 } 11603 11604 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11605 PrintWriter pw, String[] args) { 11606 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11607 if (procs == null) { 11608 pw.println("No process found for: " + args[0]); 11609 return; 11610 } 11611 11612 long uptime = SystemClock.uptimeMillis(); 11613 long realtime = SystemClock.elapsedRealtime(); 11614 pw.println("Applications Graphics Acceleration Info:"); 11615 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11616 11617 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11618 ProcessRecord r = procs.get(i); 11619 if (r.thread != null) { 11620 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11621 pw.flush(); 11622 try { 11623 TransferPipe tp = new TransferPipe(); 11624 try { 11625 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11626 tp.go(fd); 11627 } finally { 11628 tp.kill(); 11629 } 11630 } catch (IOException e) { 11631 pw.println("Failure while dumping the app: " + r); 11632 pw.flush(); 11633 } catch (RemoteException e) { 11634 pw.println("Got a RemoteException while dumping the app " + r); 11635 pw.flush(); 11636 } 11637 } 11638 } 11639 } 11640 11641 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11642 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11643 if (procs == null) { 11644 pw.println("No process found for: " + args[0]); 11645 return; 11646 } 11647 11648 pw.println("Applications Database Info:"); 11649 11650 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11651 ProcessRecord r = procs.get(i); 11652 if (r.thread != null) { 11653 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11654 pw.flush(); 11655 try { 11656 TransferPipe tp = new TransferPipe(); 11657 try { 11658 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11659 tp.go(fd); 11660 } finally { 11661 tp.kill(); 11662 } 11663 } catch (IOException e) { 11664 pw.println("Failure while dumping the app: " + r); 11665 pw.flush(); 11666 } catch (RemoteException e) { 11667 pw.println("Got a RemoteException while dumping the app " + r); 11668 pw.flush(); 11669 } 11670 } 11671 } 11672 } 11673 11674 final static class MemItem { 11675 final boolean isProc; 11676 final String label; 11677 final String shortLabel; 11678 final long pss; 11679 final int id; 11680 final boolean hasActivities; 11681 ArrayList<MemItem> subitems; 11682 11683 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11684 boolean _hasActivities) { 11685 isProc = true; 11686 label = _label; 11687 shortLabel = _shortLabel; 11688 pss = _pss; 11689 id = _id; 11690 hasActivities = _hasActivities; 11691 } 11692 11693 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11694 isProc = false; 11695 label = _label; 11696 shortLabel = _shortLabel; 11697 pss = _pss; 11698 id = _id; 11699 hasActivities = false; 11700 } 11701 } 11702 11703 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11704 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11705 if (sort && !isCompact) { 11706 Collections.sort(items, new Comparator<MemItem>() { 11707 @Override 11708 public int compare(MemItem lhs, MemItem rhs) { 11709 if (lhs.pss < rhs.pss) { 11710 return 1; 11711 } else if (lhs.pss > rhs.pss) { 11712 return -1; 11713 } 11714 return 0; 11715 } 11716 }); 11717 } 11718 11719 for (int i=0; i<items.size(); i++) { 11720 MemItem mi = items.get(i); 11721 if (!isCompact) { 11722 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11723 } else if (mi.isProc) { 11724 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11725 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11726 pw.println(mi.hasActivities ? ",a" : ",e"); 11727 } else { 11728 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11729 pw.println(mi.pss); 11730 } 11731 if (mi.subitems != null) { 11732 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11733 true, isCompact); 11734 } 11735 } 11736 } 11737 11738 // These are in KB. 11739 static final long[] DUMP_MEM_BUCKETS = new long[] { 11740 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11741 120*1024, 160*1024, 200*1024, 11742 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11743 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11744 }; 11745 11746 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11747 boolean stackLike) { 11748 int start = label.lastIndexOf('.'); 11749 if (start >= 0) start++; 11750 else start = 0; 11751 int end = label.length(); 11752 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11753 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11754 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11755 out.append(bucket); 11756 out.append(stackLike ? "MB." : "MB "); 11757 out.append(label, start, end); 11758 return; 11759 } 11760 } 11761 out.append(memKB/1024); 11762 out.append(stackLike ? "MB." : "MB "); 11763 out.append(label, start, end); 11764 } 11765 11766 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11767 ProcessList.NATIVE_ADJ, 11768 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11769 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11770 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11771 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11772 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11773 }; 11774 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11775 "Native", 11776 "System", "Persistent", "Foreground", 11777 "Visible", "Perceptible", 11778 "Heavy Weight", "Backup", 11779 "A Services", "Home", 11780 "Previous", "B Services", "Cached" 11781 }; 11782 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 11783 "native", 11784 "sys", "pers", "fore", 11785 "vis", "percept", 11786 "heavy", "backup", 11787 "servicea", "home", 11788 "prev", "serviceb", "cached" 11789 }; 11790 11791 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 11792 long realtime, boolean isCheckinRequest, boolean isCompact) { 11793 if (isCheckinRequest || isCompact) { 11794 // short checkin version 11795 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 11796 } else { 11797 pw.println("Applications Memory Usage (kB):"); 11798 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11799 } 11800 } 11801 11802 final void dumpApplicationMemoryUsage(FileDescriptor fd, 11803 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 11804 boolean dumpDetails = false; 11805 boolean dumpFullDetails = false; 11806 boolean dumpDalvik = false; 11807 boolean oomOnly = false; 11808 boolean isCompact = false; 11809 boolean localOnly = false; 11810 11811 int opti = 0; 11812 while (opti < args.length) { 11813 String opt = args[opti]; 11814 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11815 break; 11816 } 11817 opti++; 11818 if ("-a".equals(opt)) { 11819 dumpDetails = true; 11820 dumpFullDetails = true; 11821 dumpDalvik = true; 11822 } else if ("-d".equals(opt)) { 11823 dumpDalvik = true; 11824 } else if ("-c".equals(opt)) { 11825 isCompact = true; 11826 } else if ("--oom".equals(opt)) { 11827 oomOnly = true; 11828 } else if ("--local".equals(opt)) { 11829 localOnly = true; 11830 } else if ("-h".equals(opt)) { 11831 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 11832 pw.println(" -a: include all available information for each process."); 11833 pw.println(" -d: include dalvik details when dumping process details."); 11834 pw.println(" -c: dump in a compact machine-parseable representation."); 11835 pw.println(" --oom: only show processes organized by oom adj."); 11836 pw.println(" --local: only collect details locally, don't call process."); 11837 pw.println("If [process] is specified it can be the name or "); 11838 pw.println("pid of a specific process to dump."); 11839 return; 11840 } else { 11841 pw.println("Unknown argument: " + opt + "; use -h for help"); 11842 } 11843 } 11844 11845 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 11846 long uptime = SystemClock.uptimeMillis(); 11847 long realtime = SystemClock.elapsedRealtime(); 11848 final long[] tmpLong = new long[1]; 11849 11850 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 11851 if (procs == null) { 11852 // No Java processes. Maybe they want to print a native process. 11853 if (args != null && args.length > opti 11854 && args[opti].charAt(0) != '-') { 11855 ArrayList<ProcessCpuTracker.Stats> nativeProcs 11856 = new ArrayList<ProcessCpuTracker.Stats>(); 11857 updateCpuStatsNow(); 11858 int findPid = -1; 11859 try { 11860 findPid = Integer.parseInt(args[opti]); 11861 } catch (NumberFormatException e) { 11862 } 11863 synchronized (mProcessCpuThread) { 11864 final int N = mProcessCpuTracker.countStats(); 11865 for (int i=0; i<N; i++) { 11866 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 11867 if (st.pid == findPid || (st.baseName != null 11868 && st.baseName.equals(args[opti]))) { 11869 nativeProcs.add(st); 11870 } 11871 } 11872 } 11873 if (nativeProcs.size() > 0) { 11874 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 11875 isCompact); 11876 Debug.MemoryInfo mi = null; 11877 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 11878 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 11879 final int pid = r.pid; 11880 if (!isCheckinRequest && dumpDetails) { 11881 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 11882 } 11883 if (mi == null) { 11884 mi = new Debug.MemoryInfo(); 11885 } 11886 if (dumpDetails || (!brief && !oomOnly)) { 11887 Debug.getMemoryInfo(pid, mi); 11888 } else { 11889 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11890 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11891 } 11892 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11893 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 11894 if (isCheckinRequest) { 11895 pw.println(); 11896 } 11897 } 11898 return; 11899 } 11900 } 11901 pw.println("No process found for: " + args[opti]); 11902 return; 11903 } 11904 11905 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 11906 dumpDetails = true; 11907 } 11908 11909 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 11910 11911 String[] innerArgs = new String[args.length-opti]; 11912 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 11913 11914 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 11915 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 11916 long nativePss=0, dalvikPss=0, otherPss=0; 11917 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 11918 11919 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 11920 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 11921 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 11922 11923 long totalPss = 0; 11924 long cachedPss = 0; 11925 11926 Debug.MemoryInfo mi = null; 11927 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11928 final ProcessRecord r = procs.get(i); 11929 final IApplicationThread thread; 11930 final int pid; 11931 final int oomAdj; 11932 final boolean hasActivities; 11933 synchronized (this) { 11934 thread = r.thread; 11935 pid = r.pid; 11936 oomAdj = r.getSetAdjWithServices(); 11937 hasActivities = r.activities.size() > 0; 11938 } 11939 if (thread != null) { 11940 if (!isCheckinRequest && dumpDetails) { 11941 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 11942 } 11943 if (mi == null) { 11944 mi = new Debug.MemoryInfo(); 11945 } 11946 if (dumpDetails || (!brief && !oomOnly)) { 11947 Debug.getMemoryInfo(pid, mi); 11948 } else { 11949 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11950 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11951 } 11952 if (dumpDetails) { 11953 if (localOnly) { 11954 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11955 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 11956 if (isCheckinRequest) { 11957 pw.println(); 11958 } 11959 } else { 11960 try { 11961 pw.flush(); 11962 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 11963 dumpDalvik, innerArgs); 11964 } catch (RemoteException e) { 11965 if (!isCheckinRequest) { 11966 pw.println("Got RemoteException!"); 11967 pw.flush(); 11968 } 11969 } 11970 } 11971 } 11972 11973 final long myTotalPss = mi.getTotalPss(); 11974 final long myTotalUss = mi.getTotalUss(); 11975 11976 synchronized (this) { 11977 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 11978 // Record this for posterity if the process has been stable. 11979 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 11980 } 11981 } 11982 11983 if (!isCheckinRequest && mi != null) { 11984 totalPss += myTotalPss; 11985 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 11986 (hasActivities ? " / activities)" : ")"), 11987 r.processName, myTotalPss, pid, hasActivities); 11988 procMems.add(pssItem); 11989 procMemsMap.put(pid, pssItem); 11990 11991 nativePss += mi.nativePss; 11992 dalvikPss += mi.dalvikPss; 11993 otherPss += mi.otherPss; 11994 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 11995 long mem = mi.getOtherPss(j); 11996 miscPss[j] += mem; 11997 otherPss -= mem; 11998 } 11999 12000 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12001 cachedPss += myTotalPss; 12002 } 12003 12004 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12005 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12006 || oomIndex == (oomPss.length-1)) { 12007 oomPss[oomIndex] += myTotalPss; 12008 if (oomProcs[oomIndex] == null) { 12009 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12010 } 12011 oomProcs[oomIndex].add(pssItem); 12012 break; 12013 } 12014 } 12015 } 12016 } 12017 } 12018 12019 if (!isCheckinRequest && procs.size() > 1) { 12020 // If we are showing aggregations, also look for native processes to 12021 // include so that our aggregations are more accurate. 12022 updateCpuStatsNow(); 12023 synchronized (mProcessCpuThread) { 12024 final int N = mProcessCpuTracker.countStats(); 12025 for (int i=0; i<N; i++) { 12026 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12027 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12028 if (mi == null) { 12029 mi = new Debug.MemoryInfo(); 12030 } 12031 if (!brief && !oomOnly) { 12032 Debug.getMemoryInfo(st.pid, mi); 12033 } else { 12034 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12035 mi.nativePrivateDirty = (int)tmpLong[0]; 12036 } 12037 12038 final long myTotalPss = mi.getTotalPss(); 12039 totalPss += myTotalPss; 12040 12041 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12042 st.name, myTotalPss, st.pid, false); 12043 procMems.add(pssItem); 12044 12045 nativePss += mi.nativePss; 12046 dalvikPss += mi.dalvikPss; 12047 otherPss += mi.otherPss; 12048 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12049 long mem = mi.getOtherPss(j); 12050 miscPss[j] += mem; 12051 otherPss -= mem; 12052 } 12053 oomPss[0] += myTotalPss; 12054 if (oomProcs[0] == null) { 12055 oomProcs[0] = new ArrayList<MemItem>(); 12056 } 12057 oomProcs[0].add(pssItem); 12058 } 12059 } 12060 } 12061 12062 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12063 12064 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12065 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12066 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12067 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12068 String label = Debug.MemoryInfo.getOtherLabel(j); 12069 catMems.add(new MemItem(label, label, miscPss[j], j)); 12070 } 12071 12072 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12073 for (int j=0; j<oomPss.length; j++) { 12074 if (oomPss[j] != 0) { 12075 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12076 : DUMP_MEM_OOM_LABEL[j]; 12077 MemItem item = new MemItem(label, label, oomPss[j], 12078 DUMP_MEM_OOM_ADJ[j]); 12079 item.subitems = oomProcs[j]; 12080 oomMems.add(item); 12081 } 12082 } 12083 12084 if (!brief && !oomOnly && !isCompact) { 12085 pw.println(); 12086 pw.println("Total PSS by process:"); 12087 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12088 pw.println(); 12089 } 12090 if (!isCompact) { 12091 pw.println("Total PSS by OOM adjustment:"); 12092 } 12093 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12094 if (!brief && !oomOnly) { 12095 PrintWriter out = categoryPw != null ? categoryPw : pw; 12096 if (!isCompact) { 12097 out.println(); 12098 out.println("Total PSS by category:"); 12099 } 12100 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12101 } 12102 if (!isCompact) { 12103 pw.println(); 12104 } 12105 MemInfoReader memInfo = new MemInfoReader(); 12106 memInfo.readMemInfo(); 12107 if (!brief) { 12108 if (!isCompact) { 12109 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12110 pw.println(" kB"); 12111 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12112 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12113 pw.print(cachedPss); pw.print(" cached pss + "); 12114 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12115 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12116 } else { 12117 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12118 pw.print(cachedPss + memInfo.getCachedSizeKb() 12119 + memInfo.getFreeSizeKb()); pw.print(","); 12120 pw.println(totalPss - cachedPss); 12121 } 12122 } 12123 if (!isCompact) { 12124 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12125 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12126 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12127 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12128 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12129 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12130 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12131 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12132 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12133 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12134 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12135 } 12136 if (!brief) { 12137 if (memInfo.getZramTotalSizeKb() != 0) { 12138 if (!isCompact) { 12139 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12140 pw.print(" kB physical used for "); 12141 pw.print(memInfo.getSwapTotalSizeKb() 12142 - memInfo.getSwapFreeSizeKb()); 12143 pw.print(" kB in swap ("); 12144 pw.print(memInfo.getSwapTotalSizeKb()); 12145 pw.println(" kB total swap)"); 12146 } else { 12147 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12148 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12149 pw.println(memInfo.getSwapFreeSizeKb()); 12150 } 12151 } 12152 final int[] SINGLE_LONG_FORMAT = new int[] { 12153 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12154 }; 12155 long[] longOut = new long[1]; 12156 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12157 SINGLE_LONG_FORMAT, null, longOut, null); 12158 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12159 longOut[0] = 0; 12160 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12161 SINGLE_LONG_FORMAT, null, longOut, null); 12162 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12163 longOut[0] = 0; 12164 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12165 SINGLE_LONG_FORMAT, null, longOut, null); 12166 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12167 longOut[0] = 0; 12168 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12169 SINGLE_LONG_FORMAT, null, longOut, null); 12170 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12171 if (!isCompact) { 12172 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12173 pw.print(" KSM: "); pw.print(sharing); 12174 pw.print(" kB saved from shared "); 12175 pw.print(shared); pw.println(" kB"); 12176 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12177 pw.print(voltile); pw.println(" kB volatile"); 12178 } 12179 pw.print(" Tuning: "); 12180 pw.print(ActivityManager.staticGetMemoryClass()); 12181 pw.print(" (large "); 12182 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12183 pw.print("), oom "); 12184 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12185 pw.print(" kB"); 12186 pw.print(", restore limit "); 12187 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12188 pw.print(" kB"); 12189 if (ActivityManager.isLowRamDeviceStatic()) { 12190 pw.print(" (low-ram)"); 12191 } 12192 if (ActivityManager.isHighEndGfx()) { 12193 pw.print(" (high-end-gfx)"); 12194 } 12195 pw.println(); 12196 } else { 12197 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12198 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12199 pw.println(voltile); 12200 pw.print("tuning,"); 12201 pw.print(ActivityManager.staticGetMemoryClass()); 12202 pw.print(','); 12203 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12204 pw.print(','); 12205 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12206 if (ActivityManager.isLowRamDeviceStatic()) { 12207 pw.print(",low-ram"); 12208 } 12209 if (ActivityManager.isHighEndGfx()) { 12210 pw.print(",high-end-gfx"); 12211 } 12212 pw.println(); 12213 } 12214 } 12215 } 12216 } 12217 12218 /** 12219 * Searches array of arguments for the specified string 12220 * @param args array of argument strings 12221 * @param value value to search for 12222 * @return true if the value is contained in the array 12223 */ 12224 private static boolean scanArgs(String[] args, String value) { 12225 if (args != null) { 12226 for (String arg : args) { 12227 if (value.equals(arg)) { 12228 return true; 12229 } 12230 } 12231 } 12232 return false; 12233 } 12234 12235 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12236 ContentProviderRecord cpr, boolean always) { 12237 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12238 12239 if (!inLaunching || always) { 12240 synchronized (cpr) { 12241 cpr.launchingApp = null; 12242 cpr.notifyAll(); 12243 } 12244 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12245 String names[] = cpr.info.authority.split(";"); 12246 for (int j = 0; j < names.length; j++) { 12247 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12248 } 12249 } 12250 12251 for (int i=0; i<cpr.connections.size(); i++) { 12252 ContentProviderConnection conn = cpr.connections.get(i); 12253 if (conn.waiting) { 12254 // If this connection is waiting for the provider, then we don't 12255 // need to mess with its process unless we are always removing 12256 // or for some reason the provider is not currently launching. 12257 if (inLaunching && !always) { 12258 continue; 12259 } 12260 } 12261 ProcessRecord capp = conn.client; 12262 conn.dead = true; 12263 if (conn.stableCount > 0) { 12264 if (!capp.persistent && capp.thread != null 12265 && capp.pid != 0 12266 && capp.pid != MY_PID) { 12267 killUnneededProcessLocked(capp, "depends on provider " 12268 + cpr.name.flattenToShortString() 12269 + " in dying proc " + (proc != null ? proc.processName : "??")); 12270 } 12271 } else if (capp.thread != null && conn.provider.provider != null) { 12272 try { 12273 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12274 } catch (RemoteException e) { 12275 } 12276 // In the protocol here, we don't expect the client to correctly 12277 // clean up this connection, we'll just remove it. 12278 cpr.connections.remove(i); 12279 conn.client.conProviders.remove(conn); 12280 } 12281 } 12282 12283 if (inLaunching && always) { 12284 mLaunchingProviders.remove(cpr); 12285 } 12286 return inLaunching; 12287 } 12288 12289 /** 12290 * Main code for cleaning up a process when it has gone away. This is 12291 * called both as a result of the process dying, or directly when stopping 12292 * a process when running in single process mode. 12293 */ 12294 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12295 boolean restarting, boolean allowRestart, int index) { 12296 if (index >= 0) { 12297 removeLruProcessLocked(app); 12298 ProcessList.remove(app.pid); 12299 } 12300 12301 mProcessesToGc.remove(app); 12302 mPendingPssProcesses.remove(app); 12303 12304 // Dismiss any open dialogs. 12305 if (app.crashDialog != null && !app.forceCrashReport) { 12306 app.crashDialog.dismiss(); 12307 app.crashDialog = null; 12308 } 12309 if (app.anrDialog != null) { 12310 app.anrDialog.dismiss(); 12311 app.anrDialog = null; 12312 } 12313 if (app.waitDialog != null) { 12314 app.waitDialog.dismiss(); 12315 app.waitDialog = null; 12316 } 12317 12318 app.crashing = false; 12319 app.notResponding = false; 12320 12321 app.resetPackageList(mProcessStats); 12322 app.unlinkDeathRecipient(); 12323 app.makeInactive(mProcessStats); 12324 app.forcingToForeground = null; 12325 app.foregroundServices = false; 12326 app.foregroundActivities = false; 12327 app.hasShownUi = false; 12328 app.hasAboveClient = false; 12329 app.hasClientActivities = false; 12330 12331 mServices.killServicesLocked(app, allowRestart); 12332 12333 boolean restart = false; 12334 12335 // Remove published content providers. 12336 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12337 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12338 final boolean always = app.bad || !allowRestart; 12339 if (removeDyingProviderLocked(app, cpr, always) || always) { 12340 // We left the provider in the launching list, need to 12341 // restart it. 12342 restart = true; 12343 } 12344 12345 cpr.provider = null; 12346 cpr.proc = null; 12347 } 12348 app.pubProviders.clear(); 12349 12350 // Take care of any launching providers waiting for this process. 12351 if (checkAppInLaunchingProvidersLocked(app, false)) { 12352 restart = true; 12353 } 12354 12355 // Unregister from connected content providers. 12356 if (!app.conProviders.isEmpty()) { 12357 for (int i=0; i<app.conProviders.size(); i++) { 12358 ContentProviderConnection conn = app.conProviders.get(i); 12359 conn.provider.connections.remove(conn); 12360 } 12361 app.conProviders.clear(); 12362 } 12363 12364 // At this point there may be remaining entries in mLaunchingProviders 12365 // where we were the only one waiting, so they are no longer of use. 12366 // Look for these and clean up if found. 12367 // XXX Commented out for now. Trying to figure out a way to reproduce 12368 // the actual situation to identify what is actually going on. 12369 if (false) { 12370 for (int i=0; i<mLaunchingProviders.size(); i++) { 12371 ContentProviderRecord cpr = (ContentProviderRecord) 12372 mLaunchingProviders.get(i); 12373 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12374 synchronized (cpr) { 12375 cpr.launchingApp = null; 12376 cpr.notifyAll(); 12377 } 12378 } 12379 } 12380 } 12381 12382 skipCurrentReceiverLocked(app); 12383 12384 // Unregister any receivers. 12385 for (int i=app.receivers.size()-1; i>=0; i--) { 12386 removeReceiverLocked(app.receivers.valueAt(i)); 12387 } 12388 app.receivers.clear(); 12389 12390 // If the app is undergoing backup, tell the backup manager about it 12391 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12392 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12393 + mBackupTarget.appInfo + " died during backup"); 12394 try { 12395 IBackupManager bm = IBackupManager.Stub.asInterface( 12396 ServiceManager.getService(Context.BACKUP_SERVICE)); 12397 bm.agentDisconnected(app.info.packageName); 12398 } catch (RemoteException e) { 12399 // can't happen; backup manager is local 12400 } 12401 } 12402 12403 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12404 ProcessChangeItem item = mPendingProcessChanges.get(i); 12405 if (item.pid == app.pid) { 12406 mPendingProcessChanges.remove(i); 12407 mAvailProcessChanges.add(item); 12408 } 12409 } 12410 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12411 12412 // If the caller is restarting this app, then leave it in its 12413 // current lists and let the caller take care of it. 12414 if (restarting) { 12415 return; 12416 } 12417 12418 if (!app.persistent || app.isolated) { 12419 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12420 "Removing non-persistent process during cleanup: " + app); 12421 mProcessNames.remove(app.processName, app.uid); 12422 mIsolatedProcesses.remove(app.uid); 12423 if (mHeavyWeightProcess == app) { 12424 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12425 mHeavyWeightProcess.userId, 0)); 12426 mHeavyWeightProcess = null; 12427 } 12428 } else if (!app.removed) { 12429 // This app is persistent, so we need to keep its record around. 12430 // If it is not already on the pending app list, add it there 12431 // and start a new process for it. 12432 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12433 mPersistentStartingProcesses.add(app); 12434 restart = true; 12435 } 12436 } 12437 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12438 "Clean-up removing on hold: " + app); 12439 mProcessesOnHold.remove(app); 12440 12441 if (app == mHomeProcess) { 12442 mHomeProcess = null; 12443 } 12444 if (app == mPreviousProcess) { 12445 mPreviousProcess = null; 12446 } 12447 12448 if (restart && !app.isolated) { 12449 // We have components that still need to be running in the 12450 // process, so re-launch it. 12451 mProcessNames.put(app.processName, app.uid, app); 12452 startProcessLocked(app, "restart", app.processName); 12453 } else if (app.pid > 0 && app.pid != MY_PID) { 12454 // Goodbye! 12455 synchronized (mPidsSelfLocked) { 12456 mPidsSelfLocked.remove(app.pid); 12457 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12458 } 12459 app.setPid(0); 12460 } 12461 } 12462 12463 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12464 // Look through the content providers we are waiting to have launched, 12465 // and if any run in this process then either schedule a restart of 12466 // the process or kill the client waiting for it if this process has 12467 // gone bad. 12468 int NL = mLaunchingProviders.size(); 12469 boolean restart = false; 12470 for (int i=0; i<NL; i++) { 12471 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12472 if (cpr.launchingApp == app) { 12473 if (!alwaysBad && !app.bad) { 12474 restart = true; 12475 } else { 12476 removeDyingProviderLocked(app, cpr, true); 12477 // cpr should have been removed from mLaunchingProviders 12478 NL = mLaunchingProviders.size(); 12479 i--; 12480 } 12481 } 12482 } 12483 return restart; 12484 } 12485 12486 // ========================================================= 12487 // SERVICES 12488 // ========================================================= 12489 12490 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12491 int flags) { 12492 enforceNotIsolatedCaller("getServices"); 12493 synchronized (this) { 12494 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12495 } 12496 } 12497 12498 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12499 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12500 synchronized (this) { 12501 return mServices.getRunningServiceControlPanelLocked(name); 12502 } 12503 } 12504 12505 public ComponentName startService(IApplicationThread caller, Intent service, 12506 String resolvedType, int userId) { 12507 enforceNotIsolatedCaller("startService"); 12508 // Refuse possible leaked file descriptors 12509 if (service != null && service.hasFileDescriptors() == true) { 12510 throw new IllegalArgumentException("File descriptors passed in Intent"); 12511 } 12512 12513 if (DEBUG_SERVICE) 12514 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12515 synchronized(this) { 12516 final int callingPid = Binder.getCallingPid(); 12517 final int callingUid = Binder.getCallingUid(); 12518 final long origId = Binder.clearCallingIdentity(); 12519 ComponentName res = mServices.startServiceLocked(caller, service, 12520 resolvedType, callingPid, callingUid, userId); 12521 Binder.restoreCallingIdentity(origId); 12522 return res; 12523 } 12524 } 12525 12526 ComponentName startServiceInPackage(int uid, 12527 Intent service, String resolvedType, int userId) { 12528 synchronized(this) { 12529 if (DEBUG_SERVICE) 12530 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12531 final long origId = Binder.clearCallingIdentity(); 12532 ComponentName res = mServices.startServiceLocked(null, service, 12533 resolvedType, -1, uid, userId); 12534 Binder.restoreCallingIdentity(origId); 12535 return res; 12536 } 12537 } 12538 12539 public int stopService(IApplicationThread caller, Intent service, 12540 String resolvedType, int userId) { 12541 enforceNotIsolatedCaller("stopService"); 12542 // Refuse possible leaked file descriptors 12543 if (service != null && service.hasFileDescriptors() == true) { 12544 throw new IllegalArgumentException("File descriptors passed in Intent"); 12545 } 12546 12547 synchronized(this) { 12548 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12549 } 12550 } 12551 12552 public IBinder peekService(Intent service, String resolvedType) { 12553 enforceNotIsolatedCaller("peekService"); 12554 // Refuse possible leaked file descriptors 12555 if (service != null && service.hasFileDescriptors() == true) { 12556 throw new IllegalArgumentException("File descriptors passed in Intent"); 12557 } 12558 synchronized(this) { 12559 return mServices.peekServiceLocked(service, resolvedType); 12560 } 12561 } 12562 12563 public boolean stopServiceToken(ComponentName className, IBinder token, 12564 int startId) { 12565 synchronized(this) { 12566 return mServices.stopServiceTokenLocked(className, token, startId); 12567 } 12568 } 12569 12570 public void setServiceForeground(ComponentName className, IBinder token, 12571 int id, Notification notification, boolean removeNotification) { 12572 synchronized(this) { 12573 mServices.setServiceForegroundLocked(className, token, id, notification, 12574 removeNotification); 12575 } 12576 } 12577 12578 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12579 boolean requireFull, String name, String callerPackage) { 12580 final int callingUserId = UserHandle.getUserId(callingUid); 12581 if (callingUserId != userId) { 12582 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12583 if ((requireFull || checkComponentPermission( 12584 android.Manifest.permission.INTERACT_ACROSS_USERS, 12585 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12586 && checkComponentPermission( 12587 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12588 callingPid, callingUid, -1, true) 12589 != PackageManager.PERMISSION_GRANTED) { 12590 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12591 // In this case, they would like to just execute as their 12592 // owner user instead of failing. 12593 userId = callingUserId; 12594 } else { 12595 StringBuilder builder = new StringBuilder(128); 12596 builder.append("Permission Denial: "); 12597 builder.append(name); 12598 if (callerPackage != null) { 12599 builder.append(" from "); 12600 builder.append(callerPackage); 12601 } 12602 builder.append(" asks to run as user "); 12603 builder.append(userId); 12604 builder.append(" but is calling from user "); 12605 builder.append(UserHandle.getUserId(callingUid)); 12606 builder.append("; this requires "); 12607 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12608 if (!requireFull) { 12609 builder.append(" or "); 12610 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12611 } 12612 String msg = builder.toString(); 12613 Slog.w(TAG, msg); 12614 throw new SecurityException(msg); 12615 } 12616 } 12617 } 12618 if (userId == UserHandle.USER_CURRENT 12619 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12620 // Note that we may be accessing this outside of a lock... 12621 // shouldn't be a big deal, if this is being called outside 12622 // of a locked context there is intrinsically a race with 12623 // the value the caller will receive and someone else changing it. 12624 userId = mCurrentUserId; 12625 } 12626 if (!allowAll && userId < 0) { 12627 throw new IllegalArgumentException( 12628 "Call does not support special user #" + userId); 12629 } 12630 } 12631 return userId; 12632 } 12633 12634 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12635 String className, int flags) { 12636 boolean result = false; 12637 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12638 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12639 if (ActivityManager.checkUidPermission( 12640 android.Manifest.permission.INTERACT_ACROSS_USERS, 12641 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12642 ComponentName comp = new ComponentName(aInfo.packageName, className); 12643 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12644 + " requests FLAG_SINGLE_USER, but app does not hold " 12645 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12646 Slog.w(TAG, msg); 12647 throw new SecurityException(msg); 12648 } 12649 result = true; 12650 } 12651 } else if (componentProcessName == aInfo.packageName) { 12652 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12653 } else if ("system".equals(componentProcessName)) { 12654 result = true; 12655 } 12656 if (DEBUG_MU) { 12657 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12658 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12659 } 12660 return result; 12661 } 12662 12663 public int bindService(IApplicationThread caller, IBinder token, 12664 Intent service, String resolvedType, 12665 IServiceConnection connection, int flags, int userId) { 12666 enforceNotIsolatedCaller("bindService"); 12667 // Refuse possible leaked file descriptors 12668 if (service != null && service.hasFileDescriptors() == true) { 12669 throw new IllegalArgumentException("File descriptors passed in Intent"); 12670 } 12671 12672 synchronized(this) { 12673 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12674 connection, flags, userId); 12675 } 12676 } 12677 12678 public boolean unbindService(IServiceConnection connection) { 12679 synchronized (this) { 12680 return mServices.unbindServiceLocked(connection); 12681 } 12682 } 12683 12684 public void publishService(IBinder token, Intent intent, IBinder service) { 12685 // Refuse possible leaked file descriptors 12686 if (intent != null && intent.hasFileDescriptors() == true) { 12687 throw new IllegalArgumentException("File descriptors passed in Intent"); 12688 } 12689 12690 synchronized(this) { 12691 if (!(token instanceof ServiceRecord)) { 12692 throw new IllegalArgumentException("Invalid service token"); 12693 } 12694 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12695 } 12696 } 12697 12698 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12699 // Refuse possible leaked file descriptors 12700 if (intent != null && intent.hasFileDescriptors() == true) { 12701 throw new IllegalArgumentException("File descriptors passed in Intent"); 12702 } 12703 12704 synchronized(this) { 12705 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12706 } 12707 } 12708 12709 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12710 synchronized(this) { 12711 if (!(token instanceof ServiceRecord)) { 12712 throw new IllegalArgumentException("Invalid service token"); 12713 } 12714 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12715 } 12716 } 12717 12718 // ========================================================= 12719 // BACKUP AND RESTORE 12720 // ========================================================= 12721 12722 // Cause the target app to be launched if necessary and its backup agent 12723 // instantiated. The backup agent will invoke backupAgentCreated() on the 12724 // activity manager to announce its creation. 12725 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12726 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12727 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12728 12729 synchronized(this) { 12730 // !!! TODO: currently no check here that we're already bound 12731 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12732 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12733 synchronized (stats) { 12734 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12735 } 12736 12737 // Backup agent is now in use, its package can't be stopped. 12738 try { 12739 AppGlobals.getPackageManager().setPackageStoppedState( 12740 app.packageName, false, UserHandle.getUserId(app.uid)); 12741 } catch (RemoteException e) { 12742 } catch (IllegalArgumentException e) { 12743 Slog.w(TAG, "Failed trying to unstop package " 12744 + app.packageName + ": " + e); 12745 } 12746 12747 BackupRecord r = new BackupRecord(ss, app, backupMode); 12748 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12749 ? new ComponentName(app.packageName, app.backupAgentName) 12750 : new ComponentName("android", "FullBackupAgent"); 12751 // startProcessLocked() returns existing proc's record if it's already running 12752 ProcessRecord proc = startProcessLocked(app.processName, app, 12753 false, 0, "backup", hostingName, false, false, false); 12754 if (proc == null) { 12755 Slog.e(TAG, "Unable to start backup agent process " + r); 12756 return false; 12757 } 12758 12759 r.app = proc; 12760 mBackupTarget = r; 12761 mBackupAppName = app.packageName; 12762 12763 // Try not to kill the process during backup 12764 updateOomAdjLocked(proc); 12765 12766 // If the process is already attached, schedule the creation of the backup agent now. 12767 // If it is not yet live, this will be done when it attaches to the framework. 12768 if (proc.thread != null) { 12769 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12770 try { 12771 proc.thread.scheduleCreateBackupAgent(app, 12772 compatibilityInfoForPackageLocked(app), backupMode); 12773 } catch (RemoteException e) { 12774 // Will time out on the backup manager side 12775 } 12776 } else { 12777 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12778 } 12779 // Invariants: at this point, the target app process exists and the application 12780 // is either already running or in the process of coming up. mBackupTarget and 12781 // mBackupAppName describe the app, so that when it binds back to the AM we 12782 // know that it's scheduled for a backup-agent operation. 12783 } 12784 12785 return true; 12786 } 12787 12788 @Override 12789 public void clearPendingBackup() { 12790 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 12791 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 12792 12793 synchronized (this) { 12794 mBackupTarget = null; 12795 mBackupAppName = null; 12796 } 12797 } 12798 12799 // A backup agent has just come up 12800 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12801 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12802 + " = " + agent); 12803 12804 synchronized(this) { 12805 if (!agentPackageName.equals(mBackupAppName)) { 12806 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12807 return; 12808 } 12809 } 12810 12811 long oldIdent = Binder.clearCallingIdentity(); 12812 try { 12813 IBackupManager bm = IBackupManager.Stub.asInterface( 12814 ServiceManager.getService(Context.BACKUP_SERVICE)); 12815 bm.agentConnected(agentPackageName, agent); 12816 } catch (RemoteException e) { 12817 // can't happen; the backup manager service is local 12818 } catch (Exception e) { 12819 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12820 e.printStackTrace(); 12821 } finally { 12822 Binder.restoreCallingIdentity(oldIdent); 12823 } 12824 } 12825 12826 // done with this agent 12827 public void unbindBackupAgent(ApplicationInfo appInfo) { 12828 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12829 if (appInfo == null) { 12830 Slog.w(TAG, "unbind backup agent for null app"); 12831 return; 12832 } 12833 12834 synchronized(this) { 12835 try { 12836 if (mBackupAppName == null) { 12837 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12838 return; 12839 } 12840 12841 if (!mBackupAppName.equals(appInfo.packageName)) { 12842 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12843 return; 12844 } 12845 12846 // Not backing this app up any more; reset its OOM adjustment 12847 final ProcessRecord proc = mBackupTarget.app; 12848 updateOomAdjLocked(proc); 12849 12850 // If the app crashed during backup, 'thread' will be null here 12851 if (proc.thread != null) { 12852 try { 12853 proc.thread.scheduleDestroyBackupAgent(appInfo, 12854 compatibilityInfoForPackageLocked(appInfo)); 12855 } catch (Exception e) { 12856 Slog.e(TAG, "Exception when unbinding backup agent:"); 12857 e.printStackTrace(); 12858 } 12859 } 12860 } finally { 12861 mBackupTarget = null; 12862 mBackupAppName = null; 12863 } 12864 } 12865 } 12866 // ========================================================= 12867 // BROADCASTS 12868 // ========================================================= 12869 12870 private final List getStickiesLocked(String action, IntentFilter filter, 12871 List cur, int userId) { 12872 final ContentResolver resolver = mContext.getContentResolver(); 12873 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12874 if (stickies == null) { 12875 return cur; 12876 } 12877 final ArrayList<Intent> list = stickies.get(action); 12878 if (list == null) { 12879 return cur; 12880 } 12881 int N = list.size(); 12882 for (int i=0; i<N; i++) { 12883 Intent intent = list.get(i); 12884 if (filter.match(resolver, intent, true, TAG) >= 0) { 12885 if (cur == null) { 12886 cur = new ArrayList<Intent>(); 12887 } 12888 cur.add(intent); 12889 } 12890 } 12891 return cur; 12892 } 12893 12894 boolean isPendingBroadcastProcessLocked(int pid) { 12895 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12896 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12897 } 12898 12899 void skipPendingBroadcastLocked(int pid) { 12900 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 12901 for (BroadcastQueue queue : mBroadcastQueues) { 12902 queue.skipPendingBroadcastLocked(pid); 12903 } 12904 } 12905 12906 // The app just attached; send any pending broadcasts that it should receive 12907 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 12908 boolean didSomething = false; 12909 for (BroadcastQueue queue : mBroadcastQueues) { 12910 didSomething |= queue.sendPendingBroadcastsLocked(app); 12911 } 12912 return didSomething; 12913 } 12914 12915 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 12916 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 12917 enforceNotIsolatedCaller("registerReceiver"); 12918 int callingUid; 12919 int callingPid; 12920 synchronized(this) { 12921 ProcessRecord callerApp = null; 12922 if (caller != null) { 12923 callerApp = getRecordForAppLocked(caller); 12924 if (callerApp == null) { 12925 throw new SecurityException( 12926 "Unable to find app for caller " + caller 12927 + " (pid=" + Binder.getCallingPid() 12928 + ") when registering receiver " + receiver); 12929 } 12930 if (callerApp.info.uid != Process.SYSTEM_UID && 12931 !callerApp.pkgList.containsKey(callerPackage) && 12932 !"android".equals(callerPackage)) { 12933 throw new SecurityException("Given caller package " + callerPackage 12934 + " is not running in process " + callerApp); 12935 } 12936 callingUid = callerApp.info.uid; 12937 callingPid = callerApp.pid; 12938 } else { 12939 callerPackage = null; 12940 callingUid = Binder.getCallingUid(); 12941 callingPid = Binder.getCallingPid(); 12942 } 12943 12944 userId = this.handleIncomingUser(callingPid, callingUid, userId, 12945 true, true, "registerReceiver", callerPackage); 12946 12947 List allSticky = null; 12948 12949 // Look for any matching sticky broadcasts... 12950 Iterator actions = filter.actionsIterator(); 12951 if (actions != null) { 12952 while (actions.hasNext()) { 12953 String action = (String)actions.next(); 12954 allSticky = getStickiesLocked(action, filter, allSticky, 12955 UserHandle.USER_ALL); 12956 allSticky = getStickiesLocked(action, filter, allSticky, 12957 UserHandle.getUserId(callingUid)); 12958 } 12959 } else { 12960 allSticky = getStickiesLocked(null, filter, allSticky, 12961 UserHandle.USER_ALL); 12962 allSticky = getStickiesLocked(null, filter, allSticky, 12963 UserHandle.getUserId(callingUid)); 12964 } 12965 12966 // The first sticky in the list is returned directly back to 12967 // the client. 12968 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 12969 12970 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 12971 + ": " + sticky); 12972 12973 if (receiver == null) { 12974 return sticky; 12975 } 12976 12977 ReceiverList rl 12978 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12979 if (rl == null) { 12980 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 12981 userId, receiver); 12982 if (rl.app != null) { 12983 rl.app.receivers.add(rl); 12984 } else { 12985 try { 12986 receiver.asBinder().linkToDeath(rl, 0); 12987 } catch (RemoteException e) { 12988 return sticky; 12989 } 12990 rl.linkedToDeath = true; 12991 } 12992 mRegisteredReceivers.put(receiver.asBinder(), rl); 12993 } else if (rl.uid != callingUid) { 12994 throw new IllegalArgumentException( 12995 "Receiver requested to register for uid " + callingUid 12996 + " was previously registered for uid " + rl.uid); 12997 } else if (rl.pid != callingPid) { 12998 throw new IllegalArgumentException( 12999 "Receiver requested to register for pid " + callingPid 13000 + " was previously registered for pid " + rl.pid); 13001 } else if (rl.userId != userId) { 13002 throw new IllegalArgumentException( 13003 "Receiver requested to register for user " + userId 13004 + " was previously registered for user " + rl.userId); 13005 } 13006 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13007 permission, callingUid, userId); 13008 rl.add(bf); 13009 if (!bf.debugCheck()) { 13010 Slog.w(TAG, "==> For Dynamic broadast"); 13011 } 13012 mReceiverResolver.addFilter(bf); 13013 13014 // Enqueue broadcasts for all existing stickies that match 13015 // this filter. 13016 if (allSticky != null) { 13017 ArrayList receivers = new ArrayList(); 13018 receivers.add(bf); 13019 13020 int N = allSticky.size(); 13021 for (int i=0; i<N; i++) { 13022 Intent intent = (Intent)allSticky.get(i); 13023 BroadcastQueue queue = broadcastQueueForIntent(intent); 13024 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13025 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13026 null, null, false, true, true, -1); 13027 queue.enqueueParallelBroadcastLocked(r); 13028 queue.scheduleBroadcastsLocked(); 13029 } 13030 } 13031 13032 return sticky; 13033 } 13034 } 13035 13036 public void unregisterReceiver(IIntentReceiver receiver) { 13037 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13038 13039 final long origId = Binder.clearCallingIdentity(); 13040 try { 13041 boolean doTrim = false; 13042 13043 synchronized(this) { 13044 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13045 if (rl != null) { 13046 if (rl.curBroadcast != null) { 13047 BroadcastRecord r = rl.curBroadcast; 13048 final boolean doNext = finishReceiverLocked( 13049 receiver.asBinder(), r.resultCode, r.resultData, 13050 r.resultExtras, r.resultAbort); 13051 if (doNext) { 13052 doTrim = true; 13053 r.queue.processNextBroadcast(false); 13054 } 13055 } 13056 13057 if (rl.app != null) { 13058 rl.app.receivers.remove(rl); 13059 } 13060 removeReceiverLocked(rl); 13061 if (rl.linkedToDeath) { 13062 rl.linkedToDeath = false; 13063 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13064 } 13065 } 13066 } 13067 13068 // If we actually concluded any broadcasts, we might now be able 13069 // to trim the recipients' apps from our working set 13070 if (doTrim) { 13071 trimApplications(); 13072 return; 13073 } 13074 13075 } finally { 13076 Binder.restoreCallingIdentity(origId); 13077 } 13078 } 13079 13080 void removeReceiverLocked(ReceiverList rl) { 13081 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13082 int N = rl.size(); 13083 for (int i=0; i<N; i++) { 13084 mReceiverResolver.removeFilter(rl.get(i)); 13085 } 13086 } 13087 13088 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13089 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13090 ProcessRecord r = mLruProcesses.get(i); 13091 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13092 try { 13093 r.thread.dispatchPackageBroadcast(cmd, packages); 13094 } catch (RemoteException ex) { 13095 } 13096 } 13097 } 13098 } 13099 13100 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13101 int[] users) { 13102 List<ResolveInfo> receivers = null; 13103 try { 13104 HashSet<ComponentName> singleUserReceivers = null; 13105 boolean scannedFirstReceivers = false; 13106 for (int user : users) { 13107 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13108 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13109 if (user != 0 && newReceivers != null) { 13110 // If this is not the primary user, we need to check for 13111 // any receivers that should be filtered out. 13112 for (int i=0; i<newReceivers.size(); i++) { 13113 ResolveInfo ri = newReceivers.get(i); 13114 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13115 newReceivers.remove(i); 13116 i--; 13117 } 13118 } 13119 } 13120 if (newReceivers != null && newReceivers.size() == 0) { 13121 newReceivers = null; 13122 } 13123 if (receivers == null) { 13124 receivers = newReceivers; 13125 } else if (newReceivers != null) { 13126 // We need to concatenate the additional receivers 13127 // found with what we have do far. This would be easy, 13128 // but we also need to de-dup any receivers that are 13129 // singleUser. 13130 if (!scannedFirstReceivers) { 13131 // Collect any single user receivers we had already retrieved. 13132 scannedFirstReceivers = true; 13133 for (int i=0; i<receivers.size(); i++) { 13134 ResolveInfo ri = receivers.get(i); 13135 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13136 ComponentName cn = new ComponentName( 13137 ri.activityInfo.packageName, ri.activityInfo.name); 13138 if (singleUserReceivers == null) { 13139 singleUserReceivers = new HashSet<ComponentName>(); 13140 } 13141 singleUserReceivers.add(cn); 13142 } 13143 } 13144 } 13145 // Add the new results to the existing results, tracking 13146 // and de-dupping single user receivers. 13147 for (int i=0; i<newReceivers.size(); i++) { 13148 ResolveInfo ri = newReceivers.get(i); 13149 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13150 ComponentName cn = new ComponentName( 13151 ri.activityInfo.packageName, ri.activityInfo.name); 13152 if (singleUserReceivers == null) { 13153 singleUserReceivers = new HashSet<ComponentName>(); 13154 } 13155 if (!singleUserReceivers.contains(cn)) { 13156 singleUserReceivers.add(cn); 13157 receivers.add(ri); 13158 } 13159 } else { 13160 receivers.add(ri); 13161 } 13162 } 13163 } 13164 } 13165 } catch (RemoteException ex) { 13166 // pm is in same process, this will never happen. 13167 } 13168 return receivers; 13169 } 13170 13171 private final int broadcastIntentLocked(ProcessRecord callerApp, 13172 String callerPackage, Intent intent, String resolvedType, 13173 IIntentReceiver resultTo, int resultCode, String resultData, 13174 Bundle map, String requiredPermission, int appOp, 13175 boolean ordered, boolean sticky, int callingPid, int callingUid, 13176 int userId) { 13177 intent = new Intent(intent); 13178 13179 // By default broadcasts do not go to stopped apps. 13180 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13181 13182 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13183 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13184 + " ordered=" + ordered + " userid=" + userId); 13185 if ((resultTo != null) && !ordered) { 13186 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13187 } 13188 13189 userId = handleIncomingUser(callingPid, callingUid, userId, 13190 true, false, "broadcast", callerPackage); 13191 13192 // Make sure that the user who is receiving this broadcast is started. 13193 // If not, we will just skip it. 13194 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13195 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13196 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13197 Slog.w(TAG, "Skipping broadcast of " + intent 13198 + ": user " + userId + " is stopped"); 13199 return ActivityManager.BROADCAST_SUCCESS; 13200 } 13201 } 13202 13203 /* 13204 * Prevent non-system code (defined here to be non-persistent 13205 * processes) from sending protected broadcasts. 13206 */ 13207 int callingAppId = UserHandle.getAppId(callingUid); 13208 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13209 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13210 callingUid == 0) { 13211 // Always okay. 13212 } else if (callerApp == null || !callerApp.persistent) { 13213 try { 13214 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13215 intent.getAction())) { 13216 String msg = "Permission Denial: not allowed to send broadcast " 13217 + intent.getAction() + " from pid=" 13218 + callingPid + ", uid=" + callingUid; 13219 Slog.w(TAG, msg); 13220 throw new SecurityException(msg); 13221 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13222 // Special case for compatibility: we don't want apps to send this, 13223 // but historically it has not been protected and apps may be using it 13224 // to poke their own app widget. So, instead of making it protected, 13225 // just limit it to the caller. 13226 if (callerApp == null) { 13227 String msg = "Permission Denial: not allowed to send broadcast " 13228 + intent.getAction() + " from unknown caller."; 13229 Slog.w(TAG, msg); 13230 throw new SecurityException(msg); 13231 } else if (intent.getComponent() != null) { 13232 // They are good enough to send to an explicit component... verify 13233 // it is being sent to the calling app. 13234 if (!intent.getComponent().getPackageName().equals( 13235 callerApp.info.packageName)) { 13236 String msg = "Permission Denial: not allowed to send broadcast " 13237 + intent.getAction() + " to " 13238 + intent.getComponent().getPackageName() + " from " 13239 + callerApp.info.packageName; 13240 Slog.w(TAG, msg); 13241 throw new SecurityException(msg); 13242 } 13243 } else { 13244 // Limit broadcast to their own package. 13245 intent.setPackage(callerApp.info.packageName); 13246 } 13247 } 13248 } catch (RemoteException e) { 13249 Slog.w(TAG, "Remote exception", e); 13250 return ActivityManager.BROADCAST_SUCCESS; 13251 } 13252 } 13253 13254 // Handle special intents: if this broadcast is from the package 13255 // manager about a package being removed, we need to remove all of 13256 // its activities from the history stack. 13257 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13258 intent.getAction()); 13259 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13260 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13261 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13262 || uidRemoved) { 13263 if (checkComponentPermission( 13264 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13265 callingPid, callingUid, -1, true) 13266 == PackageManager.PERMISSION_GRANTED) { 13267 if (uidRemoved) { 13268 final Bundle intentExtras = intent.getExtras(); 13269 final int uid = intentExtras != null 13270 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13271 if (uid >= 0) { 13272 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13273 synchronized (bs) { 13274 bs.removeUidStatsLocked(uid); 13275 } 13276 mAppOpsService.uidRemoved(uid); 13277 } 13278 } else { 13279 // If resources are unavailable just force stop all 13280 // those packages and flush the attribute cache as well. 13281 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13282 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13283 if (list != null && (list.length > 0)) { 13284 for (String pkg : list) { 13285 forceStopPackageLocked(pkg, -1, false, true, true, false, userId, 13286 "storage unmount"); 13287 } 13288 sendPackageBroadcastLocked( 13289 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13290 } 13291 } else { 13292 Uri data = intent.getData(); 13293 String ssp; 13294 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13295 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13296 intent.getAction()); 13297 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13298 forceStopPackageLocked(ssp, UserHandle.getAppId( 13299 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13300 false, userId, removed ? "pkg removed" : "pkg changed"); 13301 } 13302 if (removed) { 13303 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13304 new String[] {ssp}, userId); 13305 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13306 mAppOpsService.packageRemoved( 13307 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13308 13309 // Remove all permissions granted from/to this package 13310 removeUriPermissionsForPackageLocked(ssp, userId, true); 13311 } 13312 } 13313 } 13314 } 13315 } 13316 } else { 13317 String msg = "Permission Denial: " + intent.getAction() 13318 + " broadcast from " + callerPackage + " (pid=" + callingPid 13319 + ", uid=" + callingUid + ")" 13320 + " requires " 13321 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13322 Slog.w(TAG, msg); 13323 throw new SecurityException(msg); 13324 } 13325 13326 // Special case for adding a package: by default turn on compatibility 13327 // mode. 13328 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13329 Uri data = intent.getData(); 13330 String ssp; 13331 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13332 mCompatModePackages.handlePackageAddedLocked(ssp, 13333 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13334 } 13335 } 13336 13337 /* 13338 * If this is the time zone changed action, queue up a message that will reset the timezone 13339 * of all currently running processes. This message will get queued up before the broadcast 13340 * happens. 13341 */ 13342 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13343 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13344 } 13345 13346 /* 13347 * If the user set the time, let all running processes know. 13348 */ 13349 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13350 final int is24Hour = intent.getBooleanExtra( 13351 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13352 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13353 } 13354 13355 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13356 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13357 } 13358 13359 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13360 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13361 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13362 } 13363 13364 // Add to the sticky list if requested. 13365 if (sticky) { 13366 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13367 callingPid, callingUid) 13368 != PackageManager.PERMISSION_GRANTED) { 13369 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13370 + callingPid + ", uid=" + callingUid 13371 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13372 Slog.w(TAG, msg); 13373 throw new SecurityException(msg); 13374 } 13375 if (requiredPermission != null) { 13376 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13377 + " and enforce permission " + requiredPermission); 13378 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13379 } 13380 if (intent.getComponent() != null) { 13381 throw new SecurityException( 13382 "Sticky broadcasts can't target a specific component"); 13383 } 13384 // We use userId directly here, since the "all" target is maintained 13385 // as a separate set of sticky broadcasts. 13386 if (userId != UserHandle.USER_ALL) { 13387 // But first, if this is not a broadcast to all users, then 13388 // make sure it doesn't conflict with an existing broadcast to 13389 // all users. 13390 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13391 UserHandle.USER_ALL); 13392 if (stickies != null) { 13393 ArrayList<Intent> list = stickies.get(intent.getAction()); 13394 if (list != null) { 13395 int N = list.size(); 13396 int i; 13397 for (i=0; i<N; i++) { 13398 if (intent.filterEquals(list.get(i))) { 13399 throw new IllegalArgumentException( 13400 "Sticky broadcast " + intent + " for user " 13401 + userId + " conflicts with existing global broadcast"); 13402 } 13403 } 13404 } 13405 } 13406 } 13407 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13408 if (stickies == null) { 13409 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13410 mStickyBroadcasts.put(userId, stickies); 13411 } 13412 ArrayList<Intent> list = stickies.get(intent.getAction()); 13413 if (list == null) { 13414 list = new ArrayList<Intent>(); 13415 stickies.put(intent.getAction(), list); 13416 } 13417 int N = list.size(); 13418 int i; 13419 for (i=0; i<N; i++) { 13420 if (intent.filterEquals(list.get(i))) { 13421 // This sticky already exists, replace it. 13422 list.set(i, new Intent(intent)); 13423 break; 13424 } 13425 } 13426 if (i >= N) { 13427 list.add(new Intent(intent)); 13428 } 13429 } 13430 13431 int[] users; 13432 if (userId == UserHandle.USER_ALL) { 13433 // Caller wants broadcast to go to all started users. 13434 users = mStartedUserArray; 13435 } else { 13436 // Caller wants broadcast to go to one specific user. 13437 users = new int[] {userId}; 13438 } 13439 13440 // Figure out who all will receive this broadcast. 13441 List receivers = null; 13442 List<BroadcastFilter> registeredReceivers = null; 13443 // Need to resolve the intent to interested receivers... 13444 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13445 == 0) { 13446 receivers = collectReceiverComponents(intent, resolvedType, users); 13447 } 13448 if (intent.getComponent() == null) { 13449 registeredReceivers = mReceiverResolver.queryIntent(intent, 13450 resolvedType, false, userId); 13451 } 13452 13453 final boolean replacePending = 13454 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13455 13456 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13457 + " replacePending=" + replacePending); 13458 13459 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13460 if (!ordered && NR > 0) { 13461 // If we are not serializing this broadcast, then send the 13462 // registered receivers separately so they don't wait for the 13463 // components to be launched. 13464 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13465 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13466 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13467 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13468 ordered, sticky, false, userId); 13469 if (DEBUG_BROADCAST) Slog.v( 13470 TAG, "Enqueueing parallel broadcast " + r); 13471 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13472 if (!replaced) { 13473 queue.enqueueParallelBroadcastLocked(r); 13474 queue.scheduleBroadcastsLocked(); 13475 } 13476 registeredReceivers = null; 13477 NR = 0; 13478 } 13479 13480 // Merge into one list. 13481 int ir = 0; 13482 if (receivers != null) { 13483 // A special case for PACKAGE_ADDED: do not allow the package 13484 // being added to see this broadcast. This prevents them from 13485 // using this as a back door to get run as soon as they are 13486 // installed. Maybe in the future we want to have a special install 13487 // broadcast or such for apps, but we'd like to deliberately make 13488 // this decision. 13489 String skipPackages[] = null; 13490 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13491 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13492 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13493 Uri data = intent.getData(); 13494 if (data != null) { 13495 String pkgName = data.getSchemeSpecificPart(); 13496 if (pkgName != null) { 13497 skipPackages = new String[] { pkgName }; 13498 } 13499 } 13500 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13501 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13502 } 13503 if (skipPackages != null && (skipPackages.length > 0)) { 13504 for (String skipPackage : skipPackages) { 13505 if (skipPackage != null) { 13506 int NT = receivers.size(); 13507 for (int it=0; it<NT; it++) { 13508 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13509 if (curt.activityInfo.packageName.equals(skipPackage)) { 13510 receivers.remove(it); 13511 it--; 13512 NT--; 13513 } 13514 } 13515 } 13516 } 13517 } 13518 13519 int NT = receivers != null ? receivers.size() : 0; 13520 int it = 0; 13521 ResolveInfo curt = null; 13522 BroadcastFilter curr = null; 13523 while (it < NT && ir < NR) { 13524 if (curt == null) { 13525 curt = (ResolveInfo)receivers.get(it); 13526 } 13527 if (curr == null) { 13528 curr = registeredReceivers.get(ir); 13529 } 13530 if (curr.getPriority() >= curt.priority) { 13531 // Insert this broadcast record into the final list. 13532 receivers.add(it, curr); 13533 ir++; 13534 curr = null; 13535 it++; 13536 NT++; 13537 } else { 13538 // Skip to the next ResolveInfo in the final list. 13539 it++; 13540 curt = null; 13541 } 13542 } 13543 } 13544 while (ir < NR) { 13545 if (receivers == null) { 13546 receivers = new ArrayList(); 13547 } 13548 receivers.add(registeredReceivers.get(ir)); 13549 ir++; 13550 } 13551 13552 if ((receivers != null && receivers.size() > 0) 13553 || resultTo != null) { 13554 BroadcastQueue queue = broadcastQueueForIntent(intent); 13555 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13556 callerPackage, callingPid, callingUid, resolvedType, 13557 requiredPermission, appOp, receivers, resultTo, resultCode, 13558 resultData, map, ordered, sticky, false, userId); 13559 if (DEBUG_BROADCAST) Slog.v( 13560 TAG, "Enqueueing ordered broadcast " + r 13561 + ": prev had " + queue.mOrderedBroadcasts.size()); 13562 if (DEBUG_BROADCAST) { 13563 int seq = r.intent.getIntExtra("seq", -1); 13564 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13565 } 13566 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13567 if (!replaced) { 13568 queue.enqueueOrderedBroadcastLocked(r); 13569 queue.scheduleBroadcastsLocked(); 13570 } 13571 } 13572 13573 return ActivityManager.BROADCAST_SUCCESS; 13574 } 13575 13576 final Intent verifyBroadcastLocked(Intent intent) { 13577 // Refuse possible leaked file descriptors 13578 if (intent != null && intent.hasFileDescriptors() == true) { 13579 throw new IllegalArgumentException("File descriptors passed in Intent"); 13580 } 13581 13582 int flags = intent.getFlags(); 13583 13584 if (!mProcessesReady) { 13585 // if the caller really truly claims to know what they're doing, go 13586 // ahead and allow the broadcast without launching any receivers 13587 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13588 intent = new Intent(intent); 13589 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13590 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13591 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13592 + " before boot completion"); 13593 throw new IllegalStateException("Cannot broadcast before boot completed"); 13594 } 13595 } 13596 13597 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13598 throw new IllegalArgumentException( 13599 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13600 } 13601 13602 return intent; 13603 } 13604 13605 public final int broadcastIntent(IApplicationThread caller, 13606 Intent intent, String resolvedType, IIntentReceiver resultTo, 13607 int resultCode, String resultData, Bundle map, 13608 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13609 enforceNotIsolatedCaller("broadcastIntent"); 13610 synchronized(this) { 13611 intent = verifyBroadcastLocked(intent); 13612 13613 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13614 final int callingPid = Binder.getCallingPid(); 13615 final int callingUid = Binder.getCallingUid(); 13616 final long origId = Binder.clearCallingIdentity(); 13617 int res = broadcastIntentLocked(callerApp, 13618 callerApp != null ? callerApp.info.packageName : null, 13619 intent, resolvedType, resultTo, 13620 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13621 callingPid, callingUid, userId); 13622 Binder.restoreCallingIdentity(origId); 13623 return res; 13624 } 13625 } 13626 13627 int broadcastIntentInPackage(String packageName, int uid, 13628 Intent intent, String resolvedType, IIntentReceiver resultTo, 13629 int resultCode, String resultData, Bundle map, 13630 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13631 synchronized(this) { 13632 intent = verifyBroadcastLocked(intent); 13633 13634 final long origId = Binder.clearCallingIdentity(); 13635 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13636 resultTo, resultCode, resultData, map, requiredPermission, 13637 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13638 Binder.restoreCallingIdentity(origId); 13639 return res; 13640 } 13641 } 13642 13643 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13644 // Refuse possible leaked file descriptors 13645 if (intent != null && intent.hasFileDescriptors() == true) { 13646 throw new IllegalArgumentException("File descriptors passed in Intent"); 13647 } 13648 13649 userId = handleIncomingUser(Binder.getCallingPid(), 13650 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13651 13652 synchronized(this) { 13653 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13654 != PackageManager.PERMISSION_GRANTED) { 13655 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13656 + Binder.getCallingPid() 13657 + ", uid=" + Binder.getCallingUid() 13658 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13659 Slog.w(TAG, msg); 13660 throw new SecurityException(msg); 13661 } 13662 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13663 if (stickies != null) { 13664 ArrayList<Intent> list = stickies.get(intent.getAction()); 13665 if (list != null) { 13666 int N = list.size(); 13667 int i; 13668 for (i=0; i<N; i++) { 13669 if (intent.filterEquals(list.get(i))) { 13670 list.remove(i); 13671 break; 13672 } 13673 } 13674 if (list.size() <= 0) { 13675 stickies.remove(intent.getAction()); 13676 } 13677 } 13678 if (stickies.size() <= 0) { 13679 mStickyBroadcasts.remove(userId); 13680 } 13681 } 13682 } 13683 } 13684 13685 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13686 String resultData, Bundle resultExtras, boolean resultAbort) { 13687 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13688 if (r == null) { 13689 Slog.w(TAG, "finishReceiver called but not found on queue"); 13690 return false; 13691 } 13692 13693 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13694 } 13695 13696 void backgroundServicesFinishedLocked(int userId) { 13697 for (BroadcastQueue queue : mBroadcastQueues) { 13698 queue.backgroundServicesFinishedLocked(userId); 13699 } 13700 } 13701 13702 public void finishReceiver(IBinder who, int resultCode, String resultData, 13703 Bundle resultExtras, boolean resultAbort) { 13704 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13705 13706 // Refuse possible leaked file descriptors 13707 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13708 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13709 } 13710 13711 final long origId = Binder.clearCallingIdentity(); 13712 try { 13713 boolean doNext = false; 13714 BroadcastRecord r; 13715 13716 synchronized(this) { 13717 r = broadcastRecordForReceiverLocked(who); 13718 if (r != null) { 13719 doNext = r.queue.finishReceiverLocked(r, resultCode, 13720 resultData, resultExtras, resultAbort, true); 13721 } 13722 } 13723 13724 if (doNext) { 13725 r.queue.processNextBroadcast(false); 13726 } 13727 trimApplications(); 13728 } finally { 13729 Binder.restoreCallingIdentity(origId); 13730 } 13731 } 13732 13733 // ========================================================= 13734 // INSTRUMENTATION 13735 // ========================================================= 13736 13737 public boolean startInstrumentation(ComponentName className, 13738 String profileFile, int flags, Bundle arguments, 13739 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13740 int userId) { 13741 enforceNotIsolatedCaller("startInstrumentation"); 13742 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13743 userId, false, true, "startInstrumentation", null); 13744 // Refuse possible leaked file descriptors 13745 if (arguments != null && arguments.hasFileDescriptors()) { 13746 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13747 } 13748 13749 synchronized(this) { 13750 InstrumentationInfo ii = null; 13751 ApplicationInfo ai = null; 13752 try { 13753 ii = mContext.getPackageManager().getInstrumentationInfo( 13754 className, STOCK_PM_FLAGS); 13755 ai = AppGlobals.getPackageManager().getApplicationInfo( 13756 ii.targetPackage, STOCK_PM_FLAGS, userId); 13757 } catch (PackageManager.NameNotFoundException e) { 13758 } catch (RemoteException e) { 13759 } 13760 if (ii == null) { 13761 reportStartInstrumentationFailure(watcher, className, 13762 "Unable to find instrumentation info for: " + className); 13763 return false; 13764 } 13765 if (ai == null) { 13766 reportStartInstrumentationFailure(watcher, className, 13767 "Unable to find instrumentation target package: " + ii.targetPackage); 13768 return false; 13769 } 13770 13771 int match = mContext.getPackageManager().checkSignatures( 13772 ii.targetPackage, ii.packageName); 13773 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13774 String msg = "Permission Denial: starting instrumentation " 13775 + className + " from pid=" 13776 + Binder.getCallingPid() 13777 + ", uid=" + Binder.getCallingPid() 13778 + " not allowed because package " + ii.packageName 13779 + " does not have a signature matching the target " 13780 + ii.targetPackage; 13781 reportStartInstrumentationFailure(watcher, className, msg); 13782 throw new SecurityException(msg); 13783 } 13784 13785 final long origId = Binder.clearCallingIdentity(); 13786 // Instrumentation can kill and relaunch even persistent processes 13787 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId, 13788 "start instr"); 13789 ProcessRecord app = addAppLocked(ai, false); 13790 app.instrumentationClass = className; 13791 app.instrumentationInfo = ai; 13792 app.instrumentationProfileFile = profileFile; 13793 app.instrumentationArguments = arguments; 13794 app.instrumentationWatcher = watcher; 13795 app.instrumentationUiAutomationConnection = uiAutomationConnection; 13796 app.instrumentationResultClass = className; 13797 Binder.restoreCallingIdentity(origId); 13798 } 13799 13800 return true; 13801 } 13802 13803 /** 13804 * Report errors that occur while attempting to start Instrumentation. Always writes the 13805 * error to the logs, but if somebody is watching, send the report there too. This enables 13806 * the "am" command to report errors with more information. 13807 * 13808 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13809 * @param cn The component name of the instrumentation. 13810 * @param report The error report. 13811 */ 13812 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13813 ComponentName cn, String report) { 13814 Slog.w(TAG, report); 13815 try { 13816 if (watcher != null) { 13817 Bundle results = new Bundle(); 13818 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13819 results.putString("Error", report); 13820 watcher.instrumentationStatus(cn, -1, results); 13821 } 13822 } catch (RemoteException e) { 13823 Slog.w(TAG, e); 13824 } 13825 } 13826 13827 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13828 if (app.instrumentationWatcher != null) { 13829 try { 13830 // NOTE: IInstrumentationWatcher *must* be oneway here 13831 app.instrumentationWatcher.instrumentationFinished( 13832 app.instrumentationClass, 13833 resultCode, 13834 results); 13835 } catch (RemoteException e) { 13836 } 13837 } 13838 if (app.instrumentationUiAutomationConnection != null) { 13839 try { 13840 app.instrumentationUiAutomationConnection.shutdown(); 13841 } catch (RemoteException re) { 13842 /* ignore */ 13843 } 13844 // Only a UiAutomation can set this flag and now that 13845 // it is finished we make sure it is reset to its default. 13846 mUserIsMonkey = false; 13847 } 13848 app.instrumentationWatcher = null; 13849 app.instrumentationUiAutomationConnection = null; 13850 app.instrumentationClass = null; 13851 app.instrumentationInfo = null; 13852 app.instrumentationProfileFile = null; 13853 app.instrumentationArguments = null; 13854 13855 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId, 13856 "finished inst"); 13857 } 13858 13859 public void finishInstrumentation(IApplicationThread target, 13860 int resultCode, Bundle results) { 13861 int userId = UserHandle.getCallingUserId(); 13862 // Refuse possible leaked file descriptors 13863 if (results != null && results.hasFileDescriptors()) { 13864 throw new IllegalArgumentException("File descriptors passed in Intent"); 13865 } 13866 13867 synchronized(this) { 13868 ProcessRecord app = getRecordForAppLocked(target); 13869 if (app == null) { 13870 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13871 return; 13872 } 13873 final long origId = Binder.clearCallingIdentity(); 13874 finishInstrumentationLocked(app, resultCode, results); 13875 Binder.restoreCallingIdentity(origId); 13876 } 13877 } 13878 13879 // ========================================================= 13880 // CONFIGURATION 13881 // ========================================================= 13882 13883 public ConfigurationInfo getDeviceConfigurationInfo() { 13884 ConfigurationInfo config = new ConfigurationInfo(); 13885 synchronized (this) { 13886 config.reqTouchScreen = mConfiguration.touchscreen; 13887 config.reqKeyboardType = mConfiguration.keyboard; 13888 config.reqNavigation = mConfiguration.navigation; 13889 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13890 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13891 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13892 } 13893 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13894 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13895 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13896 } 13897 config.reqGlEsVersion = GL_ES_VERSION; 13898 } 13899 return config; 13900 } 13901 13902 ActivityStack getFocusedStack() { 13903 return mStackSupervisor.getFocusedStack(); 13904 } 13905 13906 public Configuration getConfiguration() { 13907 Configuration ci; 13908 synchronized(this) { 13909 ci = new Configuration(mConfiguration); 13910 } 13911 return ci; 13912 } 13913 13914 public void updatePersistentConfiguration(Configuration values) { 13915 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13916 "updateConfiguration()"); 13917 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 13918 "updateConfiguration()"); 13919 if (values == null) { 13920 throw new NullPointerException("Configuration must not be null"); 13921 } 13922 13923 synchronized(this) { 13924 final long origId = Binder.clearCallingIdentity(); 13925 updateConfigurationLocked(values, null, true, false); 13926 Binder.restoreCallingIdentity(origId); 13927 } 13928 } 13929 13930 public void updateConfiguration(Configuration values) { 13931 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13932 "updateConfiguration()"); 13933 13934 synchronized(this) { 13935 if (values == null && mWindowManager != null) { 13936 // sentinel: fetch the current configuration from the window manager 13937 values = mWindowManager.computeNewConfiguration(); 13938 } 13939 13940 if (mWindowManager != null) { 13941 mProcessList.applyDisplaySize(mWindowManager); 13942 } 13943 13944 final long origId = Binder.clearCallingIdentity(); 13945 if (values != null) { 13946 Settings.System.clearConfiguration(values); 13947 } 13948 updateConfigurationLocked(values, null, false, false); 13949 Binder.restoreCallingIdentity(origId); 13950 } 13951 } 13952 13953 /** 13954 * Do either or both things: (1) change the current configuration, and (2) 13955 * make sure the given activity is running with the (now) current 13956 * configuration. Returns true if the activity has been left running, or 13957 * false if <var>starting</var> is being destroyed to match the new 13958 * configuration. 13959 * @param persistent TODO 13960 */ 13961 boolean updateConfigurationLocked(Configuration values, 13962 ActivityRecord starting, boolean persistent, boolean initLocale) { 13963 int changes = 0; 13964 13965 if (values != null) { 13966 Configuration newConfig = new Configuration(mConfiguration); 13967 changes = newConfig.updateFrom(values); 13968 if (changes != 0) { 13969 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13970 Slog.i(TAG, "Updating configuration to: " + values); 13971 } 13972 13973 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 13974 13975 if (values.locale != null && !initLocale) { 13976 saveLocaleLocked(values.locale, 13977 !values.locale.equals(mConfiguration.locale), 13978 values.userSetLocale); 13979 } 13980 13981 mConfigurationSeq++; 13982 if (mConfigurationSeq <= 0) { 13983 mConfigurationSeq = 1; 13984 } 13985 newConfig.seq = mConfigurationSeq; 13986 mConfiguration = newConfig; 13987 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 13988 13989 final Configuration configCopy = new Configuration(mConfiguration); 13990 13991 // TODO: If our config changes, should we auto dismiss any currently 13992 // showing dialogs? 13993 mShowDialogs = shouldShowDialogs(newConfig); 13994 13995 AttributeCache ac = AttributeCache.instance(); 13996 if (ac != null) { 13997 ac.updateConfiguration(configCopy); 13998 } 13999 14000 // Make sure all resources in our process are updated 14001 // right now, so that anyone who is going to retrieve 14002 // resource values after we return will be sure to get 14003 // the new ones. This is especially important during 14004 // boot, where the first config change needs to guarantee 14005 // all resources have that config before following boot 14006 // code is executed. 14007 mSystemThread.applyConfigurationToResources(configCopy); 14008 14009 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14010 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14011 msg.obj = new Configuration(configCopy); 14012 mHandler.sendMessage(msg); 14013 } 14014 14015 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14016 ProcessRecord app = mLruProcesses.get(i); 14017 try { 14018 if (app.thread != null) { 14019 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14020 + app.processName + " new config " + mConfiguration); 14021 app.thread.scheduleConfigurationChanged(configCopy); 14022 } 14023 } catch (Exception e) { 14024 } 14025 } 14026 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14027 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14028 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14029 | Intent.FLAG_RECEIVER_FOREGROUND); 14030 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14031 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14032 Process.SYSTEM_UID, UserHandle.USER_ALL); 14033 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14034 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14035 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14036 broadcastIntentLocked(null, null, intent, 14037 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14038 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14039 } 14040 } 14041 } 14042 14043 boolean kept = true; 14044 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14045 // mainStack is null during startup. 14046 if (mainStack != null) { 14047 if (changes != 0 && starting == null) { 14048 // If the configuration changed, and the caller is not already 14049 // in the process of starting an activity, then find the top 14050 // activity to check if its configuration needs to change. 14051 starting = mainStack.topRunningActivityLocked(null); 14052 } 14053 14054 if (starting != null) { 14055 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14056 // And we need to make sure at this point that all other activities 14057 // are made visible with the correct configuration. 14058 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14059 } 14060 } 14061 14062 if (values != null && mWindowManager != null) { 14063 mWindowManager.setNewConfiguration(mConfiguration); 14064 } 14065 14066 return kept; 14067 } 14068 14069 /** 14070 * Decide based on the configuration whether we should shouw the ANR, 14071 * crash, etc dialogs. The idea is that if there is no affordnace to 14072 * press the on-screen buttons, we shouldn't show the dialog. 14073 * 14074 * A thought: SystemUI might also want to get told about this, the Power 14075 * dialog / global actions also might want different behaviors. 14076 */ 14077 private static final boolean shouldShowDialogs(Configuration config) { 14078 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14079 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14080 } 14081 14082 /** 14083 * Save the locale. You must be inside a synchronized (this) block. 14084 */ 14085 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14086 if(isDiff) { 14087 SystemProperties.set("user.language", l.getLanguage()); 14088 SystemProperties.set("user.region", l.getCountry()); 14089 } 14090 14091 if(isPersist) { 14092 SystemProperties.set("persist.sys.language", l.getLanguage()); 14093 SystemProperties.set("persist.sys.country", l.getCountry()); 14094 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14095 } 14096 } 14097 14098 @Override 14099 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14100 ActivityRecord srec = ActivityRecord.forToken(token); 14101 return srec != null && srec.task.affinity != null && 14102 srec.task.affinity.equals(destAffinity); 14103 } 14104 14105 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14106 Intent resultData) { 14107 14108 synchronized (this) { 14109 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14110 if (stack != null) { 14111 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14112 } 14113 return false; 14114 } 14115 } 14116 14117 public int getLaunchedFromUid(IBinder activityToken) { 14118 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14119 if (srec == null) { 14120 return -1; 14121 } 14122 return srec.launchedFromUid; 14123 } 14124 14125 public String getLaunchedFromPackage(IBinder activityToken) { 14126 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14127 if (srec == null) { 14128 return null; 14129 } 14130 return srec.launchedFromPackage; 14131 } 14132 14133 // ========================================================= 14134 // LIFETIME MANAGEMENT 14135 // ========================================================= 14136 14137 // Returns which broadcast queue the app is the current [or imminent] receiver 14138 // on, or 'null' if the app is not an active broadcast recipient. 14139 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14140 BroadcastRecord r = app.curReceiver; 14141 if (r != null) { 14142 return r.queue; 14143 } 14144 14145 // It's not the current receiver, but it might be starting up to become one 14146 synchronized (this) { 14147 for (BroadcastQueue queue : mBroadcastQueues) { 14148 r = queue.mPendingBroadcast; 14149 if (r != null && r.curApp == app) { 14150 // found it; report which queue it's in 14151 return queue; 14152 } 14153 } 14154 } 14155 14156 return null; 14157 } 14158 14159 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14160 boolean doingAll, long now) { 14161 if (mAdjSeq == app.adjSeq) { 14162 // This adjustment has already been computed. 14163 return app.curRawAdj; 14164 } 14165 14166 if (app.thread == null) { 14167 app.adjSeq = mAdjSeq; 14168 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14169 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14170 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14171 } 14172 14173 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14174 app.adjSource = null; 14175 app.adjTarget = null; 14176 app.empty = false; 14177 app.cached = false; 14178 14179 final int activitiesSize = app.activities.size(); 14180 14181 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14182 // The max adjustment doesn't allow this app to be anything 14183 // below foreground, so it is not worth doing work for it. 14184 app.adjType = "fixed"; 14185 app.adjSeq = mAdjSeq; 14186 app.curRawAdj = app.maxAdj; 14187 app.foregroundActivities = false; 14188 app.keeping = true; 14189 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14190 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14191 // System process can do UI, and when they do we want to have 14192 // them trim their memory after the user leaves the UI. To 14193 // facilitate this, here we need to determine whether or not it 14194 // is currently showing UI. 14195 app.systemNoUi = true; 14196 if (app == TOP_APP) { 14197 app.systemNoUi = false; 14198 } else if (activitiesSize > 0) { 14199 for (int j = 0; j < activitiesSize; j++) { 14200 final ActivityRecord r = app.activities.get(j); 14201 if (r.visible) { 14202 app.systemNoUi = false; 14203 } 14204 } 14205 } 14206 if (!app.systemNoUi) { 14207 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14208 } 14209 return (app.curAdj=app.maxAdj); 14210 } 14211 14212 app.keeping = false; 14213 app.systemNoUi = false; 14214 14215 // Determine the importance of the process, starting with most 14216 // important to least, and assign an appropriate OOM adjustment. 14217 int adj; 14218 int schedGroup; 14219 int procState; 14220 boolean foregroundActivities = false; 14221 boolean interesting = false; 14222 BroadcastQueue queue; 14223 if (app == TOP_APP) { 14224 // The last app on the list is the foreground app. 14225 adj = ProcessList.FOREGROUND_APP_ADJ; 14226 schedGroup = Process.THREAD_GROUP_DEFAULT; 14227 app.adjType = "top-activity"; 14228 foregroundActivities = true; 14229 interesting = true; 14230 procState = ActivityManager.PROCESS_STATE_TOP; 14231 } else if (app.instrumentationClass != null) { 14232 // Don't want to kill running instrumentation. 14233 adj = ProcessList.FOREGROUND_APP_ADJ; 14234 schedGroup = Process.THREAD_GROUP_DEFAULT; 14235 app.adjType = "instrumentation"; 14236 interesting = true; 14237 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14238 } else if ((queue = isReceivingBroadcast(app)) != null) { 14239 // An app that is currently receiving a broadcast also 14240 // counts as being in the foreground for OOM killer purposes. 14241 // It's placed in a sched group based on the nature of the 14242 // broadcast as reflected by which queue it's active in. 14243 adj = ProcessList.FOREGROUND_APP_ADJ; 14244 schedGroup = (queue == mFgBroadcastQueue) 14245 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14246 app.adjType = "broadcast"; 14247 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14248 } else if (app.executingServices.size() > 0) { 14249 // An app that is currently executing a service callback also 14250 // counts as being in the foreground. 14251 adj = ProcessList.FOREGROUND_APP_ADJ; 14252 schedGroup = app.execServicesFg ? 14253 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14254 app.adjType = "exec-service"; 14255 procState = ActivityManager.PROCESS_STATE_SERVICE; 14256 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14257 } else { 14258 // As far as we know the process is empty. We may change our mind later. 14259 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14260 // At this point we don't actually know the adjustment. Use the cached adj 14261 // value that the caller wants us to. 14262 adj = cachedAdj; 14263 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14264 app.cached = true; 14265 app.empty = true; 14266 app.adjType = "cch-empty"; 14267 } 14268 14269 // Examine all activities if not already foreground. 14270 if (!foregroundActivities && activitiesSize > 0) { 14271 for (int j = 0; j < activitiesSize; j++) { 14272 final ActivityRecord r = app.activities.get(j); 14273 if (r.app != app) { 14274 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14275 + app + "?!?"); 14276 continue; 14277 } 14278 if (r.visible) { 14279 // App has a visible activity; only upgrade adjustment. 14280 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14281 adj = ProcessList.VISIBLE_APP_ADJ; 14282 app.adjType = "visible"; 14283 } 14284 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14285 procState = ActivityManager.PROCESS_STATE_TOP; 14286 } 14287 schedGroup = Process.THREAD_GROUP_DEFAULT; 14288 app.cached = false; 14289 app.empty = false; 14290 foregroundActivities = true; 14291 break; 14292 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14293 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14294 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14295 app.adjType = "pausing"; 14296 } 14297 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14298 procState = ActivityManager.PROCESS_STATE_TOP; 14299 } 14300 schedGroup = Process.THREAD_GROUP_DEFAULT; 14301 app.cached = false; 14302 app.empty = false; 14303 foregroundActivities = true; 14304 } else if (r.state == ActivityState.STOPPING) { 14305 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14306 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14307 app.adjType = "stopping"; 14308 } 14309 // For the process state, we will at this point consider the 14310 // process to be cached. It will be cached either as an activity 14311 // or empty depending on whether the activity is finishing. We do 14312 // this so that we can treat the process as cached for purposes of 14313 // memory trimming (determing current memory level, trim command to 14314 // send to process) since there can be an arbitrary number of stopping 14315 // processes and they should soon all go into the cached state. 14316 if (!r.finishing) { 14317 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14318 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14319 } 14320 } 14321 app.cached = false; 14322 app.empty = false; 14323 foregroundActivities = true; 14324 } else { 14325 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14326 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14327 app.adjType = "cch-act"; 14328 } 14329 } 14330 } 14331 } 14332 14333 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14334 if (app.foregroundServices) { 14335 // The user is aware of this app, so make it visible. 14336 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14337 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14338 app.cached = false; 14339 app.adjType = "fg-service"; 14340 schedGroup = Process.THREAD_GROUP_DEFAULT; 14341 } else if (app.forcingToForeground != null) { 14342 // The user is aware of this app, so make it visible. 14343 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14344 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14345 app.cached = false; 14346 app.adjType = "force-fg"; 14347 app.adjSource = app.forcingToForeground; 14348 schedGroup = Process.THREAD_GROUP_DEFAULT; 14349 } 14350 } 14351 14352 if (app.foregroundServices) { 14353 interesting = true; 14354 } 14355 14356 if (app == mHeavyWeightProcess) { 14357 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14358 // We don't want to kill the current heavy-weight process. 14359 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14360 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14361 app.cached = false; 14362 app.adjType = "heavy"; 14363 } 14364 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14365 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14366 } 14367 } 14368 14369 if (app == mHomeProcess) { 14370 if (adj > ProcessList.HOME_APP_ADJ) { 14371 // This process is hosting what we currently consider to be the 14372 // home app, so we don't want to let it go into the background. 14373 adj = ProcessList.HOME_APP_ADJ; 14374 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14375 app.cached = false; 14376 app.adjType = "home"; 14377 } 14378 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14379 procState = ActivityManager.PROCESS_STATE_HOME; 14380 } 14381 } 14382 14383 if (app == mPreviousProcess && app.activities.size() > 0) { 14384 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14385 // This was the previous process that showed UI to the user. 14386 // We want to try to keep it around more aggressively, to give 14387 // a good experience around switching between two apps. 14388 adj = ProcessList.PREVIOUS_APP_ADJ; 14389 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14390 app.cached = false; 14391 app.adjType = "previous"; 14392 } 14393 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14394 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14395 } 14396 } 14397 14398 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14399 + " reason=" + app.adjType); 14400 14401 // By default, we use the computed adjustment. It may be changed if 14402 // there are applications dependent on our services or providers, but 14403 // this gives us a baseline and makes sure we don't get into an 14404 // infinite recursion. 14405 app.adjSeq = mAdjSeq; 14406 app.curRawAdj = adj; 14407 app.hasStartedServices = false; 14408 14409 if (mBackupTarget != null && app == mBackupTarget.app) { 14410 // If possible we want to avoid killing apps while they're being backed up 14411 if (adj > ProcessList.BACKUP_APP_ADJ) { 14412 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14413 adj = ProcessList.BACKUP_APP_ADJ; 14414 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14415 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14416 } 14417 app.adjType = "backup"; 14418 app.cached = false; 14419 } 14420 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14421 procState = ActivityManager.PROCESS_STATE_BACKUP; 14422 } 14423 } 14424 14425 boolean mayBeTop = false; 14426 14427 for (int is = app.services.size()-1; 14428 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14429 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14430 || procState > ActivityManager.PROCESS_STATE_TOP); 14431 is--) { 14432 ServiceRecord s = app.services.valueAt(is); 14433 if (s.startRequested) { 14434 app.hasStartedServices = true; 14435 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14436 procState = ActivityManager.PROCESS_STATE_SERVICE; 14437 } 14438 if (app.hasShownUi && app != mHomeProcess) { 14439 // If this process has shown some UI, let it immediately 14440 // go to the LRU list because it may be pretty heavy with 14441 // UI stuff. We'll tag it with a label just to help 14442 // debug and understand what is going on. 14443 if (adj > ProcessList.SERVICE_ADJ) { 14444 app.adjType = "cch-started-ui-services"; 14445 } 14446 } else { 14447 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14448 // This service has seen some activity within 14449 // recent memory, so we will keep its process ahead 14450 // of the background processes. 14451 if (adj > ProcessList.SERVICE_ADJ) { 14452 adj = ProcessList.SERVICE_ADJ; 14453 app.adjType = "started-services"; 14454 app.cached = false; 14455 } 14456 } 14457 // If we have let the service slide into the background 14458 // state, still have some text describing what it is doing 14459 // even though the service no longer has an impact. 14460 if (adj > ProcessList.SERVICE_ADJ) { 14461 app.adjType = "cch-started-services"; 14462 } 14463 } 14464 // Don't kill this process because it is doing work; it 14465 // has said it is doing work. 14466 app.keeping = true; 14467 } 14468 for (int conni = s.connections.size()-1; 14469 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14470 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14471 || procState > ActivityManager.PROCESS_STATE_TOP); 14472 conni--) { 14473 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14474 for (int i = 0; 14475 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14476 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14477 || procState > ActivityManager.PROCESS_STATE_TOP); 14478 i++) { 14479 // XXX should compute this based on the max of 14480 // all connected clients. 14481 ConnectionRecord cr = clist.get(i); 14482 if (cr.binding.client == app) { 14483 // Binding to ourself is not interesting. 14484 continue; 14485 } 14486 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14487 ProcessRecord client = cr.binding.client; 14488 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14489 TOP_APP, doingAll, now); 14490 int clientProcState = client.curProcState; 14491 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14492 // If the other app is cached for any reason, for purposes here 14493 // we are going to consider it empty. The specific cached state 14494 // doesn't propagate except under certain conditions. 14495 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14496 } 14497 String adjType = null; 14498 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14499 // Not doing bind OOM management, so treat 14500 // this guy more like a started service. 14501 if (app.hasShownUi && app != mHomeProcess) { 14502 // If this process has shown some UI, let it immediately 14503 // go to the LRU list because it may be pretty heavy with 14504 // UI stuff. We'll tag it with a label just to help 14505 // debug and understand what is going on. 14506 if (adj > clientAdj) { 14507 adjType = "cch-bound-ui-services"; 14508 } 14509 app.cached = false; 14510 clientAdj = adj; 14511 clientProcState = procState; 14512 } else { 14513 if (now >= (s.lastActivity 14514 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14515 // This service has not seen activity within 14516 // recent memory, so allow it to drop to the 14517 // LRU list if there is no other reason to keep 14518 // it around. We'll also tag it with a label just 14519 // to help debug and undertand what is going on. 14520 if (adj > clientAdj) { 14521 adjType = "cch-bound-services"; 14522 } 14523 clientAdj = adj; 14524 } 14525 } 14526 } 14527 if (adj > clientAdj) { 14528 // If this process has recently shown UI, and 14529 // the process that is binding to it is less 14530 // important than being visible, then we don't 14531 // care about the binding as much as we care 14532 // about letting this process get into the LRU 14533 // list to be killed and restarted if needed for 14534 // memory. 14535 if (app.hasShownUi && app != mHomeProcess 14536 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14537 adjType = "cch-bound-ui-services"; 14538 } else { 14539 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14540 |Context.BIND_IMPORTANT)) != 0) { 14541 adj = clientAdj; 14542 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14543 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14544 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14545 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14546 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14547 adj = clientAdj; 14548 } else { 14549 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14550 adj = ProcessList.VISIBLE_APP_ADJ; 14551 } 14552 } 14553 if (!client.cached) { 14554 app.cached = false; 14555 } 14556 if (client.keeping) { 14557 app.keeping = true; 14558 } 14559 adjType = "service"; 14560 } 14561 } 14562 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14563 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14564 schedGroup = Process.THREAD_GROUP_DEFAULT; 14565 } 14566 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14567 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14568 // Special handling of clients who are in the top state. 14569 // We *may* want to consider this process to be in the 14570 // top state as well, but only if there is not another 14571 // reason for it to be running. Being on the top is a 14572 // special state, meaning you are specifically running 14573 // for the current top app. If the process is already 14574 // running in the background for some other reason, it 14575 // is more important to continue considering it to be 14576 // in the background state. 14577 mayBeTop = true; 14578 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14579 } else { 14580 // Special handling for above-top states (persistent 14581 // processes). These should not bring the current process 14582 // into the top state, since they are not on top. Instead 14583 // give them the best state after that. 14584 clientProcState = 14585 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14586 } 14587 } 14588 } else { 14589 if (clientProcState < 14590 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14591 clientProcState = 14592 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14593 } 14594 } 14595 if (procState > clientProcState) { 14596 procState = clientProcState; 14597 } 14598 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14599 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14600 app.pendingUiClean = true; 14601 } 14602 if (adjType != null) { 14603 app.adjType = adjType; 14604 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14605 .REASON_SERVICE_IN_USE; 14606 app.adjSource = cr.binding.client; 14607 app.adjSourceOom = clientAdj; 14608 app.adjTarget = s.name; 14609 } 14610 } 14611 final ActivityRecord a = cr.activity; 14612 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14613 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14614 (a.visible || a.state == ActivityState.RESUMED 14615 || a.state == ActivityState.PAUSING)) { 14616 adj = ProcessList.FOREGROUND_APP_ADJ; 14617 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14618 schedGroup = Process.THREAD_GROUP_DEFAULT; 14619 } 14620 app.cached = false; 14621 app.adjType = "service"; 14622 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14623 .REASON_SERVICE_IN_USE; 14624 app.adjSource = a; 14625 app.adjSourceOom = adj; 14626 app.adjTarget = s.name; 14627 } 14628 } 14629 } 14630 } 14631 } 14632 14633 for (int provi = app.pubProviders.size()-1; 14634 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14635 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14636 || procState > ActivityManager.PROCESS_STATE_TOP); 14637 provi--) { 14638 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14639 for (int i = cpr.connections.size()-1; 14640 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14641 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14642 || procState > ActivityManager.PROCESS_STATE_TOP); 14643 i--) { 14644 ContentProviderConnection conn = cpr.connections.get(i); 14645 ProcessRecord client = conn.client; 14646 if (client == app) { 14647 // Being our own client is not interesting. 14648 continue; 14649 } 14650 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14651 int clientProcState = client.curProcState; 14652 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14653 // If the other app is cached for any reason, for purposes here 14654 // we are going to consider it empty. 14655 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14656 } 14657 if (adj > clientAdj) { 14658 if (app.hasShownUi && app != mHomeProcess 14659 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14660 app.adjType = "cch-ui-provider"; 14661 } else { 14662 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14663 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14664 app.adjType = "provider"; 14665 } 14666 app.cached &= client.cached; 14667 app.keeping |= client.keeping; 14668 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14669 .REASON_PROVIDER_IN_USE; 14670 app.adjSource = client; 14671 app.adjSourceOom = clientAdj; 14672 app.adjTarget = cpr.name; 14673 } 14674 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14675 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14676 // Special handling of clients who are in the top state. 14677 // We *may* want to consider this process to be in the 14678 // top state as well, but only if there is not another 14679 // reason for it to be running. Being on the top is a 14680 // special state, meaning you are specifically running 14681 // for the current top app. If the process is already 14682 // running in the background for some other reason, it 14683 // is more important to continue considering it to be 14684 // in the background state. 14685 mayBeTop = true; 14686 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14687 } else { 14688 // Special handling for above-top states (persistent 14689 // processes). These should not bring the current process 14690 // into the top state, since they are not on top. Instead 14691 // give them the best state after that. 14692 clientProcState = 14693 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14694 } 14695 } 14696 if (procState > clientProcState) { 14697 procState = clientProcState; 14698 } 14699 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14700 schedGroup = Process.THREAD_GROUP_DEFAULT; 14701 } 14702 } 14703 // If the provider has external (non-framework) process 14704 // dependencies, ensure that its adjustment is at least 14705 // FOREGROUND_APP_ADJ. 14706 if (cpr.hasExternalProcessHandles()) { 14707 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14708 adj = ProcessList.FOREGROUND_APP_ADJ; 14709 schedGroup = Process.THREAD_GROUP_DEFAULT; 14710 app.cached = false; 14711 app.keeping = true; 14712 app.adjType = "provider"; 14713 app.adjTarget = cpr.name; 14714 } 14715 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14716 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14717 } 14718 } 14719 } 14720 14721 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14722 // A client of one of our services or providers is in the top state. We 14723 // *may* want to be in the top state, but not if we are already running in 14724 // the background for some other reason. For the decision here, we are going 14725 // to pick out a few specific states that we want to remain in when a client 14726 // is top (states that tend to be longer-term) and otherwise allow it to go 14727 // to the top state. 14728 switch (procState) { 14729 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14730 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14731 case ActivityManager.PROCESS_STATE_SERVICE: 14732 // These all are longer-term states, so pull them up to the top 14733 // of the background states, but not all the way to the top state. 14734 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14735 break; 14736 default: 14737 // Otherwise, top is a better choice, so take it. 14738 procState = ActivityManager.PROCESS_STATE_TOP; 14739 break; 14740 } 14741 } 14742 14743 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14744 // This is a cached process, but with client activities. Mark it so. 14745 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14746 app.adjType = "cch-client-act"; 14747 } 14748 14749 if (adj == ProcessList.SERVICE_ADJ) { 14750 if (doingAll) { 14751 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14752 mNewNumServiceProcs++; 14753 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14754 if (!app.serviceb) { 14755 // This service isn't far enough down on the LRU list to 14756 // normally be a B service, but if we are low on RAM and it 14757 // is large we want to force it down since we would prefer to 14758 // keep launcher over it. 14759 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 14760 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 14761 app.serviceHighRam = true; 14762 app.serviceb = true; 14763 //Slog.i(TAG, "ADJ " + app + " high ram!"); 14764 } else { 14765 mNewNumAServiceProcs++; 14766 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 14767 } 14768 } else { 14769 app.serviceHighRam = false; 14770 } 14771 } 14772 if (app.serviceb) { 14773 adj = ProcessList.SERVICE_B_ADJ; 14774 } 14775 } 14776 14777 app.curRawAdj = adj; 14778 14779 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14780 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14781 if (adj > app.maxAdj) { 14782 adj = app.maxAdj; 14783 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14784 schedGroup = Process.THREAD_GROUP_DEFAULT; 14785 } 14786 } 14787 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 14788 app.keeping = true; 14789 } 14790 14791 // Do final modification to adj. Everything we do between here and applying 14792 // the final setAdj must be done in this function, because we will also use 14793 // it when computing the final cached adj later. Note that we don't need to 14794 // worry about this for max adj above, since max adj will always be used to 14795 // keep it out of the cached vaues. 14796 adj = app.modifyRawOomAdj(adj); 14797 14798 app.curProcState = procState; 14799 14800 int importance = app.memImportance; 14801 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14802 app.curAdj = adj; 14803 app.curSchedGroup = schedGroup; 14804 if (!interesting) { 14805 // For this reporting, if there is not something explicitly 14806 // interesting in this process then we will push it to the 14807 // background importance. 14808 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14809 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 14810 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14811 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14812 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14813 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14814 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14815 } else if (adj >= ProcessList.SERVICE_ADJ) { 14816 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14817 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14818 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14819 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14820 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14821 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14822 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14823 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14824 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14825 } else { 14826 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14827 } 14828 } 14829 14830 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14831 if (foregroundActivities != app.foregroundActivities) { 14832 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14833 } 14834 if (changes != 0) { 14835 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14836 app.memImportance = importance; 14837 app.foregroundActivities = foregroundActivities; 14838 int i = mPendingProcessChanges.size()-1; 14839 ProcessChangeItem item = null; 14840 while (i >= 0) { 14841 item = mPendingProcessChanges.get(i); 14842 if (item.pid == app.pid) { 14843 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14844 break; 14845 } 14846 i--; 14847 } 14848 if (i < 0) { 14849 // No existing item in pending changes; need a new one. 14850 final int NA = mAvailProcessChanges.size(); 14851 if (NA > 0) { 14852 item = mAvailProcessChanges.remove(NA-1); 14853 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14854 } else { 14855 item = new ProcessChangeItem(); 14856 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14857 } 14858 item.changes = 0; 14859 item.pid = app.pid; 14860 item.uid = app.info.uid; 14861 if (mPendingProcessChanges.size() == 0) { 14862 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14863 "*** Enqueueing dispatch processes changed!"); 14864 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14865 } 14866 mPendingProcessChanges.add(item); 14867 } 14868 item.changes |= changes; 14869 item.importance = importance; 14870 item.foregroundActivities = foregroundActivities; 14871 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14872 + Integer.toHexString(System.identityHashCode(item)) 14873 + " " + app.toShortString() + ": changes=" + item.changes 14874 + " importance=" + item.importance 14875 + " foreground=" + item.foregroundActivities 14876 + " type=" + app.adjType + " source=" + app.adjSource 14877 + " target=" + app.adjTarget); 14878 } 14879 14880 return app.curRawAdj; 14881 } 14882 14883 /** 14884 * Schedule PSS collection of a process. 14885 */ 14886 void requestPssLocked(ProcessRecord proc, int procState) { 14887 if (mPendingPssProcesses.contains(proc)) { 14888 return; 14889 } 14890 if (mPendingPssProcesses.size() == 0) { 14891 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14892 } 14893 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 14894 proc.pssProcState = procState; 14895 mPendingPssProcesses.add(proc); 14896 } 14897 14898 /** 14899 * Schedule PSS collection of all processes. 14900 */ 14901 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 14902 if (!always) { 14903 if (now < (mLastFullPssTime + 14904 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 14905 return; 14906 } 14907 } 14908 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 14909 mLastFullPssTime = now; 14910 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 14911 mPendingPssProcesses.clear(); 14912 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14913 ProcessRecord app = mLruProcesses.get(i); 14914 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 14915 app.pssProcState = app.setProcState; 14916 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 14917 mSleeping, now); 14918 mPendingPssProcesses.add(app); 14919 } 14920 } 14921 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14922 } 14923 14924 /** 14925 * Ask a given process to GC right now. 14926 */ 14927 final void performAppGcLocked(ProcessRecord app) { 14928 try { 14929 app.lastRequestedGc = SystemClock.uptimeMillis(); 14930 if (app.thread != null) { 14931 if (app.reportLowMemory) { 14932 app.reportLowMemory = false; 14933 app.thread.scheduleLowMemory(); 14934 } else { 14935 app.thread.processInBackground(); 14936 } 14937 } 14938 } catch (Exception e) { 14939 // whatever. 14940 } 14941 } 14942 14943 /** 14944 * Returns true if things are idle enough to perform GCs. 14945 */ 14946 private final boolean canGcNowLocked() { 14947 boolean processingBroadcasts = false; 14948 for (BroadcastQueue q : mBroadcastQueues) { 14949 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 14950 processingBroadcasts = true; 14951 } 14952 } 14953 return !processingBroadcasts 14954 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 14955 } 14956 14957 /** 14958 * Perform GCs on all processes that are waiting for it, but only 14959 * if things are idle. 14960 */ 14961 final void performAppGcsLocked() { 14962 final int N = mProcessesToGc.size(); 14963 if (N <= 0) { 14964 return; 14965 } 14966 if (canGcNowLocked()) { 14967 while (mProcessesToGc.size() > 0) { 14968 ProcessRecord proc = mProcessesToGc.remove(0); 14969 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 14970 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 14971 <= SystemClock.uptimeMillis()) { 14972 // To avoid spamming the system, we will GC processes one 14973 // at a time, waiting a few seconds between each. 14974 performAppGcLocked(proc); 14975 scheduleAppGcsLocked(); 14976 return; 14977 } else { 14978 // It hasn't been long enough since we last GCed this 14979 // process... put it in the list to wait for its time. 14980 addProcessToGcListLocked(proc); 14981 break; 14982 } 14983 } 14984 } 14985 14986 scheduleAppGcsLocked(); 14987 } 14988 } 14989 14990 /** 14991 * If all looks good, perform GCs on all processes waiting for them. 14992 */ 14993 final void performAppGcsIfAppropriateLocked() { 14994 if (canGcNowLocked()) { 14995 performAppGcsLocked(); 14996 return; 14997 } 14998 // Still not idle, wait some more. 14999 scheduleAppGcsLocked(); 15000 } 15001 15002 /** 15003 * Schedule the execution of all pending app GCs. 15004 */ 15005 final void scheduleAppGcsLocked() { 15006 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15007 15008 if (mProcessesToGc.size() > 0) { 15009 // Schedule a GC for the time to the next process. 15010 ProcessRecord proc = mProcessesToGc.get(0); 15011 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15012 15013 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15014 long now = SystemClock.uptimeMillis(); 15015 if (when < (now+GC_TIMEOUT)) { 15016 when = now + GC_TIMEOUT; 15017 } 15018 mHandler.sendMessageAtTime(msg, when); 15019 } 15020 } 15021 15022 /** 15023 * Add a process to the array of processes waiting to be GCed. Keeps the 15024 * list in sorted order by the last GC time. The process can't already be 15025 * on the list. 15026 */ 15027 final void addProcessToGcListLocked(ProcessRecord proc) { 15028 boolean added = false; 15029 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15030 if (mProcessesToGc.get(i).lastRequestedGc < 15031 proc.lastRequestedGc) { 15032 added = true; 15033 mProcessesToGc.add(i+1, proc); 15034 break; 15035 } 15036 } 15037 if (!added) { 15038 mProcessesToGc.add(0, proc); 15039 } 15040 } 15041 15042 /** 15043 * Set up to ask a process to GC itself. This will either do it 15044 * immediately, or put it on the list of processes to gc the next 15045 * time things are idle. 15046 */ 15047 final void scheduleAppGcLocked(ProcessRecord app) { 15048 long now = SystemClock.uptimeMillis(); 15049 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15050 return; 15051 } 15052 if (!mProcessesToGc.contains(app)) { 15053 addProcessToGcListLocked(app); 15054 scheduleAppGcsLocked(); 15055 } 15056 } 15057 15058 final void checkExcessivePowerUsageLocked(boolean doKills) { 15059 updateCpuStatsNow(); 15060 15061 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15062 boolean doWakeKills = doKills; 15063 boolean doCpuKills = doKills; 15064 if (mLastPowerCheckRealtime == 0) { 15065 doWakeKills = false; 15066 } 15067 if (mLastPowerCheckUptime == 0) { 15068 doCpuKills = false; 15069 } 15070 if (stats.isScreenOn()) { 15071 doWakeKills = false; 15072 } 15073 final long curRealtime = SystemClock.elapsedRealtime(); 15074 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15075 final long curUptime = SystemClock.uptimeMillis(); 15076 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15077 mLastPowerCheckRealtime = curRealtime; 15078 mLastPowerCheckUptime = curUptime; 15079 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15080 doWakeKills = false; 15081 } 15082 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15083 doCpuKills = false; 15084 } 15085 int i = mLruProcesses.size(); 15086 while (i > 0) { 15087 i--; 15088 ProcessRecord app = mLruProcesses.get(i); 15089 if (!app.keeping) { 15090 long wtime; 15091 synchronized (stats) { 15092 wtime = stats.getProcessWakeTime(app.info.uid, 15093 app.pid, curRealtime); 15094 } 15095 long wtimeUsed = wtime - app.lastWakeTime; 15096 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15097 if (DEBUG_POWER) { 15098 StringBuilder sb = new StringBuilder(128); 15099 sb.append("Wake for "); 15100 app.toShortString(sb); 15101 sb.append(": over "); 15102 TimeUtils.formatDuration(realtimeSince, sb); 15103 sb.append(" used "); 15104 TimeUtils.formatDuration(wtimeUsed, sb); 15105 sb.append(" ("); 15106 sb.append((wtimeUsed*100)/realtimeSince); 15107 sb.append("%)"); 15108 Slog.i(TAG, sb.toString()); 15109 sb.setLength(0); 15110 sb.append("CPU for "); 15111 app.toShortString(sb); 15112 sb.append(": over "); 15113 TimeUtils.formatDuration(uptimeSince, sb); 15114 sb.append(" used "); 15115 TimeUtils.formatDuration(cputimeUsed, sb); 15116 sb.append(" ("); 15117 sb.append((cputimeUsed*100)/uptimeSince); 15118 sb.append("%)"); 15119 Slog.i(TAG, sb.toString()); 15120 } 15121 // If a process has held a wake lock for more 15122 // than 50% of the time during this period, 15123 // that sounds bad. Kill! 15124 if (doWakeKills && realtimeSince > 0 15125 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15126 synchronized (stats) { 15127 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15128 realtimeSince, wtimeUsed); 15129 } 15130 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15131 + " during " + realtimeSince); 15132 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15133 } else if (doCpuKills && uptimeSince > 0 15134 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15135 synchronized (stats) { 15136 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15137 uptimeSince, cputimeUsed); 15138 } 15139 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15140 + " during " + uptimeSince); 15141 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15142 } else { 15143 app.lastWakeTime = wtime; 15144 app.lastCpuTime = app.curCpuTime; 15145 } 15146 } 15147 } 15148 } 15149 15150 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15151 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15152 boolean success = true; 15153 15154 if (app.curRawAdj != app.setRawAdj) { 15155 if (wasKeeping && !app.keeping) { 15156 // This app is no longer something we want to keep. Note 15157 // its current wake lock time to later know to kill it if 15158 // it is not behaving well. 15159 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15160 synchronized (stats) { 15161 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15162 app.pid, SystemClock.elapsedRealtime()); 15163 } 15164 app.lastCpuTime = app.curCpuTime; 15165 } 15166 15167 app.setRawAdj = app.curRawAdj; 15168 } 15169 15170 if (app.curAdj != app.setAdj) { 15171 ProcessList.setOomAdj(app.pid, app.curAdj); 15172 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15173 TAG, "Set " + app.pid + " " + app.processName + 15174 " adj " + app.curAdj + ": " + app.adjType); 15175 app.setAdj = app.curAdj; 15176 } 15177 15178 if (app.setSchedGroup != app.curSchedGroup) { 15179 app.setSchedGroup = app.curSchedGroup; 15180 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15181 "Setting process group of " + app.processName 15182 + " to " + app.curSchedGroup); 15183 if (app.waitingToKill != null && 15184 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15185 killUnneededProcessLocked(app, app.waitingToKill); 15186 success = false; 15187 } else { 15188 if (true) { 15189 long oldId = Binder.clearCallingIdentity(); 15190 try { 15191 Process.setProcessGroup(app.pid, app.curSchedGroup); 15192 } catch (Exception e) { 15193 Slog.w(TAG, "Failed setting process group of " + app.pid 15194 + " to " + app.curSchedGroup); 15195 e.printStackTrace(); 15196 } finally { 15197 Binder.restoreCallingIdentity(oldId); 15198 } 15199 } else { 15200 if (app.thread != null) { 15201 try { 15202 app.thread.setSchedulingGroup(app.curSchedGroup); 15203 } catch (RemoteException e) { 15204 } 15205 } 15206 } 15207 Process.setSwappiness(app.pid, 15208 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15209 } 15210 } 15211 if (app.repProcState != app.curProcState) { 15212 app.repProcState = app.curProcState; 15213 if (!reportingProcessState && app.thread != null) { 15214 try { 15215 if (false) { 15216 //RuntimeException h = new RuntimeException("here"); 15217 Slog.i(TAG, "Sending new process state " + app.repProcState 15218 + " to " + app /*, h*/); 15219 } 15220 app.thread.setProcessState(app.repProcState); 15221 } catch (RemoteException e) { 15222 } 15223 } 15224 } 15225 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15226 app.setProcState)) { 15227 app.lastStateTime = now; 15228 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15229 mSleeping, now); 15230 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15231 + ProcessList.makeProcStateString(app.setProcState) + " to " 15232 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15233 + (app.nextPssTime-now) + ": " + app); 15234 } else { 15235 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15236 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15237 requestPssLocked(app, app.setProcState); 15238 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15239 mSleeping, now); 15240 } else if (false && DEBUG_PSS) { 15241 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15242 } 15243 } 15244 if (app.setProcState != app.curProcState) { 15245 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15246 "Proc state change of " + app.processName 15247 + " to " + app.curProcState); 15248 app.setProcState = app.curProcState; 15249 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15250 app.notCachedSinceIdle = false; 15251 } 15252 if (!doingAll) { 15253 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15254 } else { 15255 app.procStateChanged = true; 15256 } 15257 } 15258 return success; 15259 } 15260 15261 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15262 if (proc.thread != null && proc.baseProcessTracker != null) { 15263 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15264 } 15265 } 15266 15267 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15268 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15269 if (app.thread == null) { 15270 return false; 15271 } 15272 15273 final boolean wasKeeping = app.keeping; 15274 15275 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15276 15277 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15278 reportingProcessState, now); 15279 } 15280 15281 private final ActivityRecord resumedAppLocked() { 15282 return mStackSupervisor.resumedAppLocked(); 15283 } 15284 15285 final boolean updateOomAdjLocked(ProcessRecord app) { 15286 return updateOomAdjLocked(app, false); 15287 } 15288 15289 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15290 final ActivityRecord TOP_ACT = resumedAppLocked(); 15291 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15292 final boolean wasCached = app.cached; 15293 15294 mAdjSeq++; 15295 15296 // This is the desired cached adjusment we want to tell it to use. 15297 // If our app is currently cached, we know it, and that is it. Otherwise, 15298 // we don't know it yet, and it needs to now be cached we will then 15299 // need to do a complete oom adj. 15300 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15301 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15302 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15303 SystemClock.uptimeMillis()); 15304 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15305 // Changed to/from cached state, so apps after it in the LRU 15306 // list may also be changed. 15307 updateOomAdjLocked(); 15308 } 15309 return success; 15310 } 15311 15312 final void updateOomAdjLocked() { 15313 final ActivityRecord TOP_ACT = resumedAppLocked(); 15314 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15315 final long now = SystemClock.uptimeMillis(); 15316 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15317 final int N = mLruProcesses.size(); 15318 15319 if (false) { 15320 RuntimeException e = new RuntimeException(); 15321 e.fillInStackTrace(); 15322 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15323 } 15324 15325 mAdjSeq++; 15326 mNewNumServiceProcs = 0; 15327 mNewNumAServiceProcs = 0; 15328 15329 final int emptyProcessLimit; 15330 final int cachedProcessLimit; 15331 if (mProcessLimit <= 0) { 15332 emptyProcessLimit = cachedProcessLimit = 0; 15333 } else if (mProcessLimit == 1) { 15334 emptyProcessLimit = 1; 15335 cachedProcessLimit = 0; 15336 } else { 15337 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15338 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15339 } 15340 15341 // Let's determine how many processes we have running vs. 15342 // how many slots we have for background processes; we may want 15343 // to put multiple processes in a slot of there are enough of 15344 // them. 15345 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15346 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15347 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15348 if (numEmptyProcs > cachedProcessLimit) { 15349 // If there are more empty processes than our limit on cached 15350 // processes, then use the cached process limit for the factor. 15351 // This ensures that the really old empty processes get pushed 15352 // down to the bottom, so if we are running low on memory we will 15353 // have a better chance at keeping around more cached processes 15354 // instead of a gazillion empty processes. 15355 numEmptyProcs = cachedProcessLimit; 15356 } 15357 int emptyFactor = numEmptyProcs/numSlots; 15358 if (emptyFactor < 1) emptyFactor = 1; 15359 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15360 if (cachedFactor < 1) cachedFactor = 1; 15361 int stepCached = 0; 15362 int stepEmpty = 0; 15363 int numCached = 0; 15364 int numEmpty = 0; 15365 int numTrimming = 0; 15366 15367 mNumNonCachedProcs = 0; 15368 mNumCachedHiddenProcs = 0; 15369 15370 // First update the OOM adjustment for each of the 15371 // application processes based on their current state. 15372 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15373 int nextCachedAdj = curCachedAdj+1; 15374 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15375 int nextEmptyAdj = curEmptyAdj+2; 15376 for (int i=N-1; i>=0; i--) { 15377 ProcessRecord app = mLruProcesses.get(i); 15378 if (!app.killedByAm && app.thread != null) { 15379 app.procStateChanged = false; 15380 final boolean wasKeeping = app.keeping; 15381 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15382 15383 // If we haven't yet assigned the final cached adj 15384 // to the process, do that now. 15385 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15386 switch (app.curProcState) { 15387 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15388 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15389 // This process is a cached process holding activities... 15390 // assign it the next cached value for that type, and then 15391 // step that cached level. 15392 app.curRawAdj = curCachedAdj; 15393 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15394 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15395 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15396 + ")"); 15397 if (curCachedAdj != nextCachedAdj) { 15398 stepCached++; 15399 if (stepCached >= cachedFactor) { 15400 stepCached = 0; 15401 curCachedAdj = nextCachedAdj; 15402 nextCachedAdj += 2; 15403 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15404 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15405 } 15406 } 15407 } 15408 break; 15409 default: 15410 // For everything else, assign next empty cached process 15411 // level and bump that up. Note that this means that 15412 // long-running services that have dropped down to the 15413 // cached level will be treated as empty (since their process 15414 // state is still as a service), which is what we want. 15415 app.curRawAdj = curEmptyAdj; 15416 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15417 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15418 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15419 + ")"); 15420 if (curEmptyAdj != nextEmptyAdj) { 15421 stepEmpty++; 15422 if (stepEmpty >= emptyFactor) { 15423 stepEmpty = 0; 15424 curEmptyAdj = nextEmptyAdj; 15425 nextEmptyAdj += 2; 15426 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15427 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15428 } 15429 } 15430 } 15431 break; 15432 } 15433 } 15434 15435 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15436 15437 // Count the number of process types. 15438 switch (app.curProcState) { 15439 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15440 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15441 mNumCachedHiddenProcs++; 15442 numCached++; 15443 if (numCached > cachedProcessLimit) { 15444 killUnneededProcessLocked(app, "cached #" + numCached); 15445 } 15446 break; 15447 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15448 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15449 && app.lastActivityTime < oldTime) { 15450 killUnneededProcessLocked(app, "empty for " 15451 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15452 / 1000) + "s"); 15453 } else { 15454 numEmpty++; 15455 if (numEmpty > emptyProcessLimit) { 15456 killUnneededProcessLocked(app, "empty #" + numEmpty); 15457 } 15458 } 15459 break; 15460 default: 15461 mNumNonCachedProcs++; 15462 break; 15463 } 15464 15465 if (app.isolated && app.services.size() <= 0) { 15466 // If this is an isolated process, and there are no 15467 // services running in it, then the process is no longer 15468 // needed. We agressively kill these because we can by 15469 // definition not re-use the same process again, and it is 15470 // good to avoid having whatever code was running in them 15471 // left sitting around after no longer needed. 15472 killUnneededProcessLocked(app, "isolated not needed"); 15473 } 15474 15475 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15476 && !app.killedByAm) { 15477 numTrimming++; 15478 } 15479 } 15480 } 15481 15482 mNumServiceProcs = mNewNumServiceProcs; 15483 15484 // Now determine the memory trimming level of background processes. 15485 // Unfortunately we need to start at the back of the list to do this 15486 // properly. We only do this if the number of background apps we 15487 // are managing to keep around is less than half the maximum we desire; 15488 // if we are keeping a good number around, we'll let them use whatever 15489 // memory they want. 15490 final int numCachedAndEmpty = numCached + numEmpty; 15491 int memFactor; 15492 if (numCached <= ProcessList.TRIM_CACHED_APPS 15493 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15494 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15495 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15496 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15497 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15498 } else { 15499 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15500 } 15501 } else { 15502 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15503 } 15504 // We always allow the memory level to go up (better). We only allow it to go 15505 // down if we are in a state where that is allowed, *and* the total number of processes 15506 // has gone down since last time. 15507 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15508 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15509 + " last=" + mLastNumProcesses); 15510 if (memFactor > mLastMemoryLevel) { 15511 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15512 memFactor = mLastMemoryLevel; 15513 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15514 } 15515 } 15516 mLastMemoryLevel = memFactor; 15517 mLastNumProcesses = mLruProcesses.size(); 15518 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15519 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15520 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15521 if (mLowRamStartTime == 0) { 15522 mLowRamStartTime = now; 15523 } 15524 int step = 0; 15525 int fgTrimLevel; 15526 switch (memFactor) { 15527 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15528 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15529 break; 15530 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15531 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15532 break; 15533 default: 15534 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15535 break; 15536 } 15537 int factor = numTrimming/3; 15538 int minFactor = 2; 15539 if (mHomeProcess != null) minFactor++; 15540 if (mPreviousProcess != null) minFactor++; 15541 if (factor < minFactor) factor = minFactor; 15542 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15543 for (int i=N-1; i>=0; i--) { 15544 ProcessRecord app = mLruProcesses.get(i); 15545 if (allChanged || app.procStateChanged) { 15546 setProcessTrackerState(app, trackerMemFactor, now); 15547 app.procStateChanged = false; 15548 } 15549 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15550 && !app.killedByAm) { 15551 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15552 try { 15553 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15554 "Trimming memory of " + app.processName 15555 + " to " + curLevel); 15556 app.thread.scheduleTrimMemory(curLevel); 15557 } catch (RemoteException e) { 15558 } 15559 if (false) { 15560 // For now we won't do this; our memory trimming seems 15561 // to be good enough at this point that destroying 15562 // activities causes more harm than good. 15563 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15564 && app != mHomeProcess && app != mPreviousProcess) { 15565 // Need to do this on its own message because the stack may not 15566 // be in a consistent state at this point. 15567 // For these apps we will also finish their activities 15568 // to help them free memory. 15569 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15570 } 15571 } 15572 } 15573 app.trimMemoryLevel = curLevel; 15574 step++; 15575 if (step >= factor) { 15576 step = 0; 15577 switch (curLevel) { 15578 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15579 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15580 break; 15581 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15582 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15583 break; 15584 } 15585 } 15586 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15587 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15588 && app.thread != null) { 15589 try { 15590 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15591 "Trimming memory of heavy-weight " + app.processName 15592 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15593 app.thread.scheduleTrimMemory( 15594 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15595 } catch (RemoteException e) { 15596 } 15597 } 15598 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15599 } else { 15600 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15601 || app.systemNoUi) && app.pendingUiClean) { 15602 // If this application is now in the background and it 15603 // had done UI, then give it the special trim level to 15604 // have it free UI resources. 15605 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15606 if (app.trimMemoryLevel < level && app.thread != null) { 15607 try { 15608 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15609 "Trimming memory of bg-ui " + app.processName 15610 + " to " + level); 15611 app.thread.scheduleTrimMemory(level); 15612 } catch (RemoteException e) { 15613 } 15614 } 15615 app.pendingUiClean = false; 15616 } 15617 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15618 try { 15619 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15620 "Trimming memory of fg " + app.processName 15621 + " to " + fgTrimLevel); 15622 app.thread.scheduleTrimMemory(fgTrimLevel); 15623 } catch (RemoteException e) { 15624 } 15625 } 15626 app.trimMemoryLevel = fgTrimLevel; 15627 } 15628 } 15629 } else { 15630 if (mLowRamStartTime != 0) { 15631 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15632 mLowRamStartTime = 0; 15633 } 15634 for (int i=N-1; i>=0; i--) { 15635 ProcessRecord app = mLruProcesses.get(i); 15636 if (allChanged || app.procStateChanged) { 15637 setProcessTrackerState(app, trackerMemFactor, now); 15638 app.procStateChanged = false; 15639 } 15640 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15641 || app.systemNoUi) && app.pendingUiClean) { 15642 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15643 && app.thread != null) { 15644 try { 15645 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15646 "Trimming memory of ui hidden " + app.processName 15647 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15648 app.thread.scheduleTrimMemory( 15649 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15650 } catch (RemoteException e) { 15651 } 15652 } 15653 app.pendingUiClean = false; 15654 } 15655 app.trimMemoryLevel = 0; 15656 } 15657 } 15658 15659 if (mAlwaysFinishActivities) { 15660 // Need to do this on its own message because the stack may not 15661 // be in a consistent state at this point. 15662 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15663 } 15664 15665 if (allChanged) { 15666 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15667 } 15668 15669 if (mProcessStats.shouldWriteNowLocked(now)) { 15670 mHandler.post(new Runnable() { 15671 @Override public void run() { 15672 synchronized (ActivityManagerService.this) { 15673 mProcessStats.writeStateAsyncLocked(); 15674 } 15675 } 15676 }); 15677 } 15678 15679 if (DEBUG_OOM_ADJ) { 15680 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15681 } 15682 } 15683 15684 final void trimApplications() { 15685 synchronized (this) { 15686 int i; 15687 15688 // First remove any unused application processes whose package 15689 // has been removed. 15690 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15691 final ProcessRecord app = mRemovedProcesses.get(i); 15692 if (app.activities.size() == 0 15693 && app.curReceiver == null && app.services.size() == 0) { 15694 Slog.i( 15695 TAG, "Exiting empty application process " 15696 + app.processName + " (" 15697 + (app.thread != null ? app.thread.asBinder() : null) 15698 + ")\n"); 15699 if (app.pid > 0 && app.pid != MY_PID) { 15700 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 15701 app.processName, app.setAdj, "empty"); 15702 app.killedByAm = true; 15703 Process.killProcessQuiet(app.pid); 15704 } else { 15705 try { 15706 app.thread.scheduleExit(); 15707 } catch (Exception e) { 15708 // Ignore exceptions. 15709 } 15710 } 15711 cleanUpApplicationRecordLocked(app, false, true, -1); 15712 mRemovedProcesses.remove(i); 15713 15714 if (app.persistent) { 15715 if (app.persistent) { 15716 addAppLocked(app.info, false); 15717 } 15718 } 15719 } 15720 } 15721 15722 // Now update the oom adj for all processes. 15723 updateOomAdjLocked(); 15724 } 15725 } 15726 15727 /** This method sends the specified signal to each of the persistent apps */ 15728 public void signalPersistentProcesses(int sig) throws RemoteException { 15729 if (sig != Process.SIGNAL_USR1) { 15730 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 15731 } 15732 15733 synchronized (this) { 15734 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 15735 != PackageManager.PERMISSION_GRANTED) { 15736 throw new SecurityException("Requires permission " 15737 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 15738 } 15739 15740 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15741 ProcessRecord r = mLruProcesses.get(i); 15742 if (r.thread != null && r.persistent) { 15743 Process.sendSignal(r.pid, sig); 15744 } 15745 } 15746 } 15747 } 15748 15749 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 15750 if (proc == null || proc == mProfileProc) { 15751 proc = mProfileProc; 15752 path = mProfileFile; 15753 profileType = mProfileType; 15754 clearProfilerLocked(); 15755 } 15756 if (proc == null) { 15757 return; 15758 } 15759 try { 15760 proc.thread.profilerControl(false, path, null, profileType); 15761 } catch (RemoteException e) { 15762 throw new IllegalStateException("Process disappeared"); 15763 } 15764 } 15765 15766 private void clearProfilerLocked() { 15767 if (mProfileFd != null) { 15768 try { 15769 mProfileFd.close(); 15770 } catch (IOException e) { 15771 } 15772 } 15773 mProfileApp = null; 15774 mProfileProc = null; 15775 mProfileFile = null; 15776 mProfileType = 0; 15777 mAutoStopProfiler = false; 15778 } 15779 15780 public boolean profileControl(String process, int userId, boolean start, 15781 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 15782 15783 try { 15784 synchronized (this) { 15785 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15786 // its own permission. 15787 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15788 != PackageManager.PERMISSION_GRANTED) { 15789 throw new SecurityException("Requires permission " 15790 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15791 } 15792 15793 if (start && fd == null) { 15794 throw new IllegalArgumentException("null fd"); 15795 } 15796 15797 ProcessRecord proc = null; 15798 if (process != null) { 15799 proc = findProcessLocked(process, userId, "profileControl"); 15800 } 15801 15802 if (start && (proc == null || proc.thread == null)) { 15803 throw new IllegalArgumentException("Unknown process: " + process); 15804 } 15805 15806 if (start) { 15807 stopProfilerLocked(null, null, 0); 15808 setProfileApp(proc.info, proc.processName, path, fd, false); 15809 mProfileProc = proc; 15810 mProfileType = profileType; 15811 try { 15812 fd = fd.dup(); 15813 } catch (IOException e) { 15814 fd = null; 15815 } 15816 proc.thread.profilerControl(start, path, fd, profileType); 15817 fd = null; 15818 mProfileFd = null; 15819 } else { 15820 stopProfilerLocked(proc, path, profileType); 15821 if (fd != null) { 15822 try { 15823 fd.close(); 15824 } catch (IOException e) { 15825 } 15826 } 15827 } 15828 15829 return true; 15830 } 15831 } catch (RemoteException e) { 15832 throw new IllegalStateException("Process disappeared"); 15833 } finally { 15834 if (fd != null) { 15835 try { 15836 fd.close(); 15837 } catch (IOException e) { 15838 } 15839 } 15840 } 15841 } 15842 15843 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 15844 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15845 userId, true, true, callName, null); 15846 ProcessRecord proc = null; 15847 try { 15848 int pid = Integer.parseInt(process); 15849 synchronized (mPidsSelfLocked) { 15850 proc = mPidsSelfLocked.get(pid); 15851 } 15852 } catch (NumberFormatException e) { 15853 } 15854 15855 if (proc == null) { 15856 ArrayMap<String, SparseArray<ProcessRecord>> all 15857 = mProcessNames.getMap(); 15858 SparseArray<ProcessRecord> procs = all.get(process); 15859 if (procs != null && procs.size() > 0) { 15860 proc = procs.valueAt(0); 15861 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 15862 for (int i=1; i<procs.size(); i++) { 15863 ProcessRecord thisProc = procs.valueAt(i); 15864 if (thisProc.userId == userId) { 15865 proc = thisProc; 15866 break; 15867 } 15868 } 15869 } 15870 } 15871 } 15872 15873 return proc; 15874 } 15875 15876 public boolean dumpHeap(String process, int userId, boolean managed, 15877 String path, ParcelFileDescriptor fd) throws RemoteException { 15878 15879 try { 15880 synchronized (this) { 15881 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15882 // its own permission (same as profileControl). 15883 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15884 != PackageManager.PERMISSION_GRANTED) { 15885 throw new SecurityException("Requires permission " 15886 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15887 } 15888 15889 if (fd == null) { 15890 throw new IllegalArgumentException("null fd"); 15891 } 15892 15893 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 15894 if (proc == null || proc.thread == null) { 15895 throw new IllegalArgumentException("Unknown process: " + process); 15896 } 15897 15898 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 15899 if (!isDebuggable) { 15900 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 15901 throw new SecurityException("Process not debuggable: " + proc); 15902 } 15903 } 15904 15905 proc.thread.dumpHeap(managed, path, fd); 15906 fd = null; 15907 return true; 15908 } 15909 } catch (RemoteException e) { 15910 throw new IllegalStateException("Process disappeared"); 15911 } finally { 15912 if (fd != null) { 15913 try { 15914 fd.close(); 15915 } catch (IOException e) { 15916 } 15917 } 15918 } 15919 } 15920 15921 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 15922 public void monitor() { 15923 synchronized (this) { } 15924 } 15925 15926 void onCoreSettingsChange(Bundle settings) { 15927 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 15928 ProcessRecord processRecord = mLruProcesses.get(i); 15929 try { 15930 if (processRecord.thread != null) { 15931 processRecord.thread.setCoreSettings(settings); 15932 } 15933 } catch (RemoteException re) { 15934 /* ignore */ 15935 } 15936 } 15937 } 15938 15939 // Multi-user methods 15940 15941 @Override 15942 public boolean switchUser(final int userId) { 15943 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 15944 != PackageManager.PERMISSION_GRANTED) { 15945 String msg = "Permission Denial: switchUser() from pid=" 15946 + Binder.getCallingPid() 15947 + ", uid=" + Binder.getCallingUid() 15948 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 15949 Slog.w(TAG, msg); 15950 throw new SecurityException(msg); 15951 } 15952 15953 final long ident = Binder.clearCallingIdentity(); 15954 try { 15955 synchronized (this) { 15956 final int oldUserId = mCurrentUserId; 15957 if (oldUserId == userId) { 15958 return true; 15959 } 15960 15961 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 15962 if (userInfo == null) { 15963 Slog.w(TAG, "No user info for user #" + userId); 15964 return false; 15965 } 15966 15967 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 15968 R.anim.screen_user_enter); 15969 15970 boolean needStart = false; 15971 15972 // If the user we are switching to is not currently started, then 15973 // we need to start it now. 15974 if (mStartedUsers.get(userId) == null) { 15975 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 15976 updateStartedUserArrayLocked(); 15977 needStart = true; 15978 } 15979 15980 mCurrentUserId = userId; 15981 final Integer userIdInt = Integer.valueOf(userId); 15982 mUserLru.remove(userIdInt); 15983 mUserLru.add(userIdInt); 15984 15985 mWindowManager.setCurrentUser(userId); 15986 15987 // Once the internal notion of the active user has switched, we lock the device 15988 // with the option to show the user switcher on the keyguard. 15989 mWindowManager.lockNow(null); 15990 15991 final UserStartedState uss = mStartedUsers.get(userId); 15992 15993 // Make sure user is in the started state. If it is currently 15994 // stopping, we need to knock that off. 15995 if (uss.mState == UserStartedState.STATE_STOPPING) { 15996 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 15997 // so we can just fairly silently bring the user back from 15998 // the almost-dead. 15999 uss.mState = UserStartedState.STATE_RUNNING; 16000 updateStartedUserArrayLocked(); 16001 needStart = true; 16002 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16003 // This means ACTION_SHUTDOWN has been sent, so we will 16004 // need to treat this as a new boot of the user. 16005 uss.mState = UserStartedState.STATE_BOOTING; 16006 updateStartedUserArrayLocked(); 16007 needStart = true; 16008 } 16009 16010 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16011 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16012 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16013 oldUserId, userId, uss)); 16014 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16015 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16016 if (needStart) { 16017 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16018 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16019 | Intent.FLAG_RECEIVER_FOREGROUND); 16020 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16021 broadcastIntentLocked(null, null, intent, 16022 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16023 false, false, MY_PID, Process.SYSTEM_UID, userId); 16024 } 16025 16026 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16027 if (userId != 0) { 16028 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16029 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16030 broadcastIntentLocked(null, null, intent, null, 16031 new IIntentReceiver.Stub() { 16032 public void performReceive(Intent intent, int resultCode, 16033 String data, Bundle extras, boolean ordered, 16034 boolean sticky, int sendingUser) { 16035 userInitialized(uss, userId); 16036 } 16037 }, 0, null, null, null, AppOpsManager.OP_NONE, 16038 true, false, MY_PID, Process.SYSTEM_UID, 16039 userId); 16040 uss.initializing = true; 16041 } else { 16042 getUserManagerLocked().makeInitialized(userInfo.id); 16043 } 16044 } 16045 16046 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16047 if (homeInFront) { 16048 startHomeActivityLocked(userId); 16049 } else { 16050 mStackSupervisor.resumeTopActivitiesLocked(); 16051 } 16052 16053 EventLogTags.writeAmSwitchUser(userId); 16054 getUserManagerLocked().userForeground(userId); 16055 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16056 if (needStart) { 16057 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16058 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16059 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16060 broadcastIntentLocked(null, null, intent, 16061 null, new IIntentReceiver.Stub() { 16062 @Override 16063 public void performReceive(Intent intent, int resultCode, String data, 16064 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16065 throws RemoteException { 16066 } 16067 }, 0, null, null, 16068 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16069 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16070 } 16071 } 16072 } finally { 16073 Binder.restoreCallingIdentity(ident); 16074 } 16075 16076 return true; 16077 } 16078 16079 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16080 long ident = Binder.clearCallingIdentity(); 16081 try { 16082 Intent intent; 16083 if (oldUserId >= 0) { 16084 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16085 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16086 | Intent.FLAG_RECEIVER_FOREGROUND); 16087 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16088 broadcastIntentLocked(null, null, intent, 16089 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16090 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16091 } 16092 if (newUserId >= 0) { 16093 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16094 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16095 | Intent.FLAG_RECEIVER_FOREGROUND); 16096 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16097 broadcastIntentLocked(null, null, intent, 16098 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16099 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16100 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16101 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16102 | Intent.FLAG_RECEIVER_FOREGROUND); 16103 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16104 broadcastIntentLocked(null, null, intent, 16105 null, null, 0, null, null, 16106 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16107 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16108 } 16109 } finally { 16110 Binder.restoreCallingIdentity(ident); 16111 } 16112 } 16113 16114 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16115 final int newUserId) { 16116 final int N = mUserSwitchObservers.beginBroadcast(); 16117 if (N > 0) { 16118 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16119 int mCount = 0; 16120 @Override 16121 public void sendResult(Bundle data) throws RemoteException { 16122 synchronized (ActivityManagerService.this) { 16123 if (mCurUserSwitchCallback == this) { 16124 mCount++; 16125 if (mCount == N) { 16126 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16127 } 16128 } 16129 } 16130 } 16131 }; 16132 synchronized (this) { 16133 uss.switching = true; 16134 mCurUserSwitchCallback = callback; 16135 } 16136 for (int i=0; i<N; i++) { 16137 try { 16138 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16139 newUserId, callback); 16140 } catch (RemoteException e) { 16141 } 16142 } 16143 } else { 16144 synchronized (this) { 16145 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16146 } 16147 } 16148 mUserSwitchObservers.finishBroadcast(); 16149 } 16150 16151 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16152 synchronized (this) { 16153 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16154 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16155 } 16156 } 16157 16158 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16159 mCurUserSwitchCallback = null; 16160 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16161 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16162 oldUserId, newUserId, uss)); 16163 } 16164 16165 void userInitialized(UserStartedState uss, int newUserId) { 16166 completeSwitchAndInitalize(uss, newUserId, true, false); 16167 } 16168 16169 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16170 completeSwitchAndInitalize(uss, newUserId, false, true); 16171 } 16172 16173 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16174 boolean clearInitializing, boolean clearSwitching) { 16175 boolean unfrozen = false; 16176 synchronized (this) { 16177 if (clearInitializing) { 16178 uss.initializing = false; 16179 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16180 } 16181 if (clearSwitching) { 16182 uss.switching = false; 16183 } 16184 if (!uss.switching && !uss.initializing) { 16185 mWindowManager.stopFreezingScreen(); 16186 unfrozen = true; 16187 } 16188 } 16189 if (unfrozen) { 16190 final int N = mUserSwitchObservers.beginBroadcast(); 16191 for (int i=0; i<N; i++) { 16192 try { 16193 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16194 } catch (RemoteException e) { 16195 } 16196 } 16197 mUserSwitchObservers.finishBroadcast(); 16198 } 16199 } 16200 16201 void finishUserSwitch(UserStartedState uss) { 16202 synchronized (this) { 16203 if (uss.mState == UserStartedState.STATE_BOOTING 16204 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16205 uss.mState = UserStartedState.STATE_RUNNING; 16206 final int userId = uss.mHandle.getIdentifier(); 16207 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16208 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16209 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16210 broadcastIntentLocked(null, null, intent, 16211 null, null, 0, null, null, 16212 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16213 true, false, MY_PID, Process.SYSTEM_UID, userId); 16214 } 16215 int num = mUserLru.size(); 16216 int i = 0; 16217 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16218 Integer oldUserId = mUserLru.get(i); 16219 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16220 if (oldUss == null) { 16221 // Shouldn't happen, but be sane if it does. 16222 mUserLru.remove(i); 16223 num--; 16224 continue; 16225 } 16226 if (oldUss.mState == UserStartedState.STATE_STOPPING 16227 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16228 // This user is already stopping, doesn't count. 16229 num--; 16230 i++; 16231 continue; 16232 } 16233 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16234 // Owner and current can't be stopped, but count as running. 16235 i++; 16236 continue; 16237 } 16238 // This is a user to be stopped. 16239 stopUserLocked(oldUserId, null); 16240 num--; 16241 i++; 16242 } 16243 } 16244 } 16245 16246 @Override 16247 public int stopUser(final int userId, final IStopUserCallback callback) { 16248 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16249 != PackageManager.PERMISSION_GRANTED) { 16250 String msg = "Permission Denial: switchUser() from pid=" 16251 + Binder.getCallingPid() 16252 + ", uid=" + Binder.getCallingUid() 16253 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16254 Slog.w(TAG, msg); 16255 throw new SecurityException(msg); 16256 } 16257 if (userId <= 0) { 16258 throw new IllegalArgumentException("Can't stop primary user " + userId); 16259 } 16260 synchronized (this) { 16261 return stopUserLocked(userId, callback); 16262 } 16263 } 16264 16265 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16266 if (mCurrentUserId == userId) { 16267 return ActivityManager.USER_OP_IS_CURRENT; 16268 } 16269 16270 final UserStartedState uss = mStartedUsers.get(userId); 16271 if (uss == null) { 16272 // User is not started, nothing to do... but we do need to 16273 // callback if requested. 16274 if (callback != null) { 16275 mHandler.post(new Runnable() { 16276 @Override 16277 public void run() { 16278 try { 16279 callback.userStopped(userId); 16280 } catch (RemoteException e) { 16281 } 16282 } 16283 }); 16284 } 16285 return ActivityManager.USER_OP_SUCCESS; 16286 } 16287 16288 if (callback != null) { 16289 uss.mStopCallbacks.add(callback); 16290 } 16291 16292 if (uss.mState != UserStartedState.STATE_STOPPING 16293 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16294 uss.mState = UserStartedState.STATE_STOPPING; 16295 updateStartedUserArrayLocked(); 16296 16297 long ident = Binder.clearCallingIdentity(); 16298 try { 16299 // We are going to broadcast ACTION_USER_STOPPING and then 16300 // once that is done send a final ACTION_SHUTDOWN and then 16301 // stop the user. 16302 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16303 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16304 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16305 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16306 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16307 // This is the result receiver for the final shutdown broadcast. 16308 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16309 @Override 16310 public void performReceive(Intent intent, int resultCode, String data, 16311 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16312 finishUserStop(uss); 16313 } 16314 }; 16315 // This is the result receiver for the initial stopping broadcast. 16316 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16317 @Override 16318 public void performReceive(Intent intent, int resultCode, String data, 16319 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16320 // On to the next. 16321 synchronized (ActivityManagerService.this) { 16322 if (uss.mState != UserStartedState.STATE_STOPPING) { 16323 // Whoops, we are being started back up. Abort, abort! 16324 return; 16325 } 16326 uss.mState = UserStartedState.STATE_SHUTDOWN; 16327 } 16328 broadcastIntentLocked(null, null, shutdownIntent, 16329 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16330 true, false, MY_PID, Process.SYSTEM_UID, userId); 16331 } 16332 }; 16333 // Kick things off. 16334 broadcastIntentLocked(null, null, stoppingIntent, 16335 null, stoppingReceiver, 0, null, null, 16336 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16337 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16338 } finally { 16339 Binder.restoreCallingIdentity(ident); 16340 } 16341 } 16342 16343 return ActivityManager.USER_OP_SUCCESS; 16344 } 16345 16346 void finishUserStop(UserStartedState uss) { 16347 final int userId = uss.mHandle.getIdentifier(); 16348 boolean stopped; 16349 ArrayList<IStopUserCallback> callbacks; 16350 synchronized (this) { 16351 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16352 if (mStartedUsers.get(userId) != uss) { 16353 stopped = false; 16354 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16355 stopped = false; 16356 } else { 16357 stopped = true; 16358 // User can no longer run. 16359 mStartedUsers.remove(userId); 16360 mUserLru.remove(Integer.valueOf(userId)); 16361 updateStartedUserArrayLocked(); 16362 16363 // Clean up all state and processes associated with the user. 16364 // Kill all the processes for the user. 16365 forceStopUserLocked(userId, "finish user"); 16366 } 16367 } 16368 16369 for (int i=0; i<callbacks.size(); i++) { 16370 try { 16371 if (stopped) callbacks.get(i).userStopped(userId); 16372 else callbacks.get(i).userStopAborted(userId); 16373 } catch (RemoteException e) { 16374 } 16375 } 16376 16377 mStackSupervisor.removeUserLocked(userId); 16378 } 16379 16380 @Override 16381 public UserInfo getCurrentUser() { 16382 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16383 != PackageManager.PERMISSION_GRANTED) && ( 16384 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16385 != PackageManager.PERMISSION_GRANTED)) { 16386 String msg = "Permission Denial: getCurrentUser() from pid=" 16387 + Binder.getCallingPid() 16388 + ", uid=" + Binder.getCallingUid() 16389 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16390 Slog.w(TAG, msg); 16391 throw new SecurityException(msg); 16392 } 16393 synchronized (this) { 16394 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16395 } 16396 } 16397 16398 int getCurrentUserIdLocked() { 16399 return mCurrentUserId; 16400 } 16401 16402 @Override 16403 public boolean isUserRunning(int userId, boolean orStopped) { 16404 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16405 != PackageManager.PERMISSION_GRANTED) { 16406 String msg = "Permission Denial: isUserRunning() from pid=" 16407 + Binder.getCallingPid() 16408 + ", uid=" + Binder.getCallingUid() 16409 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16410 Slog.w(TAG, msg); 16411 throw new SecurityException(msg); 16412 } 16413 synchronized (this) { 16414 return isUserRunningLocked(userId, orStopped); 16415 } 16416 } 16417 16418 boolean isUserRunningLocked(int userId, boolean orStopped) { 16419 UserStartedState state = mStartedUsers.get(userId); 16420 if (state == null) { 16421 return false; 16422 } 16423 if (orStopped) { 16424 return true; 16425 } 16426 return state.mState != UserStartedState.STATE_STOPPING 16427 && state.mState != UserStartedState.STATE_SHUTDOWN; 16428 } 16429 16430 @Override 16431 public int[] getRunningUserIds() { 16432 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16433 != PackageManager.PERMISSION_GRANTED) { 16434 String msg = "Permission Denial: isUserRunning() from pid=" 16435 + Binder.getCallingPid() 16436 + ", uid=" + Binder.getCallingUid() 16437 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16438 Slog.w(TAG, msg); 16439 throw new SecurityException(msg); 16440 } 16441 synchronized (this) { 16442 return mStartedUserArray; 16443 } 16444 } 16445 16446 private void updateStartedUserArrayLocked() { 16447 int num = 0; 16448 for (int i=0; i<mStartedUsers.size(); i++) { 16449 UserStartedState uss = mStartedUsers.valueAt(i); 16450 // This list does not include stopping users. 16451 if (uss.mState != UserStartedState.STATE_STOPPING 16452 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16453 num++; 16454 } 16455 } 16456 mStartedUserArray = new int[num]; 16457 num = 0; 16458 for (int i=0; i<mStartedUsers.size(); i++) { 16459 UserStartedState uss = mStartedUsers.valueAt(i); 16460 if (uss.mState != UserStartedState.STATE_STOPPING 16461 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16462 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16463 num++; 16464 } 16465 } 16466 } 16467 16468 @Override 16469 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16470 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16471 != PackageManager.PERMISSION_GRANTED) { 16472 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16473 + Binder.getCallingPid() 16474 + ", uid=" + Binder.getCallingUid() 16475 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16476 Slog.w(TAG, msg); 16477 throw new SecurityException(msg); 16478 } 16479 16480 mUserSwitchObservers.register(observer); 16481 } 16482 16483 @Override 16484 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16485 mUserSwitchObservers.unregister(observer); 16486 } 16487 16488 private boolean userExists(int userId) { 16489 if (userId == 0) { 16490 return true; 16491 } 16492 UserManagerService ums = getUserManagerLocked(); 16493 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16494 } 16495 16496 int[] getUsersLocked() { 16497 UserManagerService ums = getUserManagerLocked(); 16498 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16499 } 16500 16501 UserManagerService getUserManagerLocked() { 16502 if (mUserManager == null) { 16503 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16504 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16505 } 16506 return mUserManager; 16507 } 16508 16509 private int applyUserId(int uid, int userId) { 16510 return UserHandle.getUid(userId, uid); 16511 } 16512 16513 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16514 if (info == null) return null; 16515 ApplicationInfo newInfo = new ApplicationInfo(info); 16516 newInfo.uid = applyUserId(info.uid, userId); 16517 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16518 + info.packageName; 16519 return newInfo; 16520 } 16521 16522 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16523 if (aInfo == null 16524 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16525 return aInfo; 16526 } 16527 16528 ActivityInfo info = new ActivityInfo(aInfo); 16529 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16530 return info; 16531 } 16532 16533 private final class LocalService extends ActivityManagerInternal { 16534 @Override 16535 public void goingToSleep() { 16536 ActivityManagerService.this.goingToSleep(); 16537 } 16538 16539 @Override 16540 public void wakingUp() { 16541 ActivityManagerService.this.wakingUp(); 16542 } 16543 } 16544} 16545