ActivityManagerService.java revision 08488bf3fe6f4b1fadf59821feaf07b4c2ae52ae
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20import static com.android.internal.util.XmlUtils.readIntAttribute; 21import static com.android.internal.util.XmlUtils.readLongAttribute; 22import static com.android.internal.util.XmlUtils.writeIntAttribute; 23import static com.android.internal.util.XmlUtils.writeLongAttribute; 24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 26import static org.xmlpull.v1.XmlPullParser.START_TAG; 27 28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 29 30import android.app.AppOpsManager; 31import android.app.IActivityContainer; 32import android.app.IActivityContainerCallback; 33import android.appwidget.AppWidgetManager; 34import android.graphics.Rect; 35import android.os.BatteryStats; 36import android.util.ArrayMap; 37import com.android.internal.R; 38import com.android.internal.annotations.GuardedBy; 39import com.android.internal.app.IAppOpsService; 40import com.android.internal.app.ProcessMap; 41import com.android.internal.app.ProcessStats; 42import com.android.internal.os.BackgroundThread; 43import com.android.internal.os.BatteryStatsImpl; 44import com.android.internal.os.ProcessCpuTracker; 45import com.android.internal.os.TransferPipe; 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.ServiceThread; 54import com.android.server.SystemService; 55import com.android.server.Watchdog; 56import com.android.server.am.ActivityStack.ActivityState; 57import com.android.server.firewall.IntentFirewall; 58import com.android.server.pm.UserManagerService; 59import com.android.server.wm.AppTransition; 60import com.android.server.wm.WindowManagerService; 61import com.google.android.collect.Lists; 62import com.google.android.collect.Maps; 63 64import dalvik.system.Zygote; 65 66import libcore.io.IoUtils; 67 68import org.xmlpull.v1.XmlPullParser; 69import org.xmlpull.v1.XmlPullParserException; 70import org.xmlpull.v1.XmlSerializer; 71 72import android.app.Activity; 73import android.app.ActivityManager; 74import android.app.ActivityManager.RunningTaskInfo; 75import android.app.ActivityManager.StackInfo; 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 boolean mStartRunning = false; 803 ComponentName mTopComponent; 804 String mTopAction; 805 String mTopData; 806 boolean mProcessesReady = false; 807 boolean mSystemReady = false; 808 boolean mBooting = false; 809 boolean mWaitingUpdate = false; 810 boolean mDidUpdate = false; 811 boolean mOnBattery = false; 812 boolean mLaunchWarningShown = false; 813 814 Context mContext; 815 816 int mFactoryTest; 817 818 boolean mCheckedForSetup; 819 820 /** 821 * The time at which we will allow normal application switches again, 822 * after a call to {@link #stopAppSwitches()}. 823 */ 824 long mAppSwitchesAllowedTime; 825 826 /** 827 * This is set to true after the first switch after mAppSwitchesAllowedTime 828 * is set; any switches after that will clear the time. 829 */ 830 boolean mDidAppSwitch; 831 832 /** 833 * Last time (in realtime) at which we checked for power usage. 834 */ 835 long mLastPowerCheckRealtime; 836 837 /** 838 * Last time (in uptime) at which we checked for power usage. 839 */ 840 long mLastPowerCheckUptime; 841 842 /** 843 * Set while we are wanting to sleep, to prevent any 844 * activities from being started/resumed. 845 */ 846 boolean mSleeping = false; 847 848 /** 849 * State of external calls telling us if the device is asleep. 850 */ 851 boolean mWentToSleep = false; 852 853 /** 854 * State of external call telling us if the lock screen is shown. 855 */ 856 boolean mLockScreenShown = false; 857 858 /** 859 * Set if we are shutting down the system, similar to sleeping. 860 */ 861 boolean mShuttingDown = false; 862 863 /** 864 * Current sequence id for oom_adj computation traversal. 865 */ 866 int mAdjSeq = 0; 867 868 /** 869 * Current sequence id for process LRU updating. 870 */ 871 int mLruSeq = 0; 872 873 /** 874 * Keep track of the non-cached/empty process we last found, to help 875 * determine how to distribute cached/empty processes next time. 876 */ 877 int mNumNonCachedProcs = 0; 878 879 /** 880 * Keep track of the number of cached hidden procs, to balance oom adj 881 * distribution between those and empty procs. 882 */ 883 int mNumCachedHiddenProcs = 0; 884 885 /** 886 * Keep track of the number of service processes we last found, to 887 * determine on the next iteration which should be B services. 888 */ 889 int mNumServiceProcs = 0; 890 int mNewNumAServiceProcs = 0; 891 int mNewNumServiceProcs = 0; 892 893 /** 894 * Allow the current computed overall memory level of the system to go down? 895 * This is set to false when we are killing processes for reasons other than 896 * memory management, so that the now smaller process list will not be taken as 897 * an indication that memory is tighter. 898 */ 899 boolean mAllowLowerMemLevel = false; 900 901 /** 902 * The last computed memory level, for holding when we are in a state that 903 * processes are going away for other reasons. 904 */ 905 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 906 907 /** 908 * The last total number of process we have, to determine if changes actually look 909 * like a shrinking number of process due to lower RAM. 910 */ 911 int mLastNumProcesses; 912 913 /** 914 * The uptime of the last time we performed idle maintenance. 915 */ 916 long mLastIdleTime = SystemClock.uptimeMillis(); 917 918 /** 919 * Total time spent with RAM that has been added in the past since the last idle time. 920 */ 921 long mLowRamTimeSinceLastIdle = 0; 922 923 /** 924 * If RAM is currently low, when that horrible situation started. 925 */ 926 long mLowRamStartTime = 0; 927 928 /** 929 * For reporting to battery stats the current top application. 930 */ 931 private String mCurResumedPackage = null; 932 private int mCurResumedUid = -1; 933 934 /** 935 * For reporting to battery stats the apps currently running foreground 936 * service. The ProcessMap is package/uid tuples; each of these contain 937 * an array of the currently foreground processes. 938 */ 939 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 940 = new ProcessMap<ArrayList<ProcessRecord>>(); 941 942 /** 943 * This is set if we had to do a delayed dexopt of an app before launching 944 * it, to increasing the ANR timeouts in that case. 945 */ 946 boolean mDidDexOpt; 947 948 String mDebugApp = null; 949 boolean mWaitForDebugger = false; 950 boolean mDebugTransient = false; 951 String mOrigDebugApp = null; 952 boolean mOrigWaitForDebugger = false; 953 boolean mAlwaysFinishActivities = false; 954 IActivityController mController = null; 955 String mProfileApp = null; 956 ProcessRecord mProfileProc = null; 957 String mProfileFile; 958 ParcelFileDescriptor mProfileFd; 959 int mProfileType = 0; 960 boolean mAutoStopProfiler = false; 961 String mOpenGlTraceApp = null; 962 963 static class ProcessChangeItem { 964 static final int CHANGE_ACTIVITIES = 1<<0; 965 static final int CHANGE_IMPORTANCE= 1<<1; 966 int changes; 967 int uid; 968 int pid; 969 int importance; 970 boolean foregroundActivities; 971 } 972 973 final RemoteCallbackList<IProcessObserver> mProcessObservers 974 = new RemoteCallbackList<IProcessObserver>(); 975 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 976 977 final ArrayList<ProcessChangeItem> mPendingProcessChanges 978 = new ArrayList<ProcessChangeItem>(); 979 final ArrayList<ProcessChangeItem> mAvailProcessChanges 980 = new ArrayList<ProcessChangeItem>(); 981 982 /** 983 * Runtime CPU use collection thread. This object's lock is used to 984 * protect all related state. 985 */ 986 final Thread mProcessCpuThread; 987 988 /** 989 * Used to collect process stats when showing not responding dialog. 990 * Protected by mProcessCpuThread. 991 */ 992 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 993 MONITOR_THREAD_CPU_USAGE); 994 final AtomicLong mLastCpuTime = new AtomicLong(0); 995 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 996 997 long mLastWriteTime = 0; 998 999 /** 1000 * Used to retain an update lock when the foreground activity is in 1001 * immersive mode. 1002 */ 1003 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1004 1005 /** 1006 * Set to true after the system has finished booting. 1007 */ 1008 boolean mBooted = false; 1009 1010 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1011 int mProcessLimitOverride = -1; 1012 1013 WindowManagerService mWindowManager; 1014 1015 final ActivityThread mSystemThread; 1016 1017 int mCurrentUserId = 0; 1018 private UserManagerService mUserManager; 1019 1020 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1021 final ProcessRecord mApp; 1022 final int mPid; 1023 final IApplicationThread mAppThread; 1024 1025 AppDeathRecipient(ProcessRecord app, int pid, 1026 IApplicationThread thread) { 1027 if (localLOGV) Slog.v( 1028 TAG, "New death recipient " + this 1029 + " for thread " + thread.asBinder()); 1030 mApp = app; 1031 mPid = pid; 1032 mAppThread = thread; 1033 } 1034 1035 @Override 1036 public void binderDied() { 1037 if (localLOGV) Slog.v( 1038 TAG, "Death received in " + this 1039 + " for thread " + mAppThread.asBinder()); 1040 synchronized(ActivityManagerService.this) { 1041 appDiedLocked(mApp, mPid, mAppThread); 1042 } 1043 } 1044 } 1045 1046 static final int SHOW_ERROR_MSG = 1; 1047 static final int SHOW_NOT_RESPONDING_MSG = 2; 1048 static final int SHOW_FACTORY_ERROR_MSG = 3; 1049 static final int UPDATE_CONFIGURATION_MSG = 4; 1050 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1051 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1052 static final int SERVICE_TIMEOUT_MSG = 12; 1053 static final int UPDATE_TIME_ZONE = 13; 1054 static final int SHOW_UID_ERROR_MSG = 14; 1055 static final int IM_FEELING_LUCKY_MSG = 15; 1056 static final int PROC_START_TIMEOUT_MSG = 20; 1057 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1058 static final int KILL_APPLICATION_MSG = 22; 1059 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1060 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1061 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1062 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1063 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1064 static final int CLEAR_DNS_CACHE_MSG = 28; 1065 static final int UPDATE_HTTP_PROXY_MSG = 29; 1066 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1067 static final int DISPATCH_PROCESSES_CHANGED = 31; 1068 static final int DISPATCH_PROCESS_DIED = 32; 1069 static final int REPORT_MEM_USAGE_MSG = 33; 1070 static final int REPORT_USER_SWITCH_MSG = 34; 1071 static final int CONTINUE_USER_SWITCH_MSG = 35; 1072 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1073 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1074 static final int PERSIST_URI_GRANTS_MSG = 38; 1075 static final int REQUEST_ALL_PSS_MSG = 39; 1076 1077 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1078 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1079 static final int FIRST_COMPAT_MODE_MSG = 300; 1080 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1081 1082 AlertDialog mUidAlert; 1083 CompatModeDialog mCompatModeDialog; 1084 long mLastMemUsageReportTime = 0; 1085 1086 /** 1087 * Flag whether the current user is a "monkey", i.e. whether 1088 * the UI is driven by a UI automation tool. 1089 */ 1090 private boolean mUserIsMonkey; 1091 1092 final ServiceThread mHandlerThread; 1093 final MainHandler mHandler; 1094 1095 final class MainHandler extends Handler { 1096 public MainHandler(Looper looper) { 1097 super(looper, null, true); 1098 } 1099 1100 @Override 1101 public void handleMessage(Message msg) { 1102 switch (msg.what) { 1103 case SHOW_ERROR_MSG: { 1104 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1105 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1106 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1107 synchronized (ActivityManagerService.this) { 1108 ProcessRecord proc = (ProcessRecord)data.get("app"); 1109 AppErrorResult res = (AppErrorResult) data.get("result"); 1110 if (proc != null && proc.crashDialog != null) { 1111 Slog.e(TAG, "App already has crash dialog: " + proc); 1112 if (res != null) { 1113 res.set(0); 1114 } 1115 return; 1116 } 1117 if (!showBackground && UserHandle.getAppId(proc.uid) 1118 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1119 && proc.pid != MY_PID) { 1120 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1121 if (res != null) { 1122 res.set(0); 1123 } 1124 return; 1125 } 1126 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1127 Dialog d = new AppErrorDialog(mContext, 1128 ActivityManagerService.this, res, proc); 1129 d.show(); 1130 proc.crashDialog = d; 1131 } else { 1132 // The device is asleep, so just pretend that the user 1133 // saw a crash dialog and hit "force quit". 1134 if (res != null) { 1135 res.set(0); 1136 } 1137 } 1138 } 1139 1140 ensureBootCompleted(); 1141 } break; 1142 case SHOW_NOT_RESPONDING_MSG: { 1143 synchronized (ActivityManagerService.this) { 1144 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1145 ProcessRecord proc = (ProcessRecord)data.get("app"); 1146 if (proc != null && proc.anrDialog != null) { 1147 Slog.e(TAG, "App already has anr dialog: " + proc); 1148 return; 1149 } 1150 1151 Intent intent = new Intent("android.intent.action.ANR"); 1152 if (!mProcessesReady) { 1153 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1154 | Intent.FLAG_RECEIVER_FOREGROUND); 1155 } 1156 broadcastIntentLocked(null, null, intent, 1157 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1158 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1159 1160 if (mShowDialogs) { 1161 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1162 mContext, proc, (ActivityRecord)data.get("activity"), 1163 msg.arg1 != 0); 1164 d.show(); 1165 proc.anrDialog = d; 1166 } else { 1167 // Just kill the app if there is no dialog to be shown. 1168 killAppAtUsersRequest(proc, null); 1169 } 1170 } 1171 1172 ensureBootCompleted(); 1173 } break; 1174 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1175 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1176 synchronized (ActivityManagerService.this) { 1177 ProcessRecord proc = (ProcessRecord) data.get("app"); 1178 if (proc == null) { 1179 Slog.e(TAG, "App not found when showing strict mode dialog."); 1180 break; 1181 } 1182 if (proc.crashDialog != null) { 1183 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1184 return; 1185 } 1186 AppErrorResult res = (AppErrorResult) data.get("result"); 1187 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1188 Dialog d = new StrictModeViolationDialog(mContext, 1189 ActivityManagerService.this, res, proc); 1190 d.show(); 1191 proc.crashDialog = d; 1192 } else { 1193 // The device is asleep, so just pretend that the user 1194 // saw a crash dialog and hit "force quit". 1195 res.set(0); 1196 } 1197 } 1198 ensureBootCompleted(); 1199 } break; 1200 case SHOW_FACTORY_ERROR_MSG: { 1201 Dialog d = new FactoryErrorDialog( 1202 mContext, msg.getData().getCharSequence("msg")); 1203 d.show(); 1204 ensureBootCompleted(); 1205 } break; 1206 case UPDATE_CONFIGURATION_MSG: { 1207 final ContentResolver resolver = mContext.getContentResolver(); 1208 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1209 } break; 1210 case GC_BACKGROUND_PROCESSES_MSG: { 1211 synchronized (ActivityManagerService.this) { 1212 performAppGcsIfAppropriateLocked(); 1213 } 1214 } break; 1215 case WAIT_FOR_DEBUGGER_MSG: { 1216 synchronized (ActivityManagerService.this) { 1217 ProcessRecord app = (ProcessRecord)msg.obj; 1218 if (msg.arg1 != 0) { 1219 if (!app.waitedForDebugger) { 1220 Dialog d = new AppWaitingForDebuggerDialog( 1221 ActivityManagerService.this, 1222 mContext, app); 1223 app.waitDialog = d; 1224 app.waitedForDebugger = true; 1225 d.show(); 1226 } 1227 } else { 1228 if (app.waitDialog != null) { 1229 app.waitDialog.dismiss(); 1230 app.waitDialog = null; 1231 } 1232 } 1233 } 1234 } break; 1235 case SERVICE_TIMEOUT_MSG: { 1236 if (mDidDexOpt) { 1237 mDidDexOpt = false; 1238 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1239 nmsg.obj = msg.obj; 1240 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1241 return; 1242 } 1243 mServices.serviceTimeout((ProcessRecord)msg.obj); 1244 } break; 1245 case UPDATE_TIME_ZONE: { 1246 synchronized (ActivityManagerService.this) { 1247 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1248 ProcessRecord r = mLruProcesses.get(i); 1249 if (r.thread != null) { 1250 try { 1251 r.thread.updateTimeZone(); 1252 } catch (RemoteException ex) { 1253 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1254 } 1255 } 1256 } 1257 } 1258 } break; 1259 case CLEAR_DNS_CACHE_MSG: { 1260 synchronized (ActivityManagerService.this) { 1261 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1262 ProcessRecord r = mLruProcesses.get(i); 1263 if (r.thread != null) { 1264 try { 1265 r.thread.clearDnsCache(); 1266 } catch (RemoteException ex) { 1267 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1268 } 1269 } 1270 } 1271 } 1272 } break; 1273 case UPDATE_HTTP_PROXY_MSG: { 1274 ProxyProperties proxy = (ProxyProperties)msg.obj; 1275 String host = ""; 1276 String port = ""; 1277 String exclList = ""; 1278 String pacFileUrl = null; 1279 if (proxy != null) { 1280 host = proxy.getHost(); 1281 port = Integer.toString(proxy.getPort()); 1282 exclList = proxy.getExclusionList(); 1283 pacFileUrl = proxy.getPacFileUrl(); 1284 } 1285 synchronized (ActivityManagerService.this) { 1286 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1287 ProcessRecord r = mLruProcesses.get(i); 1288 if (r.thread != null) { 1289 try { 1290 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1291 } catch (RemoteException ex) { 1292 Slog.w(TAG, "Failed to update http proxy for: " + 1293 r.info.processName); 1294 } 1295 } 1296 } 1297 } 1298 } break; 1299 case SHOW_UID_ERROR_MSG: { 1300 String title = "System UIDs Inconsistent"; 1301 String text = "UIDs on the system are inconsistent, you need to wipe your" 1302 + " data partition or your device will be unstable."; 1303 Log.e(TAG, title + ": " + text); 1304 if (mShowDialogs) { 1305 // XXX This is a temporary dialog, no need to localize. 1306 AlertDialog d = new BaseErrorDialog(mContext); 1307 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1308 d.setCancelable(false); 1309 d.setTitle(title); 1310 d.setMessage(text); 1311 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1312 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1313 mUidAlert = d; 1314 d.show(); 1315 } 1316 } break; 1317 case IM_FEELING_LUCKY_MSG: { 1318 if (mUidAlert != null) { 1319 mUidAlert.dismiss(); 1320 mUidAlert = null; 1321 } 1322 } break; 1323 case PROC_START_TIMEOUT_MSG: { 1324 if (mDidDexOpt) { 1325 mDidDexOpt = false; 1326 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1327 nmsg.obj = msg.obj; 1328 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1329 return; 1330 } 1331 ProcessRecord app = (ProcessRecord)msg.obj; 1332 synchronized (ActivityManagerService.this) { 1333 processStartTimedOutLocked(app); 1334 } 1335 } break; 1336 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1337 synchronized (ActivityManagerService.this) { 1338 doPendingActivityLaunchesLocked(true); 1339 } 1340 } break; 1341 case KILL_APPLICATION_MSG: { 1342 synchronized (ActivityManagerService.this) { 1343 int appid = msg.arg1; 1344 boolean restart = (msg.arg2 == 1); 1345 Bundle bundle = (Bundle)msg.obj; 1346 String pkg = bundle.getString("pkg"); 1347 String reason = bundle.getString("reason"); 1348 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1349 false, UserHandle.USER_ALL, reason); 1350 } 1351 } break; 1352 case FINALIZE_PENDING_INTENT_MSG: { 1353 ((PendingIntentRecord)msg.obj).completeFinalize(); 1354 } break; 1355 case POST_HEAVY_NOTIFICATION_MSG: { 1356 INotificationManager inm = NotificationManager.getService(); 1357 if (inm == null) { 1358 return; 1359 } 1360 1361 ActivityRecord root = (ActivityRecord)msg.obj; 1362 ProcessRecord process = root.app; 1363 if (process == null) { 1364 return; 1365 } 1366 1367 try { 1368 Context context = mContext.createPackageContext(process.info.packageName, 0); 1369 String text = mContext.getString(R.string.heavy_weight_notification, 1370 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1371 Notification notification = new Notification(); 1372 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1373 notification.when = 0; 1374 notification.flags = Notification.FLAG_ONGOING_EVENT; 1375 notification.tickerText = text; 1376 notification.defaults = 0; // please be quiet 1377 notification.sound = null; 1378 notification.vibrate = null; 1379 notification.setLatestEventInfo(context, text, 1380 mContext.getText(R.string.heavy_weight_notification_detail), 1381 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1382 PendingIntent.FLAG_CANCEL_CURRENT, null, 1383 new UserHandle(root.userId))); 1384 1385 try { 1386 int[] outId = new int[1]; 1387 inm.enqueueNotificationWithTag("android", "android", null, 1388 R.string.heavy_weight_notification, 1389 notification, outId, root.userId); 1390 } catch (RuntimeException e) { 1391 Slog.w(ActivityManagerService.TAG, 1392 "Error showing notification for heavy-weight app", e); 1393 } catch (RemoteException e) { 1394 } 1395 } catch (NameNotFoundException e) { 1396 Slog.w(TAG, "Unable to create context for heavy notification", e); 1397 } 1398 } break; 1399 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1400 INotificationManager inm = NotificationManager.getService(); 1401 if (inm == null) { 1402 return; 1403 } 1404 try { 1405 inm.cancelNotificationWithTag("android", null, 1406 R.string.heavy_weight_notification, msg.arg1); 1407 } catch (RuntimeException e) { 1408 Slog.w(ActivityManagerService.TAG, 1409 "Error canceling notification for service", e); 1410 } catch (RemoteException e) { 1411 } 1412 } break; 1413 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1414 synchronized (ActivityManagerService.this) { 1415 checkExcessivePowerUsageLocked(true); 1416 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1417 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1418 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1419 } 1420 } break; 1421 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1422 synchronized (ActivityManagerService.this) { 1423 ActivityRecord ar = (ActivityRecord)msg.obj; 1424 if (mCompatModeDialog != null) { 1425 if (mCompatModeDialog.mAppInfo.packageName.equals( 1426 ar.info.applicationInfo.packageName)) { 1427 return; 1428 } 1429 mCompatModeDialog.dismiss(); 1430 mCompatModeDialog = null; 1431 } 1432 if (ar != null && false) { 1433 if (mCompatModePackages.getPackageAskCompatModeLocked( 1434 ar.packageName)) { 1435 int mode = mCompatModePackages.computeCompatModeLocked( 1436 ar.info.applicationInfo); 1437 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1438 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1439 mCompatModeDialog = new CompatModeDialog( 1440 ActivityManagerService.this, mContext, 1441 ar.info.applicationInfo); 1442 mCompatModeDialog.show(); 1443 } 1444 } 1445 } 1446 } 1447 break; 1448 } 1449 case DISPATCH_PROCESSES_CHANGED: { 1450 dispatchProcessesChanged(); 1451 break; 1452 } 1453 case DISPATCH_PROCESS_DIED: { 1454 final int pid = msg.arg1; 1455 final int uid = msg.arg2; 1456 dispatchProcessDied(pid, uid); 1457 break; 1458 } 1459 case REPORT_MEM_USAGE_MSG: { 1460 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1461 Thread thread = new Thread() { 1462 @Override public void run() { 1463 final SparseArray<ProcessMemInfo> infoMap 1464 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1465 for (int i=0, N=memInfos.size(); i<N; i++) { 1466 ProcessMemInfo mi = memInfos.get(i); 1467 infoMap.put(mi.pid, mi); 1468 } 1469 updateCpuStatsNow(); 1470 synchronized (mProcessCpuThread) { 1471 final int N = mProcessCpuTracker.countStats(); 1472 for (int i=0; i<N; i++) { 1473 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1474 if (st.vsize > 0) { 1475 long pss = Debug.getPss(st.pid, null); 1476 if (pss > 0) { 1477 if (infoMap.indexOfKey(st.pid) < 0) { 1478 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1479 ProcessList.NATIVE_ADJ, -1, "native", null); 1480 mi.pss = pss; 1481 memInfos.add(mi); 1482 } 1483 } 1484 } 1485 } 1486 } 1487 1488 long totalPss = 0; 1489 for (int i=0, N=memInfos.size(); i<N; i++) { 1490 ProcessMemInfo mi = memInfos.get(i); 1491 if (mi.pss == 0) { 1492 mi.pss = Debug.getPss(mi.pid, null); 1493 } 1494 totalPss += mi.pss; 1495 } 1496 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1497 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1498 if (lhs.oomAdj != rhs.oomAdj) { 1499 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1500 } 1501 if (lhs.pss != rhs.pss) { 1502 return lhs.pss < rhs.pss ? 1 : -1; 1503 } 1504 return 0; 1505 } 1506 }); 1507 1508 StringBuilder tag = new StringBuilder(128); 1509 StringBuilder stack = new StringBuilder(128); 1510 tag.append("Low on memory -- "); 1511 appendMemBucket(tag, totalPss, "total", false); 1512 appendMemBucket(stack, totalPss, "total", true); 1513 1514 StringBuilder logBuilder = new StringBuilder(1024); 1515 logBuilder.append("Low on memory:\n"); 1516 1517 boolean firstLine = true; 1518 int lastOomAdj = Integer.MIN_VALUE; 1519 for (int i=0, N=memInfos.size(); i<N; i++) { 1520 ProcessMemInfo mi = memInfos.get(i); 1521 1522 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1523 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1524 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1525 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1526 if (lastOomAdj != mi.oomAdj) { 1527 lastOomAdj = mi.oomAdj; 1528 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1529 tag.append(" / "); 1530 } 1531 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1532 if (firstLine) { 1533 stack.append(":"); 1534 firstLine = false; 1535 } 1536 stack.append("\n\t at "); 1537 } else { 1538 stack.append("$"); 1539 } 1540 } else { 1541 tag.append(" "); 1542 stack.append("$"); 1543 } 1544 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1545 appendMemBucket(tag, mi.pss, mi.name, false); 1546 } 1547 appendMemBucket(stack, mi.pss, mi.name, true); 1548 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1549 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1550 stack.append("("); 1551 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1552 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1553 stack.append(DUMP_MEM_OOM_LABEL[k]); 1554 stack.append(":"); 1555 stack.append(DUMP_MEM_OOM_ADJ[k]); 1556 } 1557 } 1558 stack.append(")"); 1559 } 1560 } 1561 1562 logBuilder.append(" "); 1563 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1564 logBuilder.append(' '); 1565 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1566 logBuilder.append(' '); 1567 ProcessList.appendRamKb(logBuilder, mi.pss); 1568 logBuilder.append(" kB: "); 1569 logBuilder.append(mi.name); 1570 logBuilder.append(" ("); 1571 logBuilder.append(mi.pid); 1572 logBuilder.append(") "); 1573 logBuilder.append(mi.adjType); 1574 logBuilder.append('\n'); 1575 if (mi.adjReason != null) { 1576 logBuilder.append(" "); 1577 logBuilder.append(mi.adjReason); 1578 logBuilder.append('\n'); 1579 } 1580 } 1581 1582 logBuilder.append(" "); 1583 ProcessList.appendRamKb(logBuilder, totalPss); 1584 logBuilder.append(" kB: TOTAL\n"); 1585 1586 long[] infos = new long[Debug.MEMINFO_COUNT]; 1587 Debug.getMemInfo(infos); 1588 logBuilder.append(" MemInfo: "); 1589 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1590 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1591 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1592 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1593 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1594 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1595 logBuilder.append(" ZRAM: "); 1596 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1597 logBuilder.append(" kB RAM, "); 1598 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1599 logBuilder.append(" kB swap total, "); 1600 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1601 logBuilder.append(" kB swap free\n"); 1602 } 1603 Slog.i(TAG, logBuilder.toString()); 1604 1605 StringBuilder dropBuilder = new StringBuilder(1024); 1606 /* 1607 StringWriter oomSw = new StringWriter(); 1608 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1609 StringWriter catSw = new StringWriter(); 1610 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1611 String[] emptyArgs = new String[] { }; 1612 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1613 oomPw.flush(); 1614 String oomString = oomSw.toString(); 1615 */ 1616 dropBuilder.append(stack); 1617 dropBuilder.append('\n'); 1618 dropBuilder.append('\n'); 1619 dropBuilder.append(logBuilder); 1620 dropBuilder.append('\n'); 1621 /* 1622 dropBuilder.append(oomString); 1623 dropBuilder.append('\n'); 1624 */ 1625 StringWriter catSw = new StringWriter(); 1626 synchronized (ActivityManagerService.this) { 1627 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1628 String[] emptyArgs = new String[] { }; 1629 catPw.println(); 1630 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1631 catPw.println(); 1632 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1633 false, false, null); 1634 catPw.println(); 1635 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1636 catPw.flush(); 1637 } 1638 dropBuilder.append(catSw.toString()); 1639 addErrorToDropBox("lowmem", null, "system_server", null, 1640 null, tag.toString(), dropBuilder.toString(), null, null); 1641 //Slog.i(TAG, "Sent to dropbox:"); 1642 //Slog.i(TAG, dropBuilder.toString()); 1643 synchronized (ActivityManagerService.this) { 1644 long now = SystemClock.uptimeMillis(); 1645 if (mLastMemUsageReportTime < now) { 1646 mLastMemUsageReportTime = now; 1647 } 1648 } 1649 } 1650 }; 1651 thread.start(); 1652 break; 1653 } 1654 case REPORT_USER_SWITCH_MSG: { 1655 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1656 break; 1657 } 1658 case CONTINUE_USER_SWITCH_MSG: { 1659 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1660 break; 1661 } 1662 case USER_SWITCH_TIMEOUT_MSG: { 1663 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1664 break; 1665 } 1666 case IMMERSIVE_MODE_LOCK_MSG: { 1667 final boolean nextState = (msg.arg1 != 0); 1668 if (mUpdateLock.isHeld() != nextState) { 1669 if (DEBUG_IMMERSIVE) { 1670 final ActivityRecord r = (ActivityRecord) msg.obj; 1671 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1672 } 1673 if (nextState) { 1674 mUpdateLock.acquire(); 1675 } else { 1676 mUpdateLock.release(); 1677 } 1678 } 1679 break; 1680 } 1681 case PERSIST_URI_GRANTS_MSG: { 1682 writeGrantedUriPermissions(); 1683 break; 1684 } 1685 case REQUEST_ALL_PSS_MSG: { 1686 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1687 break; 1688 } 1689 } 1690 } 1691 }; 1692 1693 static final int COLLECT_PSS_BG_MSG = 1; 1694 1695 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1696 @Override 1697 public void handleMessage(Message msg) { 1698 switch (msg.what) { 1699 case COLLECT_PSS_BG_MSG: { 1700 int i=0, num=0; 1701 long start = SystemClock.uptimeMillis(); 1702 long[] tmp = new long[1]; 1703 do { 1704 ProcessRecord proc; 1705 int procState; 1706 int pid; 1707 synchronized (ActivityManagerService.this) { 1708 if (i >= mPendingPssProcesses.size()) { 1709 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1710 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1711 mPendingPssProcesses.clear(); 1712 return; 1713 } 1714 proc = mPendingPssProcesses.get(i); 1715 procState = proc.pssProcState; 1716 if (proc.thread != null && procState == proc.setProcState) { 1717 pid = proc.pid; 1718 } else { 1719 proc = null; 1720 pid = 0; 1721 } 1722 i++; 1723 } 1724 if (proc != null) { 1725 long pss = Debug.getPss(pid, tmp); 1726 synchronized (ActivityManagerService.this) { 1727 if (proc.thread != null && proc.setProcState == procState 1728 && proc.pid == pid) { 1729 num++; 1730 proc.lastPssTime = SystemClock.uptimeMillis(); 1731 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1732 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1733 + ": " + pss + " lastPss=" + proc.lastPss 1734 + " state=" + ProcessList.makeProcStateString(procState)); 1735 if (proc.initialIdlePss == 0) { 1736 proc.initialIdlePss = pss; 1737 } 1738 proc.lastPss = pss; 1739 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1740 proc.lastCachedPss = pss; 1741 } 1742 } 1743 } 1744 } 1745 } while (true); 1746 } 1747 } 1748 } 1749 }; 1750 1751 public void setSystemProcess() { 1752 try { 1753 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1754 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1755 ServiceManager.addService("meminfo", new MemBinder(this)); 1756 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1757 ServiceManager.addService("dbinfo", new DbBinder(this)); 1758 if (MONITOR_CPU_USAGE) { 1759 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1760 } 1761 ServiceManager.addService("permission", new PermissionController(this)); 1762 1763 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1764 "android", STOCK_PM_FLAGS); 1765 mSystemThread.installSystemApplicationInfo(info); 1766 1767 synchronized (this) { 1768 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1769 app.persistent = true; 1770 app.pid = MY_PID; 1771 app.maxAdj = ProcessList.SYSTEM_ADJ; 1772 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1773 mProcessNames.put(app.processName, app.uid, app); 1774 synchronized (mPidsSelfLocked) { 1775 mPidsSelfLocked.put(app.pid, app); 1776 } 1777 updateLruProcessLocked(app, false, null); 1778 updateOomAdjLocked(); 1779 } 1780 } catch (PackageManager.NameNotFoundException e) { 1781 throw new RuntimeException( 1782 "Unable to find android system package", e); 1783 } 1784 } 1785 1786 public void setWindowManager(WindowManagerService wm) { 1787 mWindowManager = wm; 1788 mStackSupervisor.setWindowManager(wm); 1789 } 1790 1791 public void startObservingNativeCrashes() { 1792 final NativeCrashListener ncl = new NativeCrashListener(this); 1793 ncl.start(); 1794 } 1795 1796 public IAppOpsService getAppOpsService() { 1797 return mAppOpsService; 1798 } 1799 1800 static class MemBinder extends Binder { 1801 ActivityManagerService mActivityManagerService; 1802 MemBinder(ActivityManagerService activityManagerService) { 1803 mActivityManagerService = activityManagerService; 1804 } 1805 1806 @Override 1807 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1808 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1809 != PackageManager.PERMISSION_GRANTED) { 1810 pw.println("Permission Denial: can't dump meminfo from from pid=" 1811 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1812 + " without permission " + android.Manifest.permission.DUMP); 1813 return; 1814 } 1815 1816 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1817 } 1818 } 1819 1820 static class GraphicsBinder extends Binder { 1821 ActivityManagerService mActivityManagerService; 1822 GraphicsBinder(ActivityManagerService activityManagerService) { 1823 mActivityManagerService = activityManagerService; 1824 } 1825 1826 @Override 1827 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1828 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1829 != PackageManager.PERMISSION_GRANTED) { 1830 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1831 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1832 + " without permission " + android.Manifest.permission.DUMP); 1833 return; 1834 } 1835 1836 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1837 } 1838 } 1839 1840 static class DbBinder extends Binder { 1841 ActivityManagerService mActivityManagerService; 1842 DbBinder(ActivityManagerService activityManagerService) { 1843 mActivityManagerService = activityManagerService; 1844 } 1845 1846 @Override 1847 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1848 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1849 != PackageManager.PERMISSION_GRANTED) { 1850 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1851 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1852 + " without permission " + android.Manifest.permission.DUMP); 1853 return; 1854 } 1855 1856 mActivityManagerService.dumpDbInfo(fd, pw, args); 1857 } 1858 } 1859 1860 static class CpuBinder extends Binder { 1861 ActivityManagerService mActivityManagerService; 1862 CpuBinder(ActivityManagerService activityManagerService) { 1863 mActivityManagerService = activityManagerService; 1864 } 1865 1866 @Override 1867 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1868 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1869 != PackageManager.PERMISSION_GRANTED) { 1870 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1871 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1872 + " without permission " + android.Manifest.permission.DUMP); 1873 return; 1874 } 1875 1876 synchronized (mActivityManagerService.mProcessCpuThread) { 1877 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1878 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1879 SystemClock.uptimeMillis())); 1880 } 1881 } 1882 } 1883 1884 public static final class Lifecycle extends SystemService { 1885 private final ActivityManagerService mService; 1886 1887 public Lifecycle(Context context) { 1888 super(context); 1889 mService = new ActivityManagerService(context); 1890 } 1891 1892 @Override 1893 public void onStart() { 1894 mService.start(); 1895 } 1896 1897 public ActivityManagerService getService() { 1898 return mService; 1899 } 1900 } 1901 1902 // Note: This method is invoked on the main thread but may need to attach various 1903 // handlers to other threads. So take care to be explicit about the looper. 1904 public ActivityManagerService(Context systemContext) { 1905 mContext = systemContext; 1906 mFactoryTest = FactoryTest.getMode(); 1907 mSystemThread = ActivityThread.currentActivityThread(); 1908 1909 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1910 1911 mHandlerThread = new ServiceThread(TAG, 1912 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1913 mHandlerThread.start(); 1914 mHandler = new MainHandler(mHandlerThread.getLooper()); 1915 1916 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1917 "foreground", BROADCAST_FG_TIMEOUT, false); 1918 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1919 "background", BROADCAST_BG_TIMEOUT, true); 1920 mBroadcastQueues[0] = mFgBroadcastQueue; 1921 mBroadcastQueues[1] = mBgBroadcastQueue; 1922 1923 mServices = new ActiveServices(this); 1924 mProviderMap = new ProviderMap(this); 1925 1926 // TODO: Move creation of battery stats service outside of activity manager service. 1927 File dataDir = Environment.getDataDirectory(); 1928 File systemDir = new File(dataDir, "system"); 1929 systemDir.mkdirs(); 1930 mBatteryStatsService = new BatteryStatsService(new File( 1931 systemDir, "batterystats.bin").toString(), mHandler); 1932 mBatteryStatsService.getActiveStatistics().readLocked(); 1933 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1934 mOnBattery = DEBUG_POWER ? true 1935 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1936 mBatteryStatsService.getActiveStatistics().setCallback(this); 1937 1938 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1939 1940 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1941 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1942 1943 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1944 1945 // User 0 is the first and only user that runs at boot. 1946 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1947 mUserLru.add(Integer.valueOf(0)); 1948 updateStartedUserArrayLocked(); 1949 1950 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1951 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1952 1953 mConfiguration.setToDefaults(); 1954 mConfiguration.setLocale(Locale.getDefault()); 1955 1956 mConfigurationSeq = mConfiguration.seq = 1; 1957 mProcessCpuTracker.init(); 1958 1959 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1960 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1961 mStackSupervisor = new ActivityStackSupervisor(this); 1962 1963 mProcessCpuThread = new Thread("CpuTracker") { 1964 @Override 1965 public void run() { 1966 while (true) { 1967 try { 1968 try { 1969 synchronized(this) { 1970 final long now = SystemClock.uptimeMillis(); 1971 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1972 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1973 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1974 // + ", write delay=" + nextWriteDelay); 1975 if (nextWriteDelay < nextCpuDelay) { 1976 nextCpuDelay = nextWriteDelay; 1977 } 1978 if (nextCpuDelay > 0) { 1979 mProcessCpuMutexFree.set(true); 1980 this.wait(nextCpuDelay); 1981 } 1982 } 1983 } catch (InterruptedException e) { 1984 } 1985 updateCpuStatsNow(); 1986 } catch (Exception e) { 1987 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1988 } 1989 } 1990 } 1991 }; 1992 1993 Watchdog.getInstance().addMonitor(this); 1994 Watchdog.getInstance().addThread(mHandler); 1995 } 1996 1997 private void start() { 1998 mProcessCpuThread.start(); 1999 2000 mBatteryStatsService.publish(mContext); 2001 mUsageStatsService.publish(mContext); 2002 mAppOpsService.publish(mContext); 2003 startRunning(null, null, null, null); 2004 } 2005 2006 @Override 2007 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2008 throws RemoteException { 2009 if (code == SYSPROPS_TRANSACTION) { 2010 // We need to tell all apps about the system property change. 2011 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2012 synchronized(this) { 2013 final int NP = mProcessNames.getMap().size(); 2014 for (int ip=0; ip<NP; ip++) { 2015 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2016 final int NA = apps.size(); 2017 for (int ia=0; ia<NA; ia++) { 2018 ProcessRecord app = apps.valueAt(ia); 2019 if (app.thread != null) { 2020 procs.add(app.thread.asBinder()); 2021 } 2022 } 2023 } 2024 } 2025 2026 int N = procs.size(); 2027 for (int i=0; i<N; i++) { 2028 Parcel data2 = Parcel.obtain(); 2029 try { 2030 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2031 } catch (RemoteException e) { 2032 } 2033 data2.recycle(); 2034 } 2035 } 2036 try { 2037 return super.onTransact(code, data, reply, flags); 2038 } catch (RuntimeException e) { 2039 // The activity manager only throws security exceptions, so let's 2040 // log all others. 2041 if (!(e instanceof SecurityException)) { 2042 Slog.wtf(TAG, "Activity Manager Crash", e); 2043 } 2044 throw e; 2045 } 2046 } 2047 2048 void updateCpuStats() { 2049 final long now = SystemClock.uptimeMillis(); 2050 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2051 return; 2052 } 2053 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2054 synchronized (mProcessCpuThread) { 2055 mProcessCpuThread.notify(); 2056 } 2057 } 2058 } 2059 2060 void updateCpuStatsNow() { 2061 synchronized (mProcessCpuThread) { 2062 mProcessCpuMutexFree.set(false); 2063 final long now = SystemClock.uptimeMillis(); 2064 boolean haveNewCpuStats = false; 2065 2066 if (MONITOR_CPU_USAGE && 2067 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2068 mLastCpuTime.set(now); 2069 haveNewCpuStats = true; 2070 mProcessCpuTracker.update(); 2071 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2072 //Slog.i(TAG, "Total CPU usage: " 2073 // + mProcessCpu.getTotalCpuPercent() + "%"); 2074 2075 // Slog the cpu usage if the property is set. 2076 if ("true".equals(SystemProperties.get("events.cpu"))) { 2077 int user = mProcessCpuTracker.getLastUserTime(); 2078 int system = mProcessCpuTracker.getLastSystemTime(); 2079 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2080 int irq = mProcessCpuTracker.getLastIrqTime(); 2081 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2082 int idle = mProcessCpuTracker.getLastIdleTime(); 2083 2084 int total = user + system + iowait + irq + softIrq + idle; 2085 if (total == 0) total = 1; 2086 2087 EventLog.writeEvent(EventLogTags.CPU, 2088 ((user+system+iowait+irq+softIrq) * 100) / total, 2089 (user * 100) / total, 2090 (system * 100) / total, 2091 (iowait * 100) / total, 2092 (irq * 100) / total, 2093 (softIrq * 100) / total); 2094 } 2095 } 2096 2097 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2098 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2099 synchronized(bstats) { 2100 synchronized(mPidsSelfLocked) { 2101 if (haveNewCpuStats) { 2102 if (mOnBattery) { 2103 int perc = bstats.startAddingCpuLocked(); 2104 int totalUTime = 0; 2105 int totalSTime = 0; 2106 final int N = mProcessCpuTracker.countStats(); 2107 for (int i=0; i<N; i++) { 2108 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2109 if (!st.working) { 2110 continue; 2111 } 2112 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2113 int otherUTime = (st.rel_utime*perc)/100; 2114 int otherSTime = (st.rel_stime*perc)/100; 2115 totalUTime += otherUTime; 2116 totalSTime += otherSTime; 2117 if (pr != null) { 2118 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2119 if (ps == null || !ps.isActive()) { 2120 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2121 pr.info.uid, pr.processName); 2122 } 2123 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2124 st.rel_stime-otherSTime); 2125 ps.addSpeedStepTimes(cpuSpeedTimes); 2126 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2127 } else { 2128 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2129 if (ps == null || !ps.isActive()) { 2130 st.batteryStats = ps = bstats.getProcessStatsLocked( 2131 bstats.mapUid(st.uid), st.name); 2132 } 2133 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2134 st.rel_stime-otherSTime); 2135 ps.addSpeedStepTimes(cpuSpeedTimes); 2136 } 2137 } 2138 bstats.finishAddingCpuLocked(perc, totalUTime, 2139 totalSTime, cpuSpeedTimes); 2140 } 2141 } 2142 } 2143 2144 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2145 mLastWriteTime = now; 2146 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2147 } 2148 } 2149 } 2150 } 2151 2152 @Override 2153 public void batteryNeedsCpuUpdate() { 2154 updateCpuStatsNow(); 2155 } 2156 2157 @Override 2158 public void batteryPowerChanged(boolean onBattery) { 2159 // When plugging in, update the CPU stats first before changing 2160 // the plug state. 2161 updateCpuStatsNow(); 2162 synchronized (this) { 2163 synchronized(mPidsSelfLocked) { 2164 mOnBattery = DEBUG_POWER ? true : onBattery; 2165 } 2166 } 2167 } 2168 2169 /** 2170 * Initialize the application bind args. These are passed to each 2171 * process when the bindApplication() IPC is sent to the process. They're 2172 * lazily setup to make sure the services are running when they're asked for. 2173 */ 2174 private HashMap<String, IBinder> getCommonServicesLocked() { 2175 if (mAppBindArgs == null) { 2176 mAppBindArgs = new HashMap<String, IBinder>(); 2177 2178 // Setup the application init args 2179 mAppBindArgs.put("package", ServiceManager.getService("package")); 2180 mAppBindArgs.put("window", ServiceManager.getService("window")); 2181 mAppBindArgs.put(Context.ALARM_SERVICE, 2182 ServiceManager.getService(Context.ALARM_SERVICE)); 2183 } 2184 return mAppBindArgs; 2185 } 2186 2187 final void setFocusedActivityLocked(ActivityRecord r) { 2188 if (mFocusedActivity != r) { 2189 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2190 mFocusedActivity = r; 2191 mStackSupervisor.setFocusedStack(r); 2192 if (r != null) { 2193 mWindowManager.setFocusedApp(r.appToken, true); 2194 } 2195 applyUpdateLockStateLocked(r); 2196 } 2197 } 2198 2199 @Override 2200 public void setFocusedStack(int stackId) { 2201 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2202 synchronized (ActivityManagerService.this) { 2203 ActivityStack stack = mStackSupervisor.getStack(stackId); 2204 if (stack != null) { 2205 ActivityRecord r = stack.topRunningActivityLocked(null); 2206 if (r != null) { 2207 setFocusedActivityLocked(r); 2208 } 2209 } 2210 } 2211 } 2212 2213 @Override 2214 public void notifyActivityDrawn(IBinder token) { 2215 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2216 synchronized (this) { 2217 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2218 if (r != null) { 2219 r.task.stack.notifyActivityDrawnLocked(r); 2220 } 2221 } 2222 } 2223 2224 final void applyUpdateLockStateLocked(ActivityRecord r) { 2225 // Modifications to the UpdateLock state are done on our handler, outside 2226 // the activity manager's locks. The new state is determined based on the 2227 // state *now* of the relevant activity record. The object is passed to 2228 // the handler solely for logging detail, not to be consulted/modified. 2229 final boolean nextState = r != null && r.immersive; 2230 mHandler.sendMessage( 2231 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2232 } 2233 2234 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2235 Message msg = Message.obtain(); 2236 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2237 msg.obj = r.task.askedCompatMode ? null : r; 2238 mHandler.sendMessage(msg); 2239 } 2240 2241 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2242 String what, Object obj, ProcessRecord srcApp) { 2243 app.lastActivityTime = now; 2244 2245 if (app.activities.size() > 0) { 2246 // Don't want to touch dependent processes that are hosting activities. 2247 return index; 2248 } 2249 2250 int lrui = mLruProcesses.lastIndexOf(app); 2251 if (lrui < 0) { 2252 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2253 + what + " " + obj + " from " + srcApp); 2254 return index; 2255 } 2256 2257 if (lrui >= index) { 2258 // Don't want to cause this to move dependent processes *back* in the 2259 // list as if they were less frequently used. 2260 return index; 2261 } 2262 2263 if (lrui >= mLruProcessActivityStart) { 2264 // Don't want to touch dependent processes that are hosting activities. 2265 return index; 2266 } 2267 2268 mLruProcesses.remove(lrui); 2269 if (index > 0) { 2270 index--; 2271 } 2272 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2273 + " in LRU list: " + app); 2274 mLruProcesses.add(index, app); 2275 return index; 2276 } 2277 2278 final void removeLruProcessLocked(ProcessRecord app) { 2279 int lrui = mLruProcesses.lastIndexOf(app); 2280 if (lrui >= 0) { 2281 if (lrui <= mLruProcessActivityStart) { 2282 mLruProcessActivityStart--; 2283 } 2284 if (lrui <= mLruProcessServiceStart) { 2285 mLruProcessServiceStart--; 2286 } 2287 mLruProcesses.remove(lrui); 2288 } 2289 } 2290 2291 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2292 ProcessRecord client) { 2293 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities; 2294 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2295 if (!activityChange && hasActivity) { 2296 // The process has activties, so we are only going to allow activity-based 2297 // adjustments move it. It should be kept in the front of the list with other 2298 // processes that have activities, and we don't want those to change their 2299 // order except due to activity operations. 2300 return; 2301 } 2302 2303 mLruSeq++; 2304 final long now = SystemClock.uptimeMillis(); 2305 app.lastActivityTime = now; 2306 2307 // First a quick reject: if the app is already at the position we will 2308 // put it, then there is nothing to do. 2309 if (hasActivity) { 2310 final int N = mLruProcesses.size(); 2311 if (N > 0 && mLruProcesses.get(N-1) == app) { 2312 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2313 return; 2314 } 2315 } else { 2316 if (mLruProcessServiceStart > 0 2317 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2318 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2319 return; 2320 } 2321 } 2322 2323 int lrui = mLruProcesses.lastIndexOf(app); 2324 2325 if (app.persistent && lrui >= 0) { 2326 // We don't care about the position of persistent processes, as long as 2327 // they are in the list. 2328 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2329 return; 2330 } 2331 2332 /* In progress: compute new position first, so we can avoid doing work 2333 if the process is not actually going to move. Not yet working. 2334 int addIndex; 2335 int nextIndex; 2336 boolean inActivity = false, inService = false; 2337 if (hasActivity) { 2338 // Process has activities, put it at the very tipsy-top. 2339 addIndex = mLruProcesses.size(); 2340 nextIndex = mLruProcessServiceStart; 2341 inActivity = true; 2342 } else if (hasService) { 2343 // Process has services, put it at the top of the service list. 2344 addIndex = mLruProcessActivityStart; 2345 nextIndex = mLruProcessServiceStart; 2346 inActivity = true; 2347 inService = true; 2348 } else { 2349 // Process not otherwise of interest, it goes to the top of the non-service area. 2350 addIndex = mLruProcessServiceStart; 2351 if (client != null) { 2352 int clientIndex = mLruProcesses.lastIndexOf(client); 2353 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2354 + app); 2355 if (clientIndex >= 0 && addIndex > clientIndex) { 2356 addIndex = clientIndex; 2357 } 2358 } 2359 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2360 } 2361 2362 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2363 + mLruProcessActivityStart + "): " + app); 2364 */ 2365 2366 if (lrui >= 0) { 2367 if (lrui < mLruProcessActivityStart) { 2368 mLruProcessActivityStart--; 2369 } 2370 if (lrui < mLruProcessServiceStart) { 2371 mLruProcessServiceStart--; 2372 } 2373 /* 2374 if (addIndex > lrui) { 2375 addIndex--; 2376 } 2377 if (nextIndex > lrui) { 2378 nextIndex--; 2379 } 2380 */ 2381 mLruProcesses.remove(lrui); 2382 } 2383 2384 /* 2385 mLruProcesses.add(addIndex, app); 2386 if (inActivity) { 2387 mLruProcessActivityStart++; 2388 } 2389 if (inService) { 2390 mLruProcessActivityStart++; 2391 } 2392 */ 2393 2394 int nextIndex; 2395 if (hasActivity) { 2396 final int N = mLruProcesses.size(); 2397 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2398 // Process doesn't have activities, but has clients with 2399 // activities... move it up, but one below the top (the top 2400 // should always have a real activity). 2401 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2402 mLruProcesses.add(N-1, app); 2403 // To keep it from spamming the LRU list (by making a bunch of clients), 2404 // we will push down any other entries owned by the app. 2405 final int uid = app.info.uid; 2406 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2407 ProcessRecord subProc = mLruProcesses.get(i); 2408 if (subProc.info.uid == uid) { 2409 // We want to push this one down the list. If the process after 2410 // it is for the same uid, however, don't do so, because we don't 2411 // want them internally to be re-ordered. 2412 if (mLruProcesses.get(i-1).info.uid != uid) { 2413 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2414 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2415 ProcessRecord tmp = mLruProcesses.get(i); 2416 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2417 mLruProcesses.set(i-1, tmp); 2418 i--; 2419 } 2420 } else { 2421 // A gap, we can stop here. 2422 break; 2423 } 2424 } 2425 } else { 2426 // Process has activities, put it at the very tipsy-top. 2427 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2428 mLruProcesses.add(app); 2429 } 2430 nextIndex = mLruProcessServiceStart; 2431 } else if (hasService) { 2432 // Process has services, put it at the top of the service list. 2433 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2434 mLruProcesses.add(mLruProcessActivityStart, app); 2435 nextIndex = mLruProcessServiceStart; 2436 mLruProcessActivityStart++; 2437 } else { 2438 // Process not otherwise of interest, it goes to the top of the non-service area. 2439 int index = mLruProcessServiceStart; 2440 if (client != null) { 2441 // If there is a client, don't allow the process to be moved up higher 2442 // in the list than that client. 2443 int clientIndex = mLruProcesses.lastIndexOf(client); 2444 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2445 + " when updating " + app); 2446 if (clientIndex <= lrui) { 2447 // Don't allow the client index restriction to push it down farther in the 2448 // list than it already is. 2449 clientIndex = lrui; 2450 } 2451 if (clientIndex >= 0 && index > clientIndex) { 2452 index = clientIndex; 2453 } 2454 } 2455 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2456 mLruProcesses.add(index, app); 2457 nextIndex = index-1; 2458 mLruProcessActivityStart++; 2459 mLruProcessServiceStart++; 2460 } 2461 2462 // If the app is currently using a content provider or service, 2463 // bump those processes as well. 2464 for (int j=app.connections.size()-1; j>=0; j--) { 2465 ConnectionRecord cr = app.connections.valueAt(j); 2466 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2467 && cr.binding.service.app != null 2468 && cr.binding.service.app.lruSeq != mLruSeq 2469 && !cr.binding.service.app.persistent) { 2470 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2471 "service connection", cr, app); 2472 } 2473 } 2474 for (int j=app.conProviders.size()-1; j>=0; j--) { 2475 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2476 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2477 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2478 "provider reference", cpr, app); 2479 } 2480 } 2481 } 2482 2483 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2484 if (uid == Process.SYSTEM_UID) { 2485 // The system gets to run in any process. If there are multiple 2486 // processes with the same uid, just pick the first (this 2487 // should never happen). 2488 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2489 if (procs == null) return null; 2490 final int N = procs.size(); 2491 for (int i = 0; i < N; i++) { 2492 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2493 } 2494 } 2495 ProcessRecord proc = mProcessNames.get(processName, uid); 2496 if (false && proc != null && !keepIfLarge 2497 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2498 && proc.lastCachedPss >= 4000) { 2499 // Turn this condition on to cause killing to happen regularly, for testing. 2500 if (proc.baseProcessTracker != null) { 2501 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2502 } 2503 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2504 + "k from cached"); 2505 } else if (proc != null && !keepIfLarge 2506 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2507 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2508 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2509 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2510 if (proc.baseProcessTracker != null) { 2511 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2512 } 2513 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2514 + "k from cached"); 2515 } 2516 } 2517 return proc; 2518 } 2519 2520 void ensurePackageDexOpt(String packageName) { 2521 IPackageManager pm = AppGlobals.getPackageManager(); 2522 try { 2523 if (pm.performDexOpt(packageName)) { 2524 mDidDexOpt = true; 2525 } 2526 } catch (RemoteException e) { 2527 } 2528 } 2529 2530 boolean isNextTransitionForward() { 2531 int transit = mWindowManager.getPendingAppTransition(); 2532 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2533 || transit == AppTransition.TRANSIT_TASK_OPEN 2534 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2535 } 2536 2537 final ProcessRecord startProcessLocked(String processName, 2538 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2539 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2540 boolean isolated, boolean keepIfLarge) { 2541 ProcessRecord app; 2542 if (!isolated) { 2543 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2544 } else { 2545 // If this is an isolated process, it can't re-use an existing process. 2546 app = null; 2547 } 2548 // We don't have to do anything more if: 2549 // (1) There is an existing application record; and 2550 // (2) The caller doesn't think it is dead, OR there is no thread 2551 // object attached to it so we know it couldn't have crashed; and 2552 // (3) There is a pid assigned to it, so it is either starting or 2553 // already running. 2554 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2555 + " app=" + app + " knownToBeDead=" + knownToBeDead 2556 + " thread=" + (app != null ? app.thread : null) 2557 + " pid=" + (app != null ? app.pid : -1)); 2558 if (app != null && app.pid > 0) { 2559 if (!knownToBeDead || app.thread == null) { 2560 // We already have the app running, or are waiting for it to 2561 // come up (we have a pid but not yet its thread), so keep it. 2562 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2563 // If this is a new package in the process, add the package to the list 2564 app.addPackage(info.packageName, mProcessStats); 2565 return app; 2566 } 2567 2568 // An application record is attached to a previous process, 2569 // clean it up now. 2570 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2571 handleAppDiedLocked(app, true, true); 2572 } 2573 2574 String hostingNameStr = hostingName != null 2575 ? hostingName.flattenToShortString() : null; 2576 2577 if (!isolated) { 2578 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2579 // If we are in the background, then check to see if this process 2580 // is bad. If so, we will just silently fail. 2581 if (mBadProcesses.get(info.processName, info.uid) != null) { 2582 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2583 + "/" + info.processName); 2584 return null; 2585 } 2586 } else { 2587 // When the user is explicitly starting a process, then clear its 2588 // crash count so that we won't make it bad until they see at 2589 // least one crash dialog again, and make the process good again 2590 // if it had been bad. 2591 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2592 + "/" + info.processName); 2593 mProcessCrashTimes.remove(info.processName, info.uid); 2594 if (mBadProcesses.get(info.processName, info.uid) != null) { 2595 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2596 UserHandle.getUserId(info.uid), info.uid, 2597 info.processName); 2598 mBadProcesses.remove(info.processName, info.uid); 2599 if (app != null) { 2600 app.bad = false; 2601 } 2602 } 2603 } 2604 } 2605 2606 if (app == null) { 2607 app = newProcessRecordLocked(info, processName, isolated); 2608 if (app == null) { 2609 Slog.w(TAG, "Failed making new process record for " 2610 + processName + "/" + info.uid + " isolated=" + isolated); 2611 return null; 2612 } 2613 mProcessNames.put(processName, app.uid, app); 2614 if (isolated) { 2615 mIsolatedProcesses.put(app.uid, app); 2616 } 2617 } else { 2618 // If this is a new package in the process, add the package to the list 2619 app.addPackage(info.packageName, mProcessStats); 2620 } 2621 2622 // If the system is not ready yet, then hold off on starting this 2623 // process until it is. 2624 if (!mProcessesReady 2625 && !isAllowedWhileBooting(info) 2626 && !allowWhileBooting) { 2627 if (!mProcessesOnHold.contains(app)) { 2628 mProcessesOnHold.add(app); 2629 } 2630 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2631 return app; 2632 } 2633 2634 startProcessLocked(app, hostingType, hostingNameStr); 2635 return (app.pid != 0) ? app : null; 2636 } 2637 2638 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2639 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2640 } 2641 2642 private final void startProcessLocked(ProcessRecord app, 2643 String hostingType, String hostingNameStr) { 2644 if (app.pid > 0 && app.pid != MY_PID) { 2645 synchronized (mPidsSelfLocked) { 2646 mPidsSelfLocked.remove(app.pid); 2647 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2648 } 2649 app.setPid(0); 2650 } 2651 2652 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2653 "startProcessLocked removing on hold: " + app); 2654 mProcessesOnHold.remove(app); 2655 2656 updateCpuStats(); 2657 2658 try { 2659 int uid = app.uid; 2660 2661 int[] gids = null; 2662 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2663 if (!app.isolated) { 2664 int[] permGids = null; 2665 try { 2666 final PackageManager pm = mContext.getPackageManager(); 2667 permGids = pm.getPackageGids(app.info.packageName); 2668 2669 if (Environment.isExternalStorageEmulated()) { 2670 if (pm.checkPermission( 2671 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2672 app.info.packageName) == PERMISSION_GRANTED) { 2673 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2674 } else { 2675 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2676 } 2677 } 2678 } catch (PackageManager.NameNotFoundException e) { 2679 Slog.w(TAG, "Unable to retrieve gids", e); 2680 } 2681 2682 /* 2683 * Add shared application GID so applications can share some 2684 * resources like shared libraries 2685 */ 2686 if (permGids == null) { 2687 gids = new int[1]; 2688 } else { 2689 gids = new int[permGids.length + 1]; 2690 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2691 } 2692 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2693 } 2694 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2695 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2696 && mTopComponent != null 2697 && app.processName.equals(mTopComponent.getPackageName())) { 2698 uid = 0; 2699 } 2700 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2701 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2702 uid = 0; 2703 } 2704 } 2705 int debugFlags = 0; 2706 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2707 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2708 // Also turn on CheckJNI for debuggable apps. It's quite 2709 // awkward to turn on otherwise. 2710 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2711 } 2712 // Run the app in safe mode if its manifest requests so or the 2713 // system is booted in safe mode. 2714 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2715 Zygote.systemInSafeMode == true) { 2716 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2717 } 2718 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2719 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2720 } 2721 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2722 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2723 } 2724 if ("1".equals(SystemProperties.get("debug.assert"))) { 2725 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2726 } 2727 2728 // Start the process. It will either succeed and return a result containing 2729 // the PID of the new process, or else throw a RuntimeException. 2730 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2731 app.processName, uid, uid, gids, debugFlags, mountExternal, 2732 app.info.targetSdkVersion, app.info.seinfo, null); 2733 2734 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2735 synchronized (bs) { 2736 if (bs.isOnBattery()) { 2737 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2738 } 2739 } 2740 2741 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2742 UserHandle.getUserId(uid), startResult.pid, uid, 2743 app.processName, hostingType, 2744 hostingNameStr != null ? hostingNameStr : ""); 2745 2746 if (app.persistent) { 2747 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2748 } 2749 2750 StringBuilder buf = mStringBuilder; 2751 buf.setLength(0); 2752 buf.append("Start proc "); 2753 buf.append(app.processName); 2754 buf.append(" for "); 2755 buf.append(hostingType); 2756 if (hostingNameStr != null) { 2757 buf.append(" "); 2758 buf.append(hostingNameStr); 2759 } 2760 buf.append(": pid="); 2761 buf.append(startResult.pid); 2762 buf.append(" uid="); 2763 buf.append(uid); 2764 buf.append(" gids={"); 2765 if (gids != null) { 2766 for (int gi=0; gi<gids.length; gi++) { 2767 if (gi != 0) buf.append(", "); 2768 buf.append(gids[gi]); 2769 2770 } 2771 } 2772 buf.append("}"); 2773 Slog.i(TAG, buf.toString()); 2774 app.setPid(startResult.pid); 2775 app.usingWrapper = startResult.usingWrapper; 2776 app.removed = false; 2777 synchronized (mPidsSelfLocked) { 2778 this.mPidsSelfLocked.put(startResult.pid, app); 2779 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2780 msg.obj = app; 2781 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2782 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2783 } 2784 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2785 app.processName, app.info.uid); 2786 if (app.isolated) { 2787 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2788 } 2789 } catch (RuntimeException e) { 2790 // XXX do better error recovery. 2791 app.setPid(0); 2792 Slog.e(TAG, "Failure starting process " + app.processName, e); 2793 } 2794 } 2795 2796 void updateUsageStats(ActivityRecord component, boolean resumed) { 2797 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2798 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2799 if (resumed) { 2800 mUsageStatsService.noteResumeComponent(component.realActivity); 2801 synchronized (stats) { 2802 stats.noteActivityResumedLocked(component.app.uid); 2803 } 2804 } else { 2805 mUsageStatsService.notePauseComponent(component.realActivity); 2806 synchronized (stats) { 2807 stats.noteActivityPausedLocked(component.app.uid); 2808 } 2809 } 2810 } 2811 2812 Intent getHomeIntent() { 2813 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2814 intent.setComponent(mTopComponent); 2815 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2816 intent.addCategory(Intent.CATEGORY_HOME); 2817 } 2818 return intent; 2819 } 2820 2821 boolean startHomeActivityLocked(int userId) { 2822 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2823 && mTopAction == null) { 2824 // We are running in factory test mode, but unable to find 2825 // the factory test app, so just sit around displaying the 2826 // error message and don't try to start anything. 2827 return false; 2828 } 2829 Intent intent = getHomeIntent(); 2830 ActivityInfo aInfo = 2831 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2832 if (aInfo != null) { 2833 intent.setComponent(new ComponentName( 2834 aInfo.applicationInfo.packageName, aInfo.name)); 2835 // Don't do this if the home app is currently being 2836 // instrumented. 2837 aInfo = new ActivityInfo(aInfo); 2838 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2839 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2840 aInfo.applicationInfo.uid, true); 2841 if (app == null || app.instrumentationClass == null) { 2842 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2843 mStackSupervisor.startHomeActivity(intent, aInfo); 2844 } 2845 } 2846 2847 return true; 2848 } 2849 2850 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2851 ActivityInfo ai = null; 2852 ComponentName comp = intent.getComponent(); 2853 try { 2854 if (comp != null) { 2855 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2856 } else { 2857 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2858 intent, 2859 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2860 flags, userId); 2861 2862 if (info != null) { 2863 ai = info.activityInfo; 2864 } 2865 } 2866 } catch (RemoteException e) { 2867 // ignore 2868 } 2869 2870 return ai; 2871 } 2872 2873 /** 2874 * Starts the "new version setup screen" if appropriate. 2875 */ 2876 void startSetupActivityLocked() { 2877 // Only do this once per boot. 2878 if (mCheckedForSetup) { 2879 return; 2880 } 2881 2882 // We will show this screen if the current one is a different 2883 // version than the last one shown, and we are not running in 2884 // low-level factory test mode. 2885 final ContentResolver resolver = mContext.getContentResolver(); 2886 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2887 Settings.Global.getInt(resolver, 2888 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2889 mCheckedForSetup = true; 2890 2891 // See if we should be showing the platform update setup UI. 2892 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2893 List<ResolveInfo> ris = mContext.getPackageManager() 2894 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2895 2896 // We don't allow third party apps to replace this. 2897 ResolveInfo ri = null; 2898 for (int i=0; ris != null && i<ris.size(); i++) { 2899 if ((ris.get(i).activityInfo.applicationInfo.flags 2900 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2901 ri = ris.get(i); 2902 break; 2903 } 2904 } 2905 2906 if (ri != null) { 2907 String vers = ri.activityInfo.metaData != null 2908 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2909 : null; 2910 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2911 vers = ri.activityInfo.applicationInfo.metaData.getString( 2912 Intent.METADATA_SETUP_VERSION); 2913 } 2914 String lastVers = Settings.Secure.getString( 2915 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2916 if (vers != null && !vers.equals(lastVers)) { 2917 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2918 intent.setComponent(new ComponentName( 2919 ri.activityInfo.packageName, ri.activityInfo.name)); 2920 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2921 null, null, 0, 0, 0, null, 0, null, false, null, null); 2922 } 2923 } 2924 } 2925 } 2926 2927 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2928 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2929 } 2930 2931 void enforceNotIsolatedCaller(String caller) { 2932 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2933 throw new SecurityException("Isolated process not allowed to call " + caller); 2934 } 2935 } 2936 2937 @Override 2938 public int getFrontActivityScreenCompatMode() { 2939 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2940 synchronized (this) { 2941 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2942 } 2943 } 2944 2945 @Override 2946 public void setFrontActivityScreenCompatMode(int mode) { 2947 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2948 "setFrontActivityScreenCompatMode"); 2949 synchronized (this) { 2950 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2951 } 2952 } 2953 2954 @Override 2955 public int getPackageScreenCompatMode(String packageName) { 2956 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2957 synchronized (this) { 2958 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2959 } 2960 } 2961 2962 @Override 2963 public void setPackageScreenCompatMode(String packageName, int mode) { 2964 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2965 "setPackageScreenCompatMode"); 2966 synchronized (this) { 2967 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2968 } 2969 } 2970 2971 @Override 2972 public boolean getPackageAskScreenCompat(String packageName) { 2973 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2974 synchronized (this) { 2975 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2976 } 2977 } 2978 2979 @Override 2980 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2981 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2982 "setPackageAskScreenCompat"); 2983 synchronized (this) { 2984 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2985 } 2986 } 2987 2988 private void dispatchProcessesChanged() { 2989 int N; 2990 synchronized (this) { 2991 N = mPendingProcessChanges.size(); 2992 if (mActiveProcessChanges.length < N) { 2993 mActiveProcessChanges = new ProcessChangeItem[N]; 2994 } 2995 mPendingProcessChanges.toArray(mActiveProcessChanges); 2996 mAvailProcessChanges.addAll(mPendingProcessChanges); 2997 mPendingProcessChanges.clear(); 2998 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2999 } 3000 3001 int i = mProcessObservers.beginBroadcast(); 3002 while (i > 0) { 3003 i--; 3004 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3005 if (observer != null) { 3006 try { 3007 for (int j=0; j<N; j++) { 3008 ProcessChangeItem item = mActiveProcessChanges[j]; 3009 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3010 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3011 + item.pid + " uid=" + item.uid + ": " 3012 + item.foregroundActivities); 3013 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3014 item.foregroundActivities); 3015 } 3016 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3017 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3018 + item.pid + " uid=" + item.uid + ": " + item.importance); 3019 observer.onImportanceChanged(item.pid, item.uid, 3020 item.importance); 3021 } 3022 } 3023 } catch (RemoteException e) { 3024 } 3025 } 3026 } 3027 mProcessObservers.finishBroadcast(); 3028 } 3029 3030 private void dispatchProcessDied(int pid, int uid) { 3031 int i = mProcessObservers.beginBroadcast(); 3032 while (i > 0) { 3033 i--; 3034 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3035 if (observer != null) { 3036 try { 3037 observer.onProcessDied(pid, uid); 3038 } catch (RemoteException e) { 3039 } 3040 } 3041 } 3042 mProcessObservers.finishBroadcast(); 3043 } 3044 3045 final void doPendingActivityLaunchesLocked(boolean doResume) { 3046 final int N = mPendingActivityLaunches.size(); 3047 if (N <= 0) { 3048 return; 3049 } 3050 for (int i=0; i<N; i++) { 3051 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3052 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3053 doResume && i == (N-1), null); 3054 } 3055 mPendingActivityLaunches.clear(); 3056 } 3057 3058 @Override 3059 public final int startActivity(IApplicationThread caller, String callingPackage, 3060 Intent intent, String resolvedType, IBinder resultTo, 3061 String resultWho, int requestCode, int startFlags, 3062 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3063 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3064 resultWho, requestCode, 3065 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3066 } 3067 3068 @Override 3069 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3070 Intent intent, String resolvedType, IBinder resultTo, 3071 String resultWho, int requestCode, int startFlags, 3072 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3073 enforceNotIsolatedCaller("startActivity"); 3074 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3075 false, true, "startActivity", null); 3076 // TODO: Switch to user app stacks here. 3077 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3078 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3079 null, null, options, userId, null); 3080 } 3081 3082 @Override 3083 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3084 Intent intent, String resolvedType, IBinder resultTo, 3085 String resultWho, int requestCode, int startFlags, String profileFile, 3086 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3087 enforceNotIsolatedCaller("startActivityAndWait"); 3088 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3089 false, true, "startActivityAndWait", null); 3090 WaitResult res = new WaitResult(); 3091 // TODO: Switch to user app stacks here. 3092 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3093 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3094 res, null, options, UserHandle.getCallingUserId(), null); 3095 return res; 3096 } 3097 3098 @Override 3099 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3100 Intent intent, String resolvedType, IBinder resultTo, 3101 String resultWho, int requestCode, int startFlags, Configuration config, 3102 Bundle options, int userId) { 3103 enforceNotIsolatedCaller("startActivityWithConfig"); 3104 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3105 false, true, "startActivityWithConfig", null); 3106 // TODO: Switch to user app stacks here. 3107 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3108 resolvedType, resultTo, resultWho, requestCode, startFlags, 3109 null, null, null, config, options, userId, null); 3110 return ret; 3111 } 3112 3113 @Override 3114 public int startActivityIntentSender(IApplicationThread caller, 3115 IntentSender intent, Intent fillInIntent, String resolvedType, 3116 IBinder resultTo, String resultWho, int requestCode, 3117 int flagsMask, int flagsValues, Bundle options) { 3118 enforceNotIsolatedCaller("startActivityIntentSender"); 3119 // Refuse possible leaked file descriptors 3120 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3121 throw new IllegalArgumentException("File descriptors passed in Intent"); 3122 } 3123 3124 IIntentSender sender = intent.getTarget(); 3125 if (!(sender instanceof PendingIntentRecord)) { 3126 throw new IllegalArgumentException("Bad PendingIntent object"); 3127 } 3128 3129 PendingIntentRecord pir = (PendingIntentRecord)sender; 3130 3131 synchronized (this) { 3132 // If this is coming from the currently resumed activity, it is 3133 // effectively saying that app switches are allowed at this point. 3134 final ActivityStack stack = getFocusedStack(); 3135 if (stack.mResumedActivity != null && 3136 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3137 mAppSwitchesAllowedTime = 0; 3138 } 3139 } 3140 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3141 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3142 return ret; 3143 } 3144 3145 @Override 3146 public boolean startNextMatchingActivity(IBinder callingActivity, 3147 Intent intent, Bundle options) { 3148 // Refuse possible leaked file descriptors 3149 if (intent != null && intent.hasFileDescriptors() == true) { 3150 throw new IllegalArgumentException("File descriptors passed in Intent"); 3151 } 3152 3153 synchronized (this) { 3154 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3155 if (r == null) { 3156 ActivityOptions.abort(options); 3157 return false; 3158 } 3159 if (r.app == null || r.app.thread == null) { 3160 // The caller is not running... d'oh! 3161 ActivityOptions.abort(options); 3162 return false; 3163 } 3164 intent = new Intent(intent); 3165 // The caller is not allowed to change the data. 3166 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3167 // And we are resetting to find the next component... 3168 intent.setComponent(null); 3169 3170 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3171 3172 ActivityInfo aInfo = null; 3173 try { 3174 List<ResolveInfo> resolves = 3175 AppGlobals.getPackageManager().queryIntentActivities( 3176 intent, r.resolvedType, 3177 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3178 UserHandle.getCallingUserId()); 3179 3180 // Look for the original activity in the list... 3181 final int N = resolves != null ? resolves.size() : 0; 3182 for (int i=0; i<N; i++) { 3183 ResolveInfo rInfo = resolves.get(i); 3184 if (rInfo.activityInfo.packageName.equals(r.packageName) 3185 && rInfo.activityInfo.name.equals(r.info.name)) { 3186 // We found the current one... the next matching is 3187 // after it. 3188 i++; 3189 if (i<N) { 3190 aInfo = resolves.get(i).activityInfo; 3191 } 3192 if (debug) { 3193 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3194 + "/" + r.info.name); 3195 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3196 + "/" + aInfo.name); 3197 } 3198 break; 3199 } 3200 } 3201 } catch (RemoteException e) { 3202 } 3203 3204 if (aInfo == null) { 3205 // Nobody who is next! 3206 ActivityOptions.abort(options); 3207 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3208 return false; 3209 } 3210 3211 intent.setComponent(new ComponentName( 3212 aInfo.applicationInfo.packageName, aInfo.name)); 3213 intent.setFlags(intent.getFlags()&~( 3214 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3215 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3216 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3217 Intent.FLAG_ACTIVITY_NEW_TASK)); 3218 3219 // Okay now we need to start the new activity, replacing the 3220 // currently running activity. This is a little tricky because 3221 // we want to start the new one as if the current one is finished, 3222 // but not finish the current one first so that there is no flicker. 3223 // And thus... 3224 final boolean wasFinishing = r.finishing; 3225 r.finishing = true; 3226 3227 // Propagate reply information over to the new activity. 3228 final ActivityRecord resultTo = r.resultTo; 3229 final String resultWho = r.resultWho; 3230 final int requestCode = r.requestCode; 3231 r.resultTo = null; 3232 if (resultTo != null) { 3233 resultTo.removeResultsLocked(r, resultWho, requestCode); 3234 } 3235 3236 final long origId = Binder.clearCallingIdentity(); 3237 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3238 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3239 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3240 options, false, null, null); 3241 Binder.restoreCallingIdentity(origId); 3242 3243 r.finishing = wasFinishing; 3244 if (res != ActivityManager.START_SUCCESS) { 3245 return false; 3246 } 3247 return true; 3248 } 3249 } 3250 3251 final int startActivityInPackage(int uid, String callingPackage, 3252 Intent intent, String resolvedType, IBinder resultTo, 3253 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3254 IActivityContainer container) { 3255 3256 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3257 false, true, "startActivityInPackage", null); 3258 3259 // TODO: Switch to user app stacks here. 3260 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3261 resultTo, resultWho, requestCode, startFlags, 3262 null, null, null, null, options, userId, container); 3263 return ret; 3264 } 3265 3266 @Override 3267 public final int startActivities(IApplicationThread caller, String callingPackage, 3268 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3269 int userId) { 3270 enforceNotIsolatedCaller("startActivities"); 3271 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3272 false, true, "startActivity", null); 3273 // TODO: Switch to user app stacks here. 3274 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3275 resolvedTypes, resultTo, options, userId); 3276 return ret; 3277 } 3278 3279 final int startActivitiesInPackage(int uid, String callingPackage, 3280 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3281 Bundle options, int userId) { 3282 3283 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3284 false, true, "startActivityInPackage", null); 3285 // TODO: Switch to user app stacks here. 3286 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3287 resultTo, options, userId); 3288 return ret; 3289 } 3290 3291 final void addRecentTaskLocked(TaskRecord task) { 3292 int N = mRecentTasks.size(); 3293 // Quick case: check if the top-most recent task is the same. 3294 if (N > 0 && mRecentTasks.get(0) == task) { 3295 return; 3296 } 3297 // Remove any existing entries that are the same kind of task. 3298 for (int i=0; i<N; i++) { 3299 TaskRecord tr = mRecentTasks.get(i); 3300 if (task.userId == tr.userId 3301 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 3302 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 3303 tr.disposeThumbnail(); 3304 mRecentTasks.remove(i); 3305 i--; 3306 N--; 3307 if (task.intent == null) { 3308 // If the new recent task we are adding is not fully 3309 // specified, then replace it with the existing recent task. 3310 task = tr; 3311 } 3312 } 3313 } 3314 if (N >= MAX_RECENT_TASKS) { 3315 mRecentTasks.remove(N-1).disposeThumbnail(); 3316 } 3317 mRecentTasks.add(0, task); 3318 } 3319 3320 @Override 3321 public void reportActivityFullyDrawn(IBinder token) { 3322 synchronized (this) { 3323 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3324 if (r == null) { 3325 return; 3326 } 3327 r.reportFullyDrawnLocked(); 3328 } 3329 } 3330 3331 @Override 3332 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3333 synchronized (this) { 3334 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3335 if (r == null) { 3336 return; 3337 } 3338 final long origId = Binder.clearCallingIdentity(); 3339 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3340 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3341 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3342 if (config != null) { 3343 r.frozenBeforeDestroy = true; 3344 if (!updateConfigurationLocked(config, r, false, false)) { 3345 mStackSupervisor.resumeTopActivitiesLocked(); 3346 } 3347 } 3348 Binder.restoreCallingIdentity(origId); 3349 } 3350 } 3351 3352 @Override 3353 public int getRequestedOrientation(IBinder token) { 3354 synchronized (this) { 3355 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3356 if (r == null) { 3357 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3358 } 3359 return mWindowManager.getAppOrientation(r.appToken); 3360 } 3361 } 3362 3363 /** 3364 * This is the internal entry point for handling Activity.finish(). 3365 * 3366 * @param token The Binder token referencing the Activity we want to finish. 3367 * @param resultCode Result code, if any, from this Activity. 3368 * @param resultData Result data (Intent), if any, from this Activity. 3369 * 3370 * @return Returns true if the activity successfully finished, or false if it is still running. 3371 */ 3372 @Override 3373 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3374 // Refuse possible leaked file descriptors 3375 if (resultData != null && resultData.hasFileDescriptors() == true) { 3376 throw new IllegalArgumentException("File descriptors passed in Intent"); 3377 } 3378 3379 synchronized(this) { 3380 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3381 if (r == null) { 3382 return true; 3383 } 3384 if (mController != null) { 3385 // Find the first activity that is not finishing. 3386 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3387 if (next != null) { 3388 // ask watcher if this is allowed 3389 boolean resumeOK = true; 3390 try { 3391 resumeOK = mController.activityResuming(next.packageName); 3392 } catch (RemoteException e) { 3393 mController = null; 3394 Watchdog.getInstance().setActivityController(null); 3395 } 3396 3397 if (!resumeOK) { 3398 return false; 3399 } 3400 } 3401 } 3402 final long origId = Binder.clearCallingIdentity(); 3403 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3404 resultData, "app-request", true); 3405 Binder.restoreCallingIdentity(origId); 3406 return res; 3407 } 3408 } 3409 3410 @Override 3411 public final void finishHeavyWeightApp() { 3412 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3413 != PackageManager.PERMISSION_GRANTED) { 3414 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3415 + Binder.getCallingPid() 3416 + ", uid=" + Binder.getCallingUid() 3417 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3418 Slog.w(TAG, msg); 3419 throw new SecurityException(msg); 3420 } 3421 3422 synchronized(this) { 3423 if (mHeavyWeightProcess == null) { 3424 return; 3425 } 3426 3427 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3428 mHeavyWeightProcess.activities); 3429 for (int i=0; i<activities.size(); i++) { 3430 ActivityRecord r = activities.get(i); 3431 if (!r.finishing) { 3432 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3433 null, "finish-heavy", true); 3434 } 3435 } 3436 3437 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3438 mHeavyWeightProcess.userId, 0)); 3439 mHeavyWeightProcess = null; 3440 } 3441 } 3442 3443 @Override 3444 public void crashApplication(int uid, int initialPid, String packageName, 3445 String message) { 3446 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3447 != PackageManager.PERMISSION_GRANTED) { 3448 String msg = "Permission Denial: crashApplication() from pid=" 3449 + Binder.getCallingPid() 3450 + ", uid=" + Binder.getCallingUid() 3451 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3452 Slog.w(TAG, msg); 3453 throw new SecurityException(msg); 3454 } 3455 3456 synchronized(this) { 3457 ProcessRecord proc = null; 3458 3459 // Figure out which process to kill. We don't trust that initialPid 3460 // still has any relation to current pids, so must scan through the 3461 // list. 3462 synchronized (mPidsSelfLocked) { 3463 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3464 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3465 if (p.uid != uid) { 3466 continue; 3467 } 3468 if (p.pid == initialPid) { 3469 proc = p; 3470 break; 3471 } 3472 if (p.pkgList.containsKey(packageName)) { 3473 proc = p; 3474 } 3475 } 3476 } 3477 3478 if (proc == null) { 3479 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3480 + " initialPid=" + initialPid 3481 + " packageName=" + packageName); 3482 return; 3483 } 3484 3485 if (proc.thread != null) { 3486 if (proc.pid == Process.myPid()) { 3487 Log.w(TAG, "crashApplication: trying to crash self!"); 3488 return; 3489 } 3490 long ident = Binder.clearCallingIdentity(); 3491 try { 3492 proc.thread.scheduleCrash(message); 3493 } catch (RemoteException e) { 3494 } 3495 Binder.restoreCallingIdentity(ident); 3496 } 3497 } 3498 } 3499 3500 @Override 3501 public final void finishSubActivity(IBinder token, String resultWho, 3502 int requestCode) { 3503 synchronized(this) { 3504 final long origId = Binder.clearCallingIdentity(); 3505 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3506 if (r != null) { 3507 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3508 } 3509 Binder.restoreCallingIdentity(origId); 3510 } 3511 } 3512 3513 @Override 3514 public boolean finishActivityAffinity(IBinder token) { 3515 synchronized(this) { 3516 final long origId = Binder.clearCallingIdentity(); 3517 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3518 boolean res = false; 3519 if (r != null) { 3520 res = r.task.stack.finishActivityAffinityLocked(r); 3521 } 3522 Binder.restoreCallingIdentity(origId); 3523 return res; 3524 } 3525 } 3526 3527 @Override 3528 public boolean willActivityBeVisible(IBinder token) { 3529 synchronized(this) { 3530 ActivityStack stack = ActivityRecord.getStackLocked(token); 3531 if (stack != null) { 3532 return stack.willActivityBeVisibleLocked(token); 3533 } 3534 return false; 3535 } 3536 } 3537 3538 @Override 3539 public void overridePendingTransition(IBinder token, String packageName, 3540 int enterAnim, int exitAnim) { 3541 synchronized(this) { 3542 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3543 if (self == null) { 3544 return; 3545 } 3546 3547 final long origId = Binder.clearCallingIdentity(); 3548 3549 if (self.state == ActivityState.RESUMED 3550 || self.state == ActivityState.PAUSING) { 3551 mWindowManager.overridePendingAppTransition(packageName, 3552 enterAnim, exitAnim, null); 3553 } 3554 3555 Binder.restoreCallingIdentity(origId); 3556 } 3557 } 3558 3559 /** 3560 * Main function for removing an existing process from the activity manager 3561 * as a result of that process going away. Clears out all connections 3562 * to the process. 3563 */ 3564 private final void handleAppDiedLocked(ProcessRecord app, 3565 boolean restarting, boolean allowRestart) { 3566 int pid = app.pid; 3567 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3568 if (!restarting) { 3569 removeLruProcessLocked(app); 3570 if (pid > 0) { 3571 ProcessList.remove(pid); 3572 } 3573 } 3574 3575 if (mProfileProc == app) { 3576 clearProfilerLocked(); 3577 } 3578 3579 // Remove this application's activities from active lists. 3580 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3581 3582 app.activities.clear(); 3583 3584 if (app.instrumentationClass != null) { 3585 Slog.w(TAG, "Crash of app " + app.processName 3586 + " running instrumentation " + app.instrumentationClass); 3587 Bundle info = new Bundle(); 3588 info.putString("shortMsg", "Process crashed."); 3589 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3590 } 3591 3592 if (!restarting) { 3593 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3594 // If there was nothing to resume, and we are not already 3595 // restarting this process, but there is a visible activity that 3596 // is hosted by the process... then make sure all visible 3597 // activities are running, taking care of restarting this 3598 // process. 3599 if (hasVisibleActivities) { 3600 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3601 } 3602 } 3603 } 3604 } 3605 3606 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3607 IBinder threadBinder = thread.asBinder(); 3608 // Find the application record. 3609 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3610 ProcessRecord rec = mLruProcesses.get(i); 3611 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3612 return i; 3613 } 3614 } 3615 return -1; 3616 } 3617 3618 final ProcessRecord getRecordForAppLocked( 3619 IApplicationThread thread) { 3620 if (thread == null) { 3621 return null; 3622 } 3623 3624 int appIndex = getLRURecordIndexForAppLocked(thread); 3625 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3626 } 3627 3628 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3629 // If there are no longer any background processes running, 3630 // and the app that died was not running instrumentation, 3631 // then tell everyone we are now low on memory. 3632 boolean haveBg = false; 3633 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3634 ProcessRecord rec = mLruProcesses.get(i); 3635 if (rec.thread != null 3636 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3637 haveBg = true; 3638 break; 3639 } 3640 } 3641 3642 if (!haveBg) { 3643 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3644 if (doReport) { 3645 long now = SystemClock.uptimeMillis(); 3646 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3647 doReport = false; 3648 } else { 3649 mLastMemUsageReportTime = now; 3650 } 3651 } 3652 final ArrayList<ProcessMemInfo> memInfos 3653 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3654 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3655 long now = SystemClock.uptimeMillis(); 3656 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3657 ProcessRecord rec = mLruProcesses.get(i); 3658 if (rec == dyingProc || rec.thread == null) { 3659 continue; 3660 } 3661 if (doReport) { 3662 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3663 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3664 } 3665 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3666 // The low memory report is overriding any current 3667 // state for a GC request. Make sure to do 3668 // heavy/important/visible/foreground processes first. 3669 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3670 rec.lastRequestedGc = 0; 3671 } else { 3672 rec.lastRequestedGc = rec.lastLowMemory; 3673 } 3674 rec.reportLowMemory = true; 3675 rec.lastLowMemory = now; 3676 mProcessesToGc.remove(rec); 3677 addProcessToGcListLocked(rec); 3678 } 3679 } 3680 if (doReport) { 3681 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3682 mHandler.sendMessage(msg); 3683 } 3684 scheduleAppGcsLocked(); 3685 } 3686 } 3687 3688 final void appDiedLocked(ProcessRecord app, int pid, 3689 IApplicationThread thread) { 3690 3691 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3692 synchronized (stats) { 3693 stats.noteProcessDiedLocked(app.info.uid, pid); 3694 } 3695 3696 // Clean up already done if the process has been re-started. 3697 if (app.pid == pid && app.thread != null && 3698 app.thread.asBinder() == thread.asBinder()) { 3699 boolean doLowMem = app.instrumentationClass == null; 3700 boolean doOomAdj = doLowMem; 3701 if (!app.killedByAm) { 3702 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3703 + ") has died."); 3704 mAllowLowerMemLevel = true; 3705 } else { 3706 // Note that we always want to do oom adj to update our state with the 3707 // new number of procs. 3708 mAllowLowerMemLevel = false; 3709 doLowMem = false; 3710 } 3711 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3712 if (DEBUG_CLEANUP) Slog.v( 3713 TAG, "Dying app: " + app + ", pid: " + pid 3714 + ", thread: " + thread.asBinder()); 3715 handleAppDiedLocked(app, false, true); 3716 3717 if (doOomAdj) { 3718 updateOomAdjLocked(); 3719 } 3720 if (doLowMem) { 3721 doLowMemReportIfNeededLocked(app); 3722 } 3723 } else if (app.pid != pid) { 3724 // A new process has already been started. 3725 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3726 + ") has died and restarted (pid " + app.pid + ")."); 3727 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3728 } else if (DEBUG_PROCESSES) { 3729 Slog.d(TAG, "Received spurious death notification for thread " 3730 + thread.asBinder()); 3731 } 3732 } 3733 3734 /** 3735 * If a stack trace dump file is configured, dump process stack traces. 3736 * @param clearTraces causes the dump file to be erased prior to the new 3737 * traces being written, if true; when false, the new traces will be 3738 * appended to any existing file content. 3739 * @param firstPids of dalvik VM processes to dump stack traces for first 3740 * @param lastPids of dalvik VM processes to dump stack traces for last 3741 * @param nativeProcs optional list of native process names to dump stack crawls 3742 * @return file containing stack traces, or null if no dump file is configured 3743 */ 3744 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3745 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3746 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3747 if (tracesPath == null || tracesPath.length() == 0) { 3748 return null; 3749 } 3750 3751 File tracesFile = new File(tracesPath); 3752 try { 3753 File tracesDir = tracesFile.getParentFile(); 3754 if (!tracesDir.exists()) { 3755 tracesFile.mkdirs(); 3756 if (!SELinux.restorecon(tracesDir)) { 3757 return null; 3758 } 3759 } 3760 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3761 3762 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3763 tracesFile.createNewFile(); 3764 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3765 } catch (IOException e) { 3766 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3767 return null; 3768 } 3769 3770 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3771 return tracesFile; 3772 } 3773 3774 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3775 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3776 // Use a FileObserver to detect when traces finish writing. 3777 // The order of traces is considered important to maintain for legibility. 3778 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3779 @Override 3780 public synchronized void onEvent(int event, String path) { notify(); } 3781 }; 3782 3783 try { 3784 observer.startWatching(); 3785 3786 // First collect all of the stacks of the most important pids. 3787 if (firstPids != null) { 3788 try { 3789 int num = firstPids.size(); 3790 for (int i = 0; i < num; i++) { 3791 synchronized (observer) { 3792 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3793 observer.wait(200); // Wait for write-close, give up after 200msec 3794 } 3795 } 3796 } catch (InterruptedException e) { 3797 Log.wtf(TAG, e); 3798 } 3799 } 3800 3801 // Next collect the stacks of the native pids 3802 if (nativeProcs != null) { 3803 int[] pids = Process.getPidsForCommands(nativeProcs); 3804 if (pids != null) { 3805 for (int pid : pids) { 3806 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3807 } 3808 } 3809 } 3810 3811 // Lastly, measure CPU usage. 3812 if (processCpuTracker != null) { 3813 processCpuTracker.init(); 3814 System.gc(); 3815 processCpuTracker.update(); 3816 try { 3817 synchronized (processCpuTracker) { 3818 processCpuTracker.wait(500); // measure over 1/2 second. 3819 } 3820 } catch (InterruptedException e) { 3821 } 3822 processCpuTracker.update(); 3823 3824 // We'll take the stack crawls of just the top apps using CPU. 3825 final int N = processCpuTracker.countWorkingStats(); 3826 int numProcs = 0; 3827 for (int i=0; i<N && numProcs<5; i++) { 3828 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3829 if (lastPids.indexOfKey(stats.pid) >= 0) { 3830 numProcs++; 3831 try { 3832 synchronized (observer) { 3833 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3834 observer.wait(200); // Wait for write-close, give up after 200msec 3835 } 3836 } catch (InterruptedException e) { 3837 Log.wtf(TAG, e); 3838 } 3839 3840 } 3841 } 3842 } 3843 } finally { 3844 observer.stopWatching(); 3845 } 3846 } 3847 3848 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3849 if (true || IS_USER_BUILD) { 3850 return; 3851 } 3852 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3853 if (tracesPath == null || tracesPath.length() == 0) { 3854 return; 3855 } 3856 3857 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3858 StrictMode.allowThreadDiskWrites(); 3859 try { 3860 final File tracesFile = new File(tracesPath); 3861 final File tracesDir = tracesFile.getParentFile(); 3862 final File tracesTmp = new File(tracesDir, "__tmp__"); 3863 try { 3864 if (!tracesDir.exists()) { 3865 tracesFile.mkdirs(); 3866 if (!SELinux.restorecon(tracesDir.getPath())) { 3867 return; 3868 } 3869 } 3870 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3871 3872 if (tracesFile.exists()) { 3873 tracesTmp.delete(); 3874 tracesFile.renameTo(tracesTmp); 3875 } 3876 StringBuilder sb = new StringBuilder(); 3877 Time tobj = new Time(); 3878 tobj.set(System.currentTimeMillis()); 3879 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3880 sb.append(": "); 3881 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3882 sb.append(" since "); 3883 sb.append(msg); 3884 FileOutputStream fos = new FileOutputStream(tracesFile); 3885 fos.write(sb.toString().getBytes()); 3886 if (app == null) { 3887 fos.write("\n*** No application process!".getBytes()); 3888 } 3889 fos.close(); 3890 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3891 } catch (IOException e) { 3892 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3893 return; 3894 } 3895 3896 if (app != null) { 3897 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3898 firstPids.add(app.pid); 3899 dumpStackTraces(tracesPath, firstPids, null, null, null); 3900 } 3901 3902 File lastTracesFile = null; 3903 File curTracesFile = null; 3904 for (int i=9; i>=0; i--) { 3905 String name = String.format(Locale.US, "slow%02d.txt", i); 3906 curTracesFile = new File(tracesDir, name); 3907 if (curTracesFile.exists()) { 3908 if (lastTracesFile != null) { 3909 curTracesFile.renameTo(lastTracesFile); 3910 } else { 3911 curTracesFile.delete(); 3912 } 3913 } 3914 lastTracesFile = curTracesFile; 3915 } 3916 tracesFile.renameTo(curTracesFile); 3917 if (tracesTmp.exists()) { 3918 tracesTmp.renameTo(tracesFile); 3919 } 3920 } finally { 3921 StrictMode.setThreadPolicy(oldPolicy); 3922 } 3923 } 3924 3925 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3926 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3927 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3928 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3929 3930 if (mController != null) { 3931 try { 3932 // 0 == continue, -1 = kill process immediately 3933 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3934 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3935 } catch (RemoteException e) { 3936 mController = null; 3937 Watchdog.getInstance().setActivityController(null); 3938 } 3939 } 3940 3941 long anrTime = SystemClock.uptimeMillis(); 3942 if (MONITOR_CPU_USAGE) { 3943 updateCpuStatsNow(); 3944 } 3945 3946 synchronized (this) { 3947 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3948 if (mShuttingDown) { 3949 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3950 return; 3951 } else if (app.notResponding) { 3952 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3953 return; 3954 } else if (app.crashing) { 3955 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3956 return; 3957 } 3958 3959 // In case we come through here for the same app before completing 3960 // this one, mark as anring now so we will bail out. 3961 app.notResponding = true; 3962 3963 // Log the ANR to the event log. 3964 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3965 app.processName, app.info.flags, annotation); 3966 3967 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3968 firstPids.add(app.pid); 3969 3970 int parentPid = app.pid; 3971 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3972 if (parentPid != app.pid) firstPids.add(parentPid); 3973 3974 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3975 3976 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3977 ProcessRecord r = mLruProcesses.get(i); 3978 if (r != null && r.thread != null) { 3979 int pid = r.pid; 3980 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3981 if (r.persistent) { 3982 firstPids.add(pid); 3983 } else { 3984 lastPids.put(pid, Boolean.TRUE); 3985 } 3986 } 3987 } 3988 } 3989 } 3990 3991 // Log the ANR to the main log. 3992 StringBuilder info = new StringBuilder(); 3993 info.setLength(0); 3994 info.append("ANR in ").append(app.processName); 3995 if (activity != null && activity.shortComponentName != null) { 3996 info.append(" (").append(activity.shortComponentName).append(")"); 3997 } 3998 info.append("\n"); 3999 info.append("PID: ").append(app.pid).append("\n"); 4000 if (annotation != null) { 4001 info.append("Reason: ").append(annotation).append("\n"); 4002 } 4003 if (parent != null && parent != activity) { 4004 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4005 } 4006 4007 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4008 4009 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4010 NATIVE_STACKS_OF_INTEREST); 4011 4012 String cpuInfo = null; 4013 if (MONITOR_CPU_USAGE) { 4014 updateCpuStatsNow(); 4015 synchronized (mProcessCpuThread) { 4016 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4017 } 4018 info.append(processCpuTracker.printCurrentLoad()); 4019 info.append(cpuInfo); 4020 } 4021 4022 info.append(processCpuTracker.printCurrentState(anrTime)); 4023 4024 Slog.e(TAG, info.toString()); 4025 if (tracesFile == null) { 4026 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4027 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4028 } 4029 4030 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4031 cpuInfo, tracesFile, null); 4032 4033 if (mController != null) { 4034 try { 4035 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4036 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4037 if (res != 0) { 4038 if (res < 0 && app.pid != MY_PID) { 4039 Process.killProcess(app.pid); 4040 } else { 4041 synchronized (this) { 4042 mServices.scheduleServiceTimeoutLocked(app); 4043 } 4044 } 4045 return; 4046 } 4047 } catch (RemoteException e) { 4048 mController = null; 4049 Watchdog.getInstance().setActivityController(null); 4050 } 4051 } 4052 4053 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4054 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4055 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4056 4057 synchronized (this) { 4058 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4059 killUnneededProcessLocked(app, "background ANR"); 4060 return; 4061 } 4062 4063 // Set the app's notResponding state, and look up the errorReportReceiver 4064 makeAppNotRespondingLocked(app, 4065 activity != null ? activity.shortComponentName : null, 4066 annotation != null ? "ANR " + annotation : "ANR", 4067 info.toString()); 4068 4069 // Bring up the infamous App Not Responding dialog 4070 Message msg = Message.obtain(); 4071 HashMap<String, Object> map = new HashMap<String, Object>(); 4072 msg.what = SHOW_NOT_RESPONDING_MSG; 4073 msg.obj = map; 4074 msg.arg1 = aboveSystem ? 1 : 0; 4075 map.put("app", app); 4076 if (activity != null) { 4077 map.put("activity", activity); 4078 } 4079 4080 mHandler.sendMessage(msg); 4081 } 4082 } 4083 4084 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4085 if (!mLaunchWarningShown) { 4086 mLaunchWarningShown = true; 4087 mHandler.post(new Runnable() { 4088 @Override 4089 public void run() { 4090 synchronized (ActivityManagerService.this) { 4091 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4092 d.show(); 4093 mHandler.postDelayed(new Runnable() { 4094 @Override 4095 public void run() { 4096 synchronized (ActivityManagerService.this) { 4097 d.dismiss(); 4098 mLaunchWarningShown = false; 4099 } 4100 } 4101 }, 4000); 4102 } 4103 } 4104 }); 4105 } 4106 } 4107 4108 @Override 4109 public boolean clearApplicationUserData(final String packageName, 4110 final IPackageDataObserver observer, int userId) { 4111 enforceNotIsolatedCaller("clearApplicationUserData"); 4112 int uid = Binder.getCallingUid(); 4113 int pid = Binder.getCallingPid(); 4114 userId = handleIncomingUser(pid, uid, 4115 userId, false, true, "clearApplicationUserData", null); 4116 long callingId = Binder.clearCallingIdentity(); 4117 try { 4118 IPackageManager pm = AppGlobals.getPackageManager(); 4119 int pkgUid = -1; 4120 synchronized(this) { 4121 try { 4122 pkgUid = pm.getPackageUid(packageName, userId); 4123 } catch (RemoteException e) { 4124 } 4125 if (pkgUid == -1) { 4126 Slog.w(TAG, "Invalid packageName: " + packageName); 4127 if (observer != null) { 4128 try { 4129 observer.onRemoveCompleted(packageName, false); 4130 } catch (RemoteException e) { 4131 Slog.i(TAG, "Observer no longer exists."); 4132 } 4133 } 4134 return false; 4135 } 4136 if (uid == pkgUid || checkComponentPermission( 4137 android.Manifest.permission.CLEAR_APP_USER_DATA, 4138 pid, uid, -1, true) 4139 == PackageManager.PERMISSION_GRANTED) { 4140 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4141 } else { 4142 throw new SecurityException("PID " + pid + " does not have permission " 4143 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4144 + " of package " + packageName); 4145 } 4146 } 4147 4148 try { 4149 // Clear application user data 4150 pm.clearApplicationUserData(packageName, observer, userId); 4151 4152 // Remove all permissions granted from/to this package 4153 removeUriPermissionsForPackageLocked(packageName, userId, true); 4154 4155 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4156 Uri.fromParts("package", packageName, null)); 4157 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4158 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4159 null, null, 0, null, null, null, false, false, userId); 4160 } catch (RemoteException e) { 4161 } 4162 } finally { 4163 Binder.restoreCallingIdentity(callingId); 4164 } 4165 return true; 4166 } 4167 4168 @Override 4169 public void killBackgroundProcesses(final String packageName, int userId) { 4170 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4171 != PackageManager.PERMISSION_GRANTED && 4172 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4173 != PackageManager.PERMISSION_GRANTED) { 4174 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4175 + Binder.getCallingPid() 4176 + ", uid=" + Binder.getCallingUid() 4177 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4178 Slog.w(TAG, msg); 4179 throw new SecurityException(msg); 4180 } 4181 4182 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4183 userId, true, true, "killBackgroundProcesses", null); 4184 long callingId = Binder.clearCallingIdentity(); 4185 try { 4186 IPackageManager pm = AppGlobals.getPackageManager(); 4187 synchronized(this) { 4188 int appId = -1; 4189 try { 4190 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4191 } catch (RemoteException e) { 4192 } 4193 if (appId == -1) { 4194 Slog.w(TAG, "Invalid packageName: " + packageName); 4195 return; 4196 } 4197 killPackageProcessesLocked(packageName, appId, userId, 4198 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4199 } 4200 } finally { 4201 Binder.restoreCallingIdentity(callingId); 4202 } 4203 } 4204 4205 @Override 4206 public void killAllBackgroundProcesses() { 4207 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4208 != PackageManager.PERMISSION_GRANTED) { 4209 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4210 + Binder.getCallingPid() 4211 + ", uid=" + Binder.getCallingUid() 4212 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4213 Slog.w(TAG, msg); 4214 throw new SecurityException(msg); 4215 } 4216 4217 long callingId = Binder.clearCallingIdentity(); 4218 try { 4219 synchronized(this) { 4220 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4221 final int NP = mProcessNames.getMap().size(); 4222 for (int ip=0; ip<NP; ip++) { 4223 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4224 final int NA = apps.size(); 4225 for (int ia=0; ia<NA; ia++) { 4226 ProcessRecord app = apps.valueAt(ia); 4227 if (app.persistent) { 4228 // we don't kill persistent processes 4229 continue; 4230 } 4231 if (app.removed) { 4232 procs.add(app); 4233 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4234 app.removed = true; 4235 procs.add(app); 4236 } 4237 } 4238 } 4239 4240 int N = procs.size(); 4241 for (int i=0; i<N; i++) { 4242 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4243 } 4244 mAllowLowerMemLevel = true; 4245 updateOomAdjLocked(); 4246 doLowMemReportIfNeededLocked(null); 4247 } 4248 } finally { 4249 Binder.restoreCallingIdentity(callingId); 4250 } 4251 } 4252 4253 @Override 4254 public void forceStopPackage(final String packageName, int userId) { 4255 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4256 != PackageManager.PERMISSION_GRANTED) { 4257 String msg = "Permission Denial: forceStopPackage() from pid=" 4258 + Binder.getCallingPid() 4259 + ", uid=" + Binder.getCallingUid() 4260 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4261 Slog.w(TAG, msg); 4262 throw new SecurityException(msg); 4263 } 4264 final int callingPid = Binder.getCallingPid(); 4265 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4266 userId, true, true, "forceStopPackage", null); 4267 long callingId = Binder.clearCallingIdentity(); 4268 try { 4269 IPackageManager pm = AppGlobals.getPackageManager(); 4270 synchronized(this) { 4271 int[] users = userId == UserHandle.USER_ALL 4272 ? getUsersLocked() : new int[] { userId }; 4273 for (int user : users) { 4274 int pkgUid = -1; 4275 try { 4276 pkgUid = pm.getPackageUid(packageName, user); 4277 } catch (RemoteException e) { 4278 } 4279 if (pkgUid == -1) { 4280 Slog.w(TAG, "Invalid packageName: " + packageName); 4281 continue; 4282 } 4283 try { 4284 pm.setPackageStoppedState(packageName, true, user); 4285 } catch (RemoteException e) { 4286 } catch (IllegalArgumentException e) { 4287 Slog.w(TAG, "Failed trying to unstop package " 4288 + packageName + ": " + e); 4289 } 4290 if (isUserRunningLocked(user, false)) { 4291 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4292 } 4293 } 4294 } 4295 } finally { 4296 Binder.restoreCallingIdentity(callingId); 4297 } 4298 } 4299 4300 /* 4301 * The pkg name and app id have to be specified. 4302 */ 4303 @Override 4304 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4305 if (pkg == null) { 4306 return; 4307 } 4308 // Make sure the uid is valid. 4309 if (appid < 0) { 4310 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4311 return; 4312 } 4313 int callerUid = Binder.getCallingUid(); 4314 // Only the system server can kill an application 4315 if (callerUid == Process.SYSTEM_UID) { 4316 // Post an aysnc message to kill the application 4317 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4318 msg.arg1 = appid; 4319 msg.arg2 = 0; 4320 Bundle bundle = new Bundle(); 4321 bundle.putString("pkg", pkg); 4322 bundle.putString("reason", reason); 4323 msg.obj = bundle; 4324 mHandler.sendMessage(msg); 4325 } else { 4326 throw new SecurityException(callerUid + " cannot kill pkg: " + 4327 pkg); 4328 } 4329 } 4330 4331 @Override 4332 public void closeSystemDialogs(String reason) { 4333 enforceNotIsolatedCaller("closeSystemDialogs"); 4334 4335 final int pid = Binder.getCallingPid(); 4336 final int uid = Binder.getCallingUid(); 4337 final long origId = Binder.clearCallingIdentity(); 4338 try { 4339 synchronized (this) { 4340 // Only allow this from foreground processes, so that background 4341 // applications can't abuse it to prevent system UI from being shown. 4342 if (uid >= Process.FIRST_APPLICATION_UID) { 4343 ProcessRecord proc; 4344 synchronized (mPidsSelfLocked) { 4345 proc = mPidsSelfLocked.get(pid); 4346 } 4347 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4348 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4349 + " from background process " + proc); 4350 return; 4351 } 4352 } 4353 closeSystemDialogsLocked(reason); 4354 } 4355 } finally { 4356 Binder.restoreCallingIdentity(origId); 4357 } 4358 } 4359 4360 void closeSystemDialogsLocked(String reason) { 4361 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4362 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4363 | Intent.FLAG_RECEIVER_FOREGROUND); 4364 if (reason != null) { 4365 intent.putExtra("reason", reason); 4366 } 4367 mWindowManager.closeSystemDialogs(reason); 4368 4369 mStackSupervisor.closeSystemDialogsLocked(); 4370 4371 broadcastIntentLocked(null, null, intent, null, 4372 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4373 Process.SYSTEM_UID, UserHandle.USER_ALL); 4374 } 4375 4376 @Override 4377 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4378 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4379 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4380 for (int i=pids.length-1; i>=0; i--) { 4381 ProcessRecord proc; 4382 int oomAdj; 4383 synchronized (this) { 4384 synchronized (mPidsSelfLocked) { 4385 proc = mPidsSelfLocked.get(pids[i]); 4386 oomAdj = proc != null ? proc.setAdj : 0; 4387 } 4388 } 4389 infos[i] = new Debug.MemoryInfo(); 4390 Debug.getMemoryInfo(pids[i], infos[i]); 4391 if (proc != null) { 4392 synchronized (this) { 4393 if (proc.thread != null && proc.setAdj == oomAdj) { 4394 // Record this for posterity if the process has been stable. 4395 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4396 infos[i].getTotalUss(), false, proc.pkgList); 4397 } 4398 } 4399 } 4400 } 4401 return infos; 4402 } 4403 4404 @Override 4405 public long[] getProcessPss(int[] pids) { 4406 enforceNotIsolatedCaller("getProcessPss"); 4407 long[] pss = new long[pids.length]; 4408 for (int i=pids.length-1; i>=0; i--) { 4409 ProcessRecord proc; 4410 int oomAdj; 4411 synchronized (this) { 4412 synchronized (mPidsSelfLocked) { 4413 proc = mPidsSelfLocked.get(pids[i]); 4414 oomAdj = proc != null ? proc.setAdj : 0; 4415 } 4416 } 4417 long[] tmpUss = new long[1]; 4418 pss[i] = Debug.getPss(pids[i], tmpUss); 4419 if (proc != null) { 4420 synchronized (this) { 4421 if (proc.thread != null && proc.setAdj == oomAdj) { 4422 // Record this for posterity if the process has been stable. 4423 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4424 } 4425 } 4426 } 4427 } 4428 return pss; 4429 } 4430 4431 @Override 4432 public void killApplicationProcess(String processName, int uid) { 4433 if (processName == null) { 4434 return; 4435 } 4436 4437 int callerUid = Binder.getCallingUid(); 4438 // Only the system server can kill an application 4439 if (callerUid == Process.SYSTEM_UID) { 4440 synchronized (this) { 4441 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4442 if (app != null && app.thread != null) { 4443 try { 4444 app.thread.scheduleSuicide(); 4445 } catch (RemoteException e) { 4446 // If the other end already died, then our work here is done. 4447 } 4448 } else { 4449 Slog.w(TAG, "Process/uid not found attempting kill of " 4450 + processName + " / " + uid); 4451 } 4452 } 4453 } else { 4454 throw new SecurityException(callerUid + " cannot kill app process: " + 4455 processName); 4456 } 4457 } 4458 4459 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4460 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4461 false, true, false, false, UserHandle.getUserId(uid), reason); 4462 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4463 Uri.fromParts("package", packageName, null)); 4464 if (!mProcessesReady) { 4465 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4466 | Intent.FLAG_RECEIVER_FOREGROUND); 4467 } 4468 intent.putExtra(Intent.EXTRA_UID, uid); 4469 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4470 broadcastIntentLocked(null, null, intent, 4471 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4472 false, false, 4473 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4474 } 4475 4476 private void forceStopUserLocked(int userId, String reason) { 4477 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4478 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4479 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4480 | Intent.FLAG_RECEIVER_FOREGROUND); 4481 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4482 broadcastIntentLocked(null, null, intent, 4483 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4484 false, false, 4485 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4486 } 4487 4488 private final boolean killPackageProcessesLocked(String packageName, int appId, 4489 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4490 boolean doit, boolean evenPersistent, String reason) { 4491 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4492 4493 // Remove all processes this package may have touched: all with the 4494 // same UID (except for the system or root user), and all whose name 4495 // matches the package name. 4496 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4497 final int NP = mProcessNames.getMap().size(); 4498 for (int ip=0; ip<NP; ip++) { 4499 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4500 final int NA = apps.size(); 4501 for (int ia=0; ia<NA; ia++) { 4502 ProcessRecord app = apps.valueAt(ia); 4503 if (app.persistent && !evenPersistent) { 4504 // we don't kill persistent processes 4505 continue; 4506 } 4507 if (app.removed) { 4508 if (doit) { 4509 procs.add(app); 4510 } 4511 continue; 4512 } 4513 4514 // Skip process if it doesn't meet our oom adj requirement. 4515 if (app.setAdj < minOomAdj) { 4516 continue; 4517 } 4518 4519 // If no package is specified, we call all processes under the 4520 // give user id. 4521 if (packageName == null) { 4522 if (app.userId != userId) { 4523 continue; 4524 } 4525 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4526 continue; 4527 } 4528 // Package has been specified, we want to hit all processes 4529 // that match it. We need to qualify this by the processes 4530 // that are running under the specified app and user ID. 4531 } else { 4532 if (UserHandle.getAppId(app.uid) != appId) { 4533 continue; 4534 } 4535 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4536 continue; 4537 } 4538 if (!app.pkgList.containsKey(packageName)) { 4539 continue; 4540 } 4541 } 4542 4543 // Process has passed all conditions, kill it! 4544 if (!doit) { 4545 return true; 4546 } 4547 app.removed = true; 4548 procs.add(app); 4549 } 4550 } 4551 4552 int N = procs.size(); 4553 for (int i=0; i<N; i++) { 4554 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4555 } 4556 updateOomAdjLocked(); 4557 return N > 0; 4558 } 4559 4560 private final boolean forceStopPackageLocked(String name, int appId, 4561 boolean callerWillRestart, boolean purgeCache, boolean doit, 4562 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4563 int i; 4564 int N; 4565 4566 if (userId == UserHandle.USER_ALL && name == null) { 4567 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4568 } 4569 4570 if (appId < 0 && name != null) { 4571 try { 4572 appId = UserHandle.getAppId( 4573 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4574 } catch (RemoteException e) { 4575 } 4576 } 4577 4578 if (doit) { 4579 if (name != null) { 4580 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4581 + " user=" + userId + ": " + reason); 4582 } else { 4583 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4584 } 4585 4586 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4587 for (int ip=pmap.size()-1; ip>=0; ip--) { 4588 SparseArray<Long> ba = pmap.valueAt(ip); 4589 for (i=ba.size()-1; i>=0; i--) { 4590 boolean remove = false; 4591 final int entUid = ba.keyAt(i); 4592 if (name != null) { 4593 if (userId == UserHandle.USER_ALL) { 4594 if (UserHandle.getAppId(entUid) == appId) { 4595 remove = true; 4596 } 4597 } else { 4598 if (entUid == UserHandle.getUid(userId, appId)) { 4599 remove = true; 4600 } 4601 } 4602 } else if (UserHandle.getUserId(entUid) == userId) { 4603 remove = true; 4604 } 4605 if (remove) { 4606 ba.removeAt(i); 4607 } 4608 } 4609 if (ba.size() == 0) { 4610 pmap.removeAt(ip); 4611 } 4612 } 4613 } 4614 4615 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4616 -100, callerWillRestart, true, doit, evenPersistent, 4617 name == null ? ("stop user " + userId) : ("stop " + name)); 4618 4619 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4620 if (!doit) { 4621 return true; 4622 } 4623 didSomething = true; 4624 } 4625 4626 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4627 if (!doit) { 4628 return true; 4629 } 4630 didSomething = true; 4631 } 4632 4633 if (name == null) { 4634 // Remove all sticky broadcasts from this user. 4635 mStickyBroadcasts.remove(userId); 4636 } 4637 4638 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4639 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4640 userId, providers)) { 4641 if (!doit) { 4642 return true; 4643 } 4644 didSomething = true; 4645 } 4646 N = providers.size(); 4647 for (i=0; i<N; i++) { 4648 removeDyingProviderLocked(null, providers.get(i), true); 4649 } 4650 4651 // Remove transient permissions granted from/to this package/user 4652 removeUriPermissionsForPackageLocked(name, userId, false); 4653 4654 if (name == null || uninstalling) { 4655 // Remove pending intents. For now we only do this when force 4656 // stopping users, because we have some problems when doing this 4657 // for packages -- app widgets are not currently cleaned up for 4658 // such packages, so they can be left with bad pending intents. 4659 if (mIntentSenderRecords.size() > 0) { 4660 Iterator<WeakReference<PendingIntentRecord>> it 4661 = mIntentSenderRecords.values().iterator(); 4662 while (it.hasNext()) { 4663 WeakReference<PendingIntentRecord> wpir = it.next(); 4664 if (wpir == null) { 4665 it.remove(); 4666 continue; 4667 } 4668 PendingIntentRecord pir = wpir.get(); 4669 if (pir == null) { 4670 it.remove(); 4671 continue; 4672 } 4673 if (name == null) { 4674 // Stopping user, remove all objects for the user. 4675 if (pir.key.userId != userId) { 4676 // Not the same user, skip it. 4677 continue; 4678 } 4679 } else { 4680 if (UserHandle.getAppId(pir.uid) != appId) { 4681 // Different app id, skip it. 4682 continue; 4683 } 4684 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4685 // Different user, skip it. 4686 continue; 4687 } 4688 if (!pir.key.packageName.equals(name)) { 4689 // Different package, skip it. 4690 continue; 4691 } 4692 } 4693 if (!doit) { 4694 return true; 4695 } 4696 didSomething = true; 4697 it.remove(); 4698 pir.canceled = true; 4699 if (pir.key.activity != null) { 4700 pir.key.activity.pendingResults.remove(pir.ref); 4701 } 4702 } 4703 } 4704 } 4705 4706 if (doit) { 4707 if (purgeCache && name != null) { 4708 AttributeCache ac = AttributeCache.instance(); 4709 if (ac != null) { 4710 ac.removePackage(name); 4711 } 4712 } 4713 if (mBooted) { 4714 mStackSupervisor.resumeTopActivitiesLocked(); 4715 mStackSupervisor.scheduleIdleLocked(); 4716 } 4717 } 4718 4719 return didSomething; 4720 } 4721 4722 private final boolean removeProcessLocked(ProcessRecord app, 4723 boolean callerWillRestart, boolean allowRestart, String reason) { 4724 final String name = app.processName; 4725 final int uid = app.uid; 4726 if (DEBUG_PROCESSES) Slog.d( 4727 TAG, "Force removing proc " + app.toShortString() + " (" + name 4728 + "/" + uid + ")"); 4729 4730 mProcessNames.remove(name, uid); 4731 mIsolatedProcesses.remove(app.uid); 4732 if (mHeavyWeightProcess == app) { 4733 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4734 mHeavyWeightProcess.userId, 0)); 4735 mHeavyWeightProcess = null; 4736 } 4737 boolean needRestart = false; 4738 if (app.pid > 0 && app.pid != MY_PID) { 4739 int pid = app.pid; 4740 synchronized (mPidsSelfLocked) { 4741 mPidsSelfLocked.remove(pid); 4742 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4743 } 4744 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4745 app.processName, app.info.uid); 4746 if (app.isolated) { 4747 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4748 } 4749 killUnneededProcessLocked(app, reason); 4750 handleAppDiedLocked(app, true, allowRestart); 4751 removeLruProcessLocked(app); 4752 4753 if (app.persistent && !app.isolated) { 4754 if (!callerWillRestart) { 4755 addAppLocked(app.info, false); 4756 } else { 4757 needRestart = true; 4758 } 4759 } 4760 } else { 4761 mRemovedProcesses.add(app); 4762 } 4763 4764 return needRestart; 4765 } 4766 4767 private final void processStartTimedOutLocked(ProcessRecord app) { 4768 final int pid = app.pid; 4769 boolean gone = false; 4770 synchronized (mPidsSelfLocked) { 4771 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4772 if (knownApp != null && knownApp.thread == null) { 4773 mPidsSelfLocked.remove(pid); 4774 gone = true; 4775 } 4776 } 4777 4778 if (gone) { 4779 Slog.w(TAG, "Process " + app + " failed to attach"); 4780 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4781 pid, app.uid, app.processName); 4782 mProcessNames.remove(app.processName, app.uid); 4783 mIsolatedProcesses.remove(app.uid); 4784 if (mHeavyWeightProcess == app) { 4785 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4786 mHeavyWeightProcess.userId, 0)); 4787 mHeavyWeightProcess = null; 4788 } 4789 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4790 app.processName, app.info.uid); 4791 if (app.isolated) { 4792 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4793 } 4794 // Take care of any launching providers waiting for this process. 4795 checkAppInLaunchingProvidersLocked(app, true); 4796 // Take care of any services that are waiting for the process. 4797 mServices.processStartTimedOutLocked(app); 4798 killUnneededProcessLocked(app, "start timeout"); 4799 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4800 Slog.w(TAG, "Unattached app died before backup, skipping"); 4801 try { 4802 IBackupManager bm = IBackupManager.Stub.asInterface( 4803 ServiceManager.getService(Context.BACKUP_SERVICE)); 4804 bm.agentDisconnected(app.info.packageName); 4805 } catch (RemoteException e) { 4806 // Can't happen; the backup manager is local 4807 } 4808 } 4809 if (isPendingBroadcastProcessLocked(pid)) { 4810 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4811 skipPendingBroadcastLocked(pid); 4812 } 4813 } else { 4814 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4815 } 4816 } 4817 4818 private final boolean attachApplicationLocked(IApplicationThread thread, 4819 int pid) { 4820 4821 // Find the application record that is being attached... either via 4822 // the pid if we are running in multiple processes, or just pull the 4823 // next app record if we are emulating process with anonymous threads. 4824 ProcessRecord app; 4825 if (pid != MY_PID && pid >= 0) { 4826 synchronized (mPidsSelfLocked) { 4827 app = mPidsSelfLocked.get(pid); 4828 } 4829 } else { 4830 app = null; 4831 } 4832 4833 if (app == null) { 4834 Slog.w(TAG, "No pending application record for pid " + pid 4835 + " (IApplicationThread " + thread + "); dropping process"); 4836 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4837 if (pid > 0 && pid != MY_PID) { 4838 Process.killProcessQuiet(pid); 4839 } else { 4840 try { 4841 thread.scheduleExit(); 4842 } catch (Exception e) { 4843 // Ignore exceptions. 4844 } 4845 } 4846 return false; 4847 } 4848 4849 // If this application record is still attached to a previous 4850 // process, clean it up now. 4851 if (app.thread != null) { 4852 handleAppDiedLocked(app, true, true); 4853 } 4854 4855 // Tell the process all about itself. 4856 4857 if (localLOGV) Slog.v( 4858 TAG, "Binding process pid " + pid + " to record " + app); 4859 4860 final String processName = app.processName; 4861 try { 4862 AppDeathRecipient adr = new AppDeathRecipient( 4863 app, pid, thread); 4864 thread.asBinder().linkToDeath(adr, 0); 4865 app.deathRecipient = adr; 4866 } catch (RemoteException e) { 4867 app.resetPackageList(mProcessStats); 4868 startProcessLocked(app, "link fail", processName); 4869 return false; 4870 } 4871 4872 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4873 4874 app.makeActive(thread, mProcessStats); 4875 app.curAdj = app.setAdj = -100; 4876 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4877 app.forcingToForeground = null; 4878 updateProcessForegroundLocked(app, false, false); 4879 app.hasShownUi = false; 4880 app.debugging = false; 4881 app.cached = false; 4882 4883 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4884 4885 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4886 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4887 4888 if (!normalMode) { 4889 Slog.i(TAG, "Launching preboot mode app: " + app); 4890 } 4891 4892 if (localLOGV) Slog.v( 4893 TAG, "New app record " + app 4894 + " thread=" + thread.asBinder() + " pid=" + pid); 4895 try { 4896 int testMode = IApplicationThread.DEBUG_OFF; 4897 if (mDebugApp != null && mDebugApp.equals(processName)) { 4898 testMode = mWaitForDebugger 4899 ? IApplicationThread.DEBUG_WAIT 4900 : IApplicationThread.DEBUG_ON; 4901 app.debugging = true; 4902 if (mDebugTransient) { 4903 mDebugApp = mOrigDebugApp; 4904 mWaitForDebugger = mOrigWaitForDebugger; 4905 } 4906 } 4907 String profileFile = app.instrumentationProfileFile; 4908 ParcelFileDescriptor profileFd = null; 4909 boolean profileAutoStop = false; 4910 if (mProfileApp != null && mProfileApp.equals(processName)) { 4911 mProfileProc = app; 4912 profileFile = mProfileFile; 4913 profileFd = mProfileFd; 4914 profileAutoStop = mAutoStopProfiler; 4915 } 4916 boolean enableOpenGlTrace = false; 4917 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4918 enableOpenGlTrace = true; 4919 mOpenGlTraceApp = null; 4920 } 4921 4922 // If the app is being launched for restore or full backup, set it up specially 4923 boolean isRestrictedBackupMode = false; 4924 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4925 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4926 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4927 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4928 } 4929 4930 ensurePackageDexOpt(app.instrumentationInfo != null 4931 ? app.instrumentationInfo.packageName 4932 : app.info.packageName); 4933 if (app.instrumentationClass != null) { 4934 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4935 } 4936 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4937 + processName + " with config " + mConfiguration); 4938 ApplicationInfo appInfo = app.instrumentationInfo != null 4939 ? app.instrumentationInfo : app.info; 4940 app.compat = compatibilityInfoForPackageLocked(appInfo); 4941 if (profileFd != null) { 4942 profileFd = profileFd.dup(); 4943 } 4944 thread.bindApplication(processName, appInfo, providers, 4945 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4946 app.instrumentationArguments, app.instrumentationWatcher, 4947 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4948 isRestrictedBackupMode || !normalMode, app.persistent, 4949 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4950 mCoreSettingsObserver.getCoreSettingsLocked()); 4951 updateLruProcessLocked(app, false, null); 4952 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4953 } catch (Exception e) { 4954 // todo: Yikes! What should we do? For now we will try to 4955 // start another process, but that could easily get us in 4956 // an infinite loop of restarting processes... 4957 Slog.w(TAG, "Exception thrown during bind!", e); 4958 4959 app.resetPackageList(mProcessStats); 4960 app.unlinkDeathRecipient(); 4961 startProcessLocked(app, "bind fail", processName); 4962 return false; 4963 } 4964 4965 // Remove this record from the list of starting applications. 4966 mPersistentStartingProcesses.remove(app); 4967 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4968 "Attach application locked removing on hold: " + app); 4969 mProcessesOnHold.remove(app); 4970 4971 boolean badApp = false; 4972 boolean didSomething = false; 4973 4974 // See if the top visible activity is waiting to run in this process... 4975 if (normalMode) { 4976 try { 4977 if (mStackSupervisor.attachApplicationLocked(app)) { 4978 didSomething = true; 4979 } 4980 } catch (Exception e) { 4981 badApp = true; 4982 } 4983 } 4984 4985 // Find any services that should be running in this process... 4986 if (!badApp) { 4987 try { 4988 didSomething |= mServices.attachApplicationLocked(app, processName); 4989 } catch (Exception e) { 4990 badApp = true; 4991 } 4992 } 4993 4994 // Check if a next-broadcast receiver is in this process... 4995 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4996 try { 4997 didSomething |= sendPendingBroadcastsLocked(app); 4998 } catch (Exception e) { 4999 // If the app died trying to launch the receiver we declare it 'bad' 5000 badApp = true; 5001 } 5002 } 5003 5004 // Check whether the next backup agent is in this process... 5005 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5006 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5007 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5008 try { 5009 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5010 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5011 mBackupTarget.backupMode); 5012 } catch (Exception e) { 5013 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5014 e.printStackTrace(); 5015 } 5016 } 5017 5018 if (badApp) { 5019 // todo: Also need to kill application to deal with all 5020 // kinds of exceptions. 5021 handleAppDiedLocked(app, false, true); 5022 return false; 5023 } 5024 5025 if (!didSomething) { 5026 updateOomAdjLocked(); 5027 } 5028 5029 return true; 5030 } 5031 5032 @Override 5033 public final void attachApplication(IApplicationThread thread) { 5034 synchronized (this) { 5035 int callingPid = Binder.getCallingPid(); 5036 final long origId = Binder.clearCallingIdentity(); 5037 attachApplicationLocked(thread, callingPid); 5038 Binder.restoreCallingIdentity(origId); 5039 } 5040 } 5041 5042 @Override 5043 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5044 final long origId = Binder.clearCallingIdentity(); 5045 synchronized (this) { 5046 ActivityStack stack = ActivityRecord.getStackLocked(token); 5047 if (stack != null) { 5048 ActivityRecord r = 5049 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5050 if (stopProfiling) { 5051 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5052 try { 5053 mProfileFd.close(); 5054 } catch (IOException e) { 5055 } 5056 clearProfilerLocked(); 5057 } 5058 } 5059 } 5060 } 5061 Binder.restoreCallingIdentity(origId); 5062 } 5063 5064 void enableScreenAfterBoot() { 5065 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5066 SystemClock.uptimeMillis()); 5067 mWindowManager.enableScreenAfterBoot(); 5068 5069 synchronized (this) { 5070 updateEventDispatchingLocked(); 5071 } 5072 } 5073 5074 @Override 5075 public void showBootMessage(final CharSequence msg, final boolean always) { 5076 enforceNotIsolatedCaller("showBootMessage"); 5077 mWindowManager.showBootMessage(msg, always); 5078 } 5079 5080 @Override 5081 public void dismissKeyguardOnNextActivity() { 5082 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5083 final long token = Binder.clearCallingIdentity(); 5084 try { 5085 synchronized (this) { 5086 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5087 if (mLockScreenShown) { 5088 mLockScreenShown = false; 5089 comeOutOfSleepIfNeededLocked(); 5090 } 5091 mStackSupervisor.setDismissKeyguard(true); 5092 } 5093 } finally { 5094 Binder.restoreCallingIdentity(token); 5095 } 5096 } 5097 5098 final void finishBooting() { 5099 IntentFilter pkgFilter = new IntentFilter(); 5100 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5101 pkgFilter.addDataScheme("package"); 5102 mContext.registerReceiver(new BroadcastReceiver() { 5103 @Override 5104 public void onReceive(Context context, Intent intent) { 5105 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5106 if (pkgs != null) { 5107 for (String pkg : pkgs) { 5108 synchronized (ActivityManagerService.this) { 5109 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 5110 "finished booting")) { 5111 setResultCode(Activity.RESULT_OK); 5112 return; 5113 } 5114 } 5115 } 5116 } 5117 } 5118 }, pkgFilter); 5119 5120 synchronized (this) { 5121 // Ensure that any processes we had put on hold are now started 5122 // up. 5123 final int NP = mProcessesOnHold.size(); 5124 if (NP > 0) { 5125 ArrayList<ProcessRecord> procs = 5126 new ArrayList<ProcessRecord>(mProcessesOnHold); 5127 for (int ip=0; ip<NP; ip++) { 5128 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5129 + procs.get(ip)); 5130 startProcessLocked(procs.get(ip), "on-hold", null); 5131 } 5132 } 5133 5134 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5135 // Start looking for apps that are abusing wake locks. 5136 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5137 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5138 // Tell anyone interested that we are done booting! 5139 SystemProperties.set("sys.boot_completed", "1"); 5140 SystemProperties.set("dev.bootcomplete", "1"); 5141 for (int i=0; i<mStartedUsers.size(); i++) { 5142 UserStartedState uss = mStartedUsers.valueAt(i); 5143 if (uss.mState == UserStartedState.STATE_BOOTING) { 5144 uss.mState = UserStartedState.STATE_RUNNING; 5145 final int userId = mStartedUsers.keyAt(i); 5146 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5147 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5148 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5149 broadcastIntentLocked(null, null, intent, null, 5150 new IIntentReceiver.Stub() { 5151 @Override 5152 public void performReceive(Intent intent, int resultCode, 5153 String data, Bundle extras, boolean ordered, 5154 boolean sticky, int sendingUser) { 5155 synchronized (ActivityManagerService.this) { 5156 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5157 true, false); 5158 } 5159 } 5160 }, 5161 0, null, null, 5162 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5163 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5164 userId); 5165 } 5166 } 5167 } 5168 } 5169 } 5170 5171 final void ensureBootCompleted() { 5172 boolean booting; 5173 boolean enableScreen; 5174 synchronized (this) { 5175 booting = mBooting; 5176 mBooting = false; 5177 enableScreen = !mBooted; 5178 mBooted = true; 5179 } 5180 5181 if (booting) { 5182 finishBooting(); 5183 } 5184 5185 if (enableScreen) { 5186 enableScreenAfterBoot(); 5187 } 5188 } 5189 5190 @Override 5191 public final void activityResumed(IBinder token) { 5192 final long origId = Binder.clearCallingIdentity(); 5193 synchronized(this) { 5194 ActivityStack stack = ActivityRecord.getStackLocked(token); 5195 if (stack != null) { 5196 ActivityRecord.activityResumedLocked(token); 5197 } 5198 } 5199 Binder.restoreCallingIdentity(origId); 5200 } 5201 5202 @Override 5203 public final void activityPaused(IBinder token) { 5204 final long origId = Binder.clearCallingIdentity(); 5205 synchronized(this) { 5206 ActivityStack stack = ActivityRecord.getStackLocked(token); 5207 if (stack != null) { 5208 stack.activityPausedLocked(token, false); 5209 } 5210 } 5211 Binder.restoreCallingIdentity(origId); 5212 } 5213 5214 @Override 5215 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5216 CharSequence description) { 5217 if (localLOGV) Slog.v( 5218 TAG, "Activity stopped: token=" + token); 5219 5220 // Refuse possible leaked file descriptors 5221 if (icicle != null && icicle.hasFileDescriptors()) { 5222 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5223 } 5224 5225 ActivityRecord r = null; 5226 5227 final long origId = Binder.clearCallingIdentity(); 5228 5229 synchronized (this) { 5230 r = ActivityRecord.isInStackLocked(token); 5231 if (r != null) { 5232 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5233 } 5234 } 5235 5236 if (r != null) { 5237 sendPendingThumbnail(r, null, null, null, false); 5238 } 5239 5240 trimApplications(); 5241 5242 Binder.restoreCallingIdentity(origId); 5243 } 5244 5245 @Override 5246 public final void activityDestroyed(IBinder token) { 5247 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5248 synchronized (this) { 5249 ActivityStack stack = ActivityRecord.getStackLocked(token); 5250 if (stack != null) { 5251 stack.activityDestroyedLocked(token); 5252 } 5253 } 5254 } 5255 5256 @Override 5257 public String getCallingPackage(IBinder token) { 5258 synchronized (this) { 5259 ActivityRecord r = getCallingRecordLocked(token); 5260 return r != null ? r.info.packageName : null; 5261 } 5262 } 5263 5264 @Override 5265 public ComponentName getCallingActivity(IBinder token) { 5266 synchronized (this) { 5267 ActivityRecord r = getCallingRecordLocked(token); 5268 return r != null ? r.intent.getComponent() : null; 5269 } 5270 } 5271 5272 private ActivityRecord getCallingRecordLocked(IBinder token) { 5273 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5274 if (r == null) { 5275 return null; 5276 } 5277 return r.resultTo; 5278 } 5279 5280 @Override 5281 public ComponentName getActivityClassForToken(IBinder token) { 5282 synchronized(this) { 5283 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5284 if (r == null) { 5285 return null; 5286 } 5287 return r.intent.getComponent(); 5288 } 5289 } 5290 5291 @Override 5292 public String getPackageForToken(IBinder token) { 5293 synchronized(this) { 5294 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5295 if (r == null) { 5296 return null; 5297 } 5298 return r.packageName; 5299 } 5300 } 5301 5302 @Override 5303 public IIntentSender getIntentSender(int type, 5304 String packageName, IBinder token, String resultWho, 5305 int requestCode, Intent[] intents, String[] resolvedTypes, 5306 int flags, Bundle options, int userId) { 5307 enforceNotIsolatedCaller("getIntentSender"); 5308 // Refuse possible leaked file descriptors 5309 if (intents != null) { 5310 if (intents.length < 1) { 5311 throw new IllegalArgumentException("Intents array length must be >= 1"); 5312 } 5313 for (int i=0; i<intents.length; i++) { 5314 Intent intent = intents[i]; 5315 if (intent != null) { 5316 if (intent.hasFileDescriptors()) { 5317 throw new IllegalArgumentException("File descriptors passed in Intent"); 5318 } 5319 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5320 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5321 throw new IllegalArgumentException( 5322 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5323 } 5324 intents[i] = new Intent(intent); 5325 } 5326 } 5327 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5328 throw new IllegalArgumentException( 5329 "Intent array length does not match resolvedTypes length"); 5330 } 5331 } 5332 if (options != null) { 5333 if (options.hasFileDescriptors()) { 5334 throw new IllegalArgumentException("File descriptors passed in options"); 5335 } 5336 } 5337 5338 synchronized(this) { 5339 int callingUid = Binder.getCallingUid(); 5340 int origUserId = userId; 5341 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5342 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5343 "getIntentSender", null); 5344 if (origUserId == UserHandle.USER_CURRENT) { 5345 // We don't want to evaluate this until the pending intent is 5346 // actually executed. However, we do want to always do the 5347 // security checking for it above. 5348 userId = UserHandle.USER_CURRENT; 5349 } 5350 try { 5351 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5352 int uid = AppGlobals.getPackageManager() 5353 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5354 if (!UserHandle.isSameApp(callingUid, uid)) { 5355 String msg = "Permission Denial: getIntentSender() from pid=" 5356 + Binder.getCallingPid() 5357 + ", uid=" + Binder.getCallingUid() 5358 + ", (need uid=" + uid + ")" 5359 + " is not allowed to send as package " + packageName; 5360 Slog.w(TAG, msg); 5361 throw new SecurityException(msg); 5362 } 5363 } 5364 5365 return getIntentSenderLocked(type, packageName, callingUid, userId, 5366 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5367 5368 } catch (RemoteException e) { 5369 throw new SecurityException(e); 5370 } 5371 } 5372 } 5373 5374 IIntentSender getIntentSenderLocked(int type, String packageName, 5375 int callingUid, int userId, IBinder token, String resultWho, 5376 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5377 Bundle options) { 5378 if (DEBUG_MU) 5379 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5380 ActivityRecord activity = null; 5381 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5382 activity = ActivityRecord.isInStackLocked(token); 5383 if (activity == null) { 5384 return null; 5385 } 5386 if (activity.finishing) { 5387 return null; 5388 } 5389 } 5390 5391 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5392 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5393 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5394 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5395 |PendingIntent.FLAG_UPDATE_CURRENT); 5396 5397 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5398 type, packageName, activity, resultWho, 5399 requestCode, intents, resolvedTypes, flags, options, userId); 5400 WeakReference<PendingIntentRecord> ref; 5401 ref = mIntentSenderRecords.get(key); 5402 PendingIntentRecord rec = ref != null ? ref.get() : null; 5403 if (rec != null) { 5404 if (!cancelCurrent) { 5405 if (updateCurrent) { 5406 if (rec.key.requestIntent != null) { 5407 rec.key.requestIntent.replaceExtras(intents != null ? 5408 intents[intents.length - 1] : null); 5409 } 5410 if (intents != null) { 5411 intents[intents.length-1] = rec.key.requestIntent; 5412 rec.key.allIntents = intents; 5413 rec.key.allResolvedTypes = resolvedTypes; 5414 } else { 5415 rec.key.allIntents = null; 5416 rec.key.allResolvedTypes = null; 5417 } 5418 } 5419 return rec; 5420 } 5421 rec.canceled = true; 5422 mIntentSenderRecords.remove(key); 5423 } 5424 if (noCreate) { 5425 return rec; 5426 } 5427 rec = new PendingIntentRecord(this, key, callingUid); 5428 mIntentSenderRecords.put(key, rec.ref); 5429 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5430 if (activity.pendingResults == null) { 5431 activity.pendingResults 5432 = new HashSet<WeakReference<PendingIntentRecord>>(); 5433 } 5434 activity.pendingResults.add(rec.ref); 5435 } 5436 return rec; 5437 } 5438 5439 @Override 5440 public void cancelIntentSender(IIntentSender sender) { 5441 if (!(sender instanceof PendingIntentRecord)) { 5442 return; 5443 } 5444 synchronized(this) { 5445 PendingIntentRecord rec = (PendingIntentRecord)sender; 5446 try { 5447 int uid = AppGlobals.getPackageManager() 5448 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5449 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5450 String msg = "Permission Denial: cancelIntentSender() from pid=" 5451 + Binder.getCallingPid() 5452 + ", uid=" + Binder.getCallingUid() 5453 + " is not allowed to cancel packges " 5454 + rec.key.packageName; 5455 Slog.w(TAG, msg); 5456 throw new SecurityException(msg); 5457 } 5458 } catch (RemoteException e) { 5459 throw new SecurityException(e); 5460 } 5461 cancelIntentSenderLocked(rec, true); 5462 } 5463 } 5464 5465 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5466 rec.canceled = true; 5467 mIntentSenderRecords.remove(rec.key); 5468 if (cleanActivity && rec.key.activity != null) { 5469 rec.key.activity.pendingResults.remove(rec.ref); 5470 } 5471 } 5472 5473 @Override 5474 public String getPackageForIntentSender(IIntentSender pendingResult) { 5475 if (!(pendingResult instanceof PendingIntentRecord)) { 5476 return null; 5477 } 5478 try { 5479 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5480 return res.key.packageName; 5481 } catch (ClassCastException e) { 5482 } 5483 return null; 5484 } 5485 5486 @Override 5487 public int getUidForIntentSender(IIntentSender sender) { 5488 if (sender instanceof PendingIntentRecord) { 5489 try { 5490 PendingIntentRecord res = (PendingIntentRecord)sender; 5491 return res.uid; 5492 } catch (ClassCastException e) { 5493 } 5494 } 5495 return -1; 5496 } 5497 5498 @Override 5499 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5500 if (!(pendingResult instanceof PendingIntentRecord)) { 5501 return false; 5502 } 5503 try { 5504 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5505 if (res.key.allIntents == null) { 5506 return false; 5507 } 5508 for (int i=0; i<res.key.allIntents.length; i++) { 5509 Intent intent = res.key.allIntents[i]; 5510 if (intent.getPackage() != null && intent.getComponent() != null) { 5511 return false; 5512 } 5513 } 5514 return true; 5515 } catch (ClassCastException e) { 5516 } 5517 return false; 5518 } 5519 5520 @Override 5521 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5522 if (!(pendingResult instanceof PendingIntentRecord)) { 5523 return false; 5524 } 5525 try { 5526 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5527 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5528 return true; 5529 } 5530 return false; 5531 } catch (ClassCastException e) { 5532 } 5533 return false; 5534 } 5535 5536 @Override 5537 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5538 if (!(pendingResult instanceof PendingIntentRecord)) { 5539 return null; 5540 } 5541 try { 5542 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5543 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5544 } catch (ClassCastException e) { 5545 } 5546 return null; 5547 } 5548 5549 @Override 5550 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5551 if (!(pendingResult instanceof PendingIntentRecord)) { 5552 return null; 5553 } 5554 try { 5555 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5556 Intent intent = res.key.requestIntent; 5557 if (intent != null) { 5558 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5559 || res.lastTagPrefix.equals(prefix))) { 5560 return res.lastTag; 5561 } 5562 res.lastTagPrefix = prefix; 5563 StringBuilder sb = new StringBuilder(128); 5564 if (prefix != null) { 5565 sb.append(prefix); 5566 } 5567 if (intent.getAction() != null) { 5568 sb.append(intent.getAction()); 5569 } else if (intent.getComponent() != null) { 5570 intent.getComponent().appendShortString(sb); 5571 } else { 5572 sb.append("?"); 5573 } 5574 return res.lastTag = sb.toString(); 5575 } 5576 } catch (ClassCastException e) { 5577 } 5578 return null; 5579 } 5580 5581 @Override 5582 public void setProcessLimit(int max) { 5583 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5584 "setProcessLimit()"); 5585 synchronized (this) { 5586 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5587 mProcessLimitOverride = max; 5588 } 5589 trimApplications(); 5590 } 5591 5592 @Override 5593 public int getProcessLimit() { 5594 synchronized (this) { 5595 return mProcessLimitOverride; 5596 } 5597 } 5598 5599 void foregroundTokenDied(ForegroundToken token) { 5600 synchronized (ActivityManagerService.this) { 5601 synchronized (mPidsSelfLocked) { 5602 ForegroundToken cur 5603 = mForegroundProcesses.get(token.pid); 5604 if (cur != token) { 5605 return; 5606 } 5607 mForegroundProcesses.remove(token.pid); 5608 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5609 if (pr == null) { 5610 return; 5611 } 5612 pr.forcingToForeground = null; 5613 updateProcessForegroundLocked(pr, false, false); 5614 } 5615 updateOomAdjLocked(); 5616 } 5617 } 5618 5619 @Override 5620 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5621 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5622 "setProcessForeground()"); 5623 synchronized(this) { 5624 boolean changed = false; 5625 5626 synchronized (mPidsSelfLocked) { 5627 ProcessRecord pr = mPidsSelfLocked.get(pid); 5628 if (pr == null && isForeground) { 5629 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5630 return; 5631 } 5632 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5633 if (oldToken != null) { 5634 oldToken.token.unlinkToDeath(oldToken, 0); 5635 mForegroundProcesses.remove(pid); 5636 if (pr != null) { 5637 pr.forcingToForeground = null; 5638 } 5639 changed = true; 5640 } 5641 if (isForeground && token != null) { 5642 ForegroundToken newToken = new ForegroundToken() { 5643 @Override 5644 public void binderDied() { 5645 foregroundTokenDied(this); 5646 } 5647 }; 5648 newToken.pid = pid; 5649 newToken.token = token; 5650 try { 5651 token.linkToDeath(newToken, 0); 5652 mForegroundProcesses.put(pid, newToken); 5653 pr.forcingToForeground = token; 5654 changed = true; 5655 } catch (RemoteException e) { 5656 // If the process died while doing this, we will later 5657 // do the cleanup with the process death link. 5658 } 5659 } 5660 } 5661 5662 if (changed) { 5663 updateOomAdjLocked(); 5664 } 5665 } 5666 } 5667 5668 // ========================================================= 5669 // PERMISSIONS 5670 // ========================================================= 5671 5672 static class PermissionController extends IPermissionController.Stub { 5673 ActivityManagerService mActivityManagerService; 5674 PermissionController(ActivityManagerService activityManagerService) { 5675 mActivityManagerService = activityManagerService; 5676 } 5677 5678 @Override 5679 public boolean checkPermission(String permission, int pid, int uid) { 5680 return mActivityManagerService.checkPermission(permission, pid, 5681 uid) == PackageManager.PERMISSION_GRANTED; 5682 } 5683 } 5684 5685 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5686 @Override 5687 public int checkComponentPermission(String permission, int pid, int uid, 5688 int owningUid, boolean exported) { 5689 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5690 owningUid, exported); 5691 } 5692 5693 @Override 5694 public Object getAMSLock() { 5695 return ActivityManagerService.this; 5696 } 5697 } 5698 5699 /** 5700 * This can be called with or without the global lock held. 5701 */ 5702 int checkComponentPermission(String permission, int pid, int uid, 5703 int owningUid, boolean exported) { 5704 // We might be performing an operation on behalf of an indirect binder 5705 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5706 // client identity accordingly before proceeding. 5707 Identity tlsIdentity = sCallerIdentity.get(); 5708 if (tlsIdentity != null) { 5709 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5710 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5711 uid = tlsIdentity.uid; 5712 pid = tlsIdentity.pid; 5713 } 5714 5715 if (pid == MY_PID) { 5716 return PackageManager.PERMISSION_GRANTED; 5717 } 5718 5719 return ActivityManager.checkComponentPermission(permission, uid, 5720 owningUid, exported); 5721 } 5722 5723 /** 5724 * As the only public entry point for permissions checking, this method 5725 * can enforce the semantic that requesting a check on a null global 5726 * permission is automatically denied. (Internally a null permission 5727 * string is used when calling {@link #checkComponentPermission} in cases 5728 * when only uid-based security is needed.) 5729 * 5730 * This can be called with or without the global lock held. 5731 */ 5732 @Override 5733 public int checkPermission(String permission, int pid, int uid) { 5734 if (permission == null) { 5735 return PackageManager.PERMISSION_DENIED; 5736 } 5737 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5738 } 5739 5740 /** 5741 * Binder IPC calls go through the public entry point. 5742 * This can be called with or without the global lock held. 5743 */ 5744 int checkCallingPermission(String permission) { 5745 return checkPermission(permission, 5746 Binder.getCallingPid(), 5747 UserHandle.getAppId(Binder.getCallingUid())); 5748 } 5749 5750 /** 5751 * This can be called with or without the global lock held. 5752 */ 5753 void enforceCallingPermission(String permission, String func) { 5754 if (checkCallingPermission(permission) 5755 == PackageManager.PERMISSION_GRANTED) { 5756 return; 5757 } 5758 5759 String msg = "Permission Denial: " + func + " from pid=" 5760 + Binder.getCallingPid() 5761 + ", uid=" + Binder.getCallingUid() 5762 + " requires " + permission; 5763 Slog.w(TAG, msg); 5764 throw new SecurityException(msg); 5765 } 5766 5767 /** 5768 * Determine if UID is holding permissions required to access {@link Uri} in 5769 * the given {@link ProviderInfo}. Final permission checking is always done 5770 * in {@link ContentProvider}. 5771 */ 5772 private final boolean checkHoldingPermissionsLocked( 5773 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5774 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5775 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5776 5777 if (pi.applicationInfo.uid == uid) { 5778 return true; 5779 } else if (!pi.exported) { 5780 return false; 5781 } 5782 5783 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5784 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5785 try { 5786 // check if target holds top-level <provider> permissions 5787 if (!readMet && pi.readPermission != null 5788 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5789 readMet = true; 5790 } 5791 if (!writeMet && pi.writePermission != null 5792 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5793 writeMet = true; 5794 } 5795 5796 // track if unprotected read/write is allowed; any denied 5797 // <path-permission> below removes this ability 5798 boolean allowDefaultRead = pi.readPermission == null; 5799 boolean allowDefaultWrite = pi.writePermission == null; 5800 5801 // check if target holds any <path-permission> that match uri 5802 final PathPermission[] pps = pi.pathPermissions; 5803 if (pps != null) { 5804 final String path = uri.getPath(); 5805 int i = pps.length; 5806 while (i > 0 && (!readMet || !writeMet)) { 5807 i--; 5808 PathPermission pp = pps[i]; 5809 if (pp.match(path)) { 5810 if (!readMet) { 5811 final String pprperm = pp.getReadPermission(); 5812 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5813 + pprperm + " for " + pp.getPath() 5814 + ": match=" + pp.match(path) 5815 + " check=" + pm.checkUidPermission(pprperm, uid)); 5816 if (pprperm != null) { 5817 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5818 readMet = true; 5819 } else { 5820 allowDefaultRead = false; 5821 } 5822 } 5823 } 5824 if (!writeMet) { 5825 final String ppwperm = pp.getWritePermission(); 5826 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5827 + ppwperm + " for " + pp.getPath() 5828 + ": match=" + pp.match(path) 5829 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5830 if (ppwperm != null) { 5831 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5832 writeMet = true; 5833 } else { 5834 allowDefaultWrite = false; 5835 } 5836 } 5837 } 5838 } 5839 } 5840 } 5841 5842 // grant unprotected <provider> read/write, if not blocked by 5843 // <path-permission> above 5844 if (allowDefaultRead) readMet = true; 5845 if (allowDefaultWrite) writeMet = true; 5846 5847 } catch (RemoteException e) { 5848 return false; 5849 } 5850 5851 return readMet && writeMet; 5852 } 5853 5854 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5855 ProviderInfo pi = null; 5856 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5857 if (cpr != null) { 5858 pi = cpr.info; 5859 } else { 5860 try { 5861 pi = AppGlobals.getPackageManager().resolveContentProvider( 5862 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5863 } catch (RemoteException ex) { 5864 } 5865 } 5866 return pi; 5867 } 5868 5869 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5870 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5871 if (targetUris != null) { 5872 return targetUris.get(uri); 5873 } else { 5874 return null; 5875 } 5876 } 5877 5878 private UriPermission findOrCreateUriPermissionLocked( 5879 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5880 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5881 if (targetUris == null) { 5882 targetUris = Maps.newArrayMap(); 5883 mGrantedUriPermissions.put(targetUid, targetUris); 5884 } 5885 5886 UriPermission perm = targetUris.get(uri); 5887 if (perm == null) { 5888 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5889 targetUris.put(uri, perm); 5890 } 5891 5892 return perm; 5893 } 5894 5895 private final boolean checkUriPermissionLocked( 5896 Uri uri, int uid, int modeFlags, int minStrength) { 5897 // Root gets to do everything. 5898 if (uid == 0) { 5899 return true; 5900 } 5901 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5902 if (perms == null) return false; 5903 UriPermission perm = perms.get(uri); 5904 if (perm == null) return false; 5905 return perm.getStrength(modeFlags) >= minStrength; 5906 } 5907 5908 @Override 5909 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5910 enforceNotIsolatedCaller("checkUriPermission"); 5911 5912 // Another redirected-binder-call permissions check as in 5913 // {@link checkComponentPermission}. 5914 Identity tlsIdentity = sCallerIdentity.get(); 5915 if (tlsIdentity != null) { 5916 uid = tlsIdentity.uid; 5917 pid = tlsIdentity.pid; 5918 } 5919 5920 // Our own process gets to do everything. 5921 if (pid == MY_PID) { 5922 return PackageManager.PERMISSION_GRANTED; 5923 } 5924 synchronized(this) { 5925 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5926 ? PackageManager.PERMISSION_GRANTED 5927 : PackageManager.PERMISSION_DENIED; 5928 } 5929 } 5930 5931 /** 5932 * Check if the targetPkg can be granted permission to access uri by 5933 * the callingUid using the given modeFlags. Throws a security exception 5934 * if callingUid is not allowed to do this. Returns the uid of the target 5935 * if the URI permission grant should be performed; returns -1 if it is not 5936 * needed (for example targetPkg already has permission to access the URI). 5937 * If you already know the uid of the target, you can supply it in 5938 * lastTargetUid else set that to -1. 5939 */ 5940 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5941 Uri uri, int modeFlags, int lastTargetUid) { 5942 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5943 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5944 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5945 if (modeFlags == 0) { 5946 return -1; 5947 } 5948 5949 if (targetPkg != null) { 5950 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5951 "Checking grant " + targetPkg + " permission to " + uri); 5952 } 5953 5954 final IPackageManager pm = AppGlobals.getPackageManager(); 5955 5956 // If this is not a content: uri, we can't do anything with it. 5957 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5958 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5959 "Can't grant URI permission for non-content URI: " + uri); 5960 return -1; 5961 } 5962 5963 final String authority = uri.getAuthority(); 5964 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 5965 if (pi == null) { 5966 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5967 return -1; 5968 } 5969 5970 int targetUid = lastTargetUid; 5971 if (targetUid < 0 && targetPkg != null) { 5972 try { 5973 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5974 if (targetUid < 0) { 5975 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5976 "Can't grant URI permission no uid for: " + targetPkg); 5977 return -1; 5978 } 5979 } catch (RemoteException ex) { 5980 return -1; 5981 } 5982 } 5983 5984 if (targetUid >= 0) { 5985 // First... does the target actually need this permission? 5986 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5987 // No need to grant the target this permission. 5988 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5989 "Target " + targetPkg + " already has full permission to " + uri); 5990 return -1; 5991 } 5992 } else { 5993 // First... there is no target package, so can anyone access it? 5994 boolean allowed = pi.exported; 5995 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5996 if (pi.readPermission != null) { 5997 allowed = false; 5998 } 5999 } 6000 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6001 if (pi.writePermission != null) { 6002 allowed = false; 6003 } 6004 } 6005 if (allowed) { 6006 return -1; 6007 } 6008 } 6009 6010 // Second... is the provider allowing granting of URI permissions? 6011 if (!pi.grantUriPermissions) { 6012 throw new SecurityException("Provider " + pi.packageName 6013 + "/" + pi.name 6014 + " does not allow granting of Uri permissions (uri " 6015 + uri + ")"); 6016 } 6017 if (pi.uriPermissionPatterns != null) { 6018 final int N = pi.uriPermissionPatterns.length; 6019 boolean allowed = false; 6020 for (int i=0; i<N; i++) { 6021 if (pi.uriPermissionPatterns[i] != null 6022 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6023 allowed = true; 6024 break; 6025 } 6026 } 6027 if (!allowed) { 6028 throw new SecurityException("Provider " + pi.packageName 6029 + "/" + pi.name 6030 + " does not allow granting of permission to path of Uri " 6031 + uri); 6032 } 6033 } 6034 6035 // Third... does the caller itself have permission to access 6036 // this uri? 6037 if (callingUid != Process.myUid()) { 6038 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6039 // Require they hold a strong enough Uri permission 6040 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6041 : UriPermission.STRENGTH_OWNED; 6042 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6043 throw new SecurityException("Uid " + callingUid 6044 + " does not have permission to uri " + uri); 6045 } 6046 } 6047 } 6048 6049 return targetUid; 6050 } 6051 6052 @Override 6053 public int checkGrantUriPermission(int callingUid, String targetPkg, 6054 Uri uri, int modeFlags) { 6055 enforceNotIsolatedCaller("checkGrantUriPermission"); 6056 synchronized(this) { 6057 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6058 } 6059 } 6060 6061 void grantUriPermissionUncheckedLocked( 6062 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6063 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6064 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6065 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6066 if (modeFlags == 0) { 6067 return; 6068 } 6069 6070 // So here we are: the caller has the assumed permission 6071 // to the uri, and the target doesn't. Let's now give this to 6072 // the target. 6073 6074 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6075 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6076 6077 final String authority = uri.getAuthority(); 6078 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6079 if (pi == null) { 6080 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6081 return; 6082 } 6083 6084 final UriPermission perm = findOrCreateUriPermissionLocked( 6085 pi.packageName, targetPkg, targetUid, uri); 6086 perm.grantModes(modeFlags, persistable, owner); 6087 } 6088 6089 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6090 int modeFlags, UriPermissionOwner owner) { 6091 if (targetPkg == null) { 6092 throw new NullPointerException("targetPkg"); 6093 } 6094 6095 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6096 if (targetUid < 0) { 6097 return; 6098 } 6099 6100 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6101 } 6102 6103 static class NeededUriGrants extends ArrayList<Uri> { 6104 final String targetPkg; 6105 final int targetUid; 6106 final int flags; 6107 6108 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6109 this.targetPkg = targetPkg; 6110 this.targetUid = targetUid; 6111 this.flags = flags; 6112 } 6113 } 6114 6115 /** 6116 * Like checkGrantUriPermissionLocked, but takes an Intent. 6117 */ 6118 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6119 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6120 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6121 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6122 + " clip=" + (intent != null ? intent.getClipData() : null) 6123 + " from " + intent + "; flags=0x" 6124 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6125 6126 if (targetPkg == null) { 6127 throw new NullPointerException("targetPkg"); 6128 } 6129 6130 if (intent == null) { 6131 return null; 6132 } 6133 Uri data = intent.getData(); 6134 ClipData clip = intent.getClipData(); 6135 if (data == null && clip == null) { 6136 return null; 6137 } 6138 6139 if (data != null) { 6140 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6141 mode, needed != null ? needed.targetUid : -1); 6142 if (targetUid > 0) { 6143 if (needed == null) { 6144 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6145 } 6146 needed.add(data); 6147 } 6148 } 6149 if (clip != null) { 6150 for (int i=0; i<clip.getItemCount(); i++) { 6151 Uri uri = clip.getItemAt(i).getUri(); 6152 if (uri != null) { 6153 int targetUid = -1; 6154 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6155 mode, needed != null ? needed.targetUid : -1); 6156 if (targetUid > 0) { 6157 if (needed == null) { 6158 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6159 } 6160 needed.add(uri); 6161 } 6162 } else { 6163 Intent clipIntent = clip.getItemAt(i).getIntent(); 6164 if (clipIntent != null) { 6165 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6166 callingUid, targetPkg, clipIntent, mode, needed); 6167 if (newNeeded != null) { 6168 needed = newNeeded; 6169 } 6170 } 6171 } 6172 } 6173 } 6174 6175 return needed; 6176 } 6177 6178 /** 6179 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6180 */ 6181 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6182 UriPermissionOwner owner) { 6183 if (needed != null) { 6184 for (int i=0; i<needed.size(); i++) { 6185 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6186 needed.get(i), needed.flags, owner); 6187 } 6188 } 6189 } 6190 6191 void grantUriPermissionFromIntentLocked(int callingUid, 6192 String targetPkg, Intent intent, UriPermissionOwner owner) { 6193 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6194 intent, intent != null ? intent.getFlags() : 0, null); 6195 if (needed == null) { 6196 return; 6197 } 6198 6199 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6200 } 6201 6202 @Override 6203 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6204 Uri uri, int modeFlags) { 6205 enforceNotIsolatedCaller("grantUriPermission"); 6206 synchronized(this) { 6207 final ProcessRecord r = getRecordForAppLocked(caller); 6208 if (r == null) { 6209 throw new SecurityException("Unable to find app for caller " 6210 + caller 6211 + " when granting permission to uri " + uri); 6212 } 6213 if (targetPkg == null) { 6214 throw new IllegalArgumentException("null target"); 6215 } 6216 if (uri == null) { 6217 throw new IllegalArgumentException("null uri"); 6218 } 6219 6220 // Persistable only supported through Intents 6221 Preconditions.checkFlagsArgument(modeFlags, 6222 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6223 6224 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6225 null); 6226 } 6227 } 6228 6229 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6230 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6231 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6232 ArrayMap<Uri, UriPermission> perms 6233 = mGrantedUriPermissions.get(perm.targetUid); 6234 if (perms != null) { 6235 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6236 "Removing " + perm.targetUid + " permission to " + perm.uri); 6237 perms.remove(perm.uri); 6238 if (perms.size() == 0) { 6239 mGrantedUriPermissions.remove(perm.targetUid); 6240 } 6241 } 6242 } 6243 } 6244 6245 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6246 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6247 6248 final IPackageManager pm = AppGlobals.getPackageManager(); 6249 final String authority = uri.getAuthority(); 6250 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6251 if (pi == null) { 6252 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6253 return; 6254 } 6255 6256 // Does the caller have this permission on the URI? 6257 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6258 // Right now, if you are not the original owner of the permission, 6259 // you are not allowed to revoke it. 6260 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6261 throw new SecurityException("Uid " + callingUid 6262 + " does not have permission to uri " + uri); 6263 //} 6264 } 6265 6266 boolean persistChanged = false; 6267 6268 // Go through all of the permissions and remove any that match. 6269 final List<String> SEGMENTS = uri.getPathSegments(); 6270 if (SEGMENTS != null) { 6271 final int NS = SEGMENTS.size(); 6272 int N = mGrantedUriPermissions.size(); 6273 for (int i=0; i<N; i++) { 6274 ArrayMap<Uri, UriPermission> perms 6275 = mGrantedUriPermissions.valueAt(i); 6276 Iterator<UriPermission> it = perms.values().iterator(); 6277 toploop: 6278 while (it.hasNext()) { 6279 UriPermission perm = it.next(); 6280 Uri targetUri = perm.uri; 6281 if (!authority.equals(targetUri.getAuthority())) { 6282 continue; 6283 } 6284 List<String> targetSegments = targetUri.getPathSegments(); 6285 if (targetSegments == null) { 6286 continue; 6287 } 6288 if (targetSegments.size() < NS) { 6289 continue; 6290 } 6291 for (int j=0; j<NS; j++) { 6292 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6293 continue toploop; 6294 } 6295 } 6296 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6297 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6298 persistChanged |= perm.clearModes(modeFlags, true); 6299 if (perm.modeFlags == 0) { 6300 it.remove(); 6301 } 6302 } 6303 if (perms.size() == 0) { 6304 mGrantedUriPermissions.remove( 6305 mGrantedUriPermissions.keyAt(i)); 6306 N--; 6307 i--; 6308 } 6309 } 6310 } 6311 6312 if (persistChanged) { 6313 schedulePersistUriGrants(); 6314 } 6315 } 6316 6317 @Override 6318 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6319 int modeFlags) { 6320 enforceNotIsolatedCaller("revokeUriPermission"); 6321 synchronized(this) { 6322 final ProcessRecord r = getRecordForAppLocked(caller); 6323 if (r == null) { 6324 throw new SecurityException("Unable to find app for caller " 6325 + caller 6326 + " when revoking permission to uri " + uri); 6327 } 6328 if (uri == null) { 6329 Slog.w(TAG, "revokeUriPermission: null uri"); 6330 return; 6331 } 6332 6333 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6334 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6335 if (modeFlags == 0) { 6336 return; 6337 } 6338 6339 final IPackageManager pm = AppGlobals.getPackageManager(); 6340 final String authority = uri.getAuthority(); 6341 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6342 if (pi == null) { 6343 Slog.w(TAG, "No content provider found for permission revoke: " 6344 + uri.toSafeString()); 6345 return; 6346 } 6347 6348 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6349 } 6350 } 6351 6352 /** 6353 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6354 * given package. 6355 * 6356 * @param packageName Package name to match, or {@code null} to apply to all 6357 * packages. 6358 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6359 * to all users. 6360 * @param persistable If persistable grants should be removed. 6361 */ 6362 private void removeUriPermissionsForPackageLocked( 6363 String packageName, int userHandle, boolean persistable) { 6364 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6365 throw new IllegalArgumentException("Must narrow by either package or user"); 6366 } 6367 6368 boolean persistChanged = false; 6369 6370 final int size = mGrantedUriPermissions.size(); 6371 for (int i = 0; i < size; i++) { 6372 // Only inspect grants matching user 6373 if (userHandle == UserHandle.USER_ALL 6374 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6375 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6376 .values().iterator(); 6377 while (it.hasNext()) { 6378 final UriPermission perm = it.next(); 6379 6380 // Only inspect grants matching package 6381 if (packageName == null || perm.sourcePkg.equals(packageName) 6382 || perm.targetPkg.equals(packageName)) { 6383 persistChanged |= perm.clearModes(~0, persistable); 6384 6385 // Only remove when no modes remain; any persisted grants 6386 // will keep this alive. 6387 if (perm.modeFlags == 0) { 6388 it.remove(); 6389 } 6390 } 6391 } 6392 } 6393 } 6394 6395 if (persistChanged) { 6396 schedulePersistUriGrants(); 6397 } 6398 } 6399 6400 @Override 6401 public IBinder newUriPermissionOwner(String name) { 6402 enforceNotIsolatedCaller("newUriPermissionOwner"); 6403 synchronized(this) { 6404 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6405 return owner.getExternalTokenLocked(); 6406 } 6407 } 6408 6409 @Override 6410 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6411 Uri uri, int modeFlags) { 6412 synchronized(this) { 6413 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6414 if (owner == null) { 6415 throw new IllegalArgumentException("Unknown owner: " + token); 6416 } 6417 if (fromUid != Binder.getCallingUid()) { 6418 if (Binder.getCallingUid() != Process.myUid()) { 6419 // Only system code can grant URI permissions on behalf 6420 // of other users. 6421 throw new SecurityException("nice try"); 6422 } 6423 } 6424 if (targetPkg == null) { 6425 throw new IllegalArgumentException("null target"); 6426 } 6427 if (uri == null) { 6428 throw new IllegalArgumentException("null uri"); 6429 } 6430 6431 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6432 } 6433 } 6434 6435 @Override 6436 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6437 synchronized(this) { 6438 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6439 if (owner == null) { 6440 throw new IllegalArgumentException("Unknown owner: " + token); 6441 } 6442 6443 if (uri == null) { 6444 owner.removeUriPermissionsLocked(mode); 6445 } else { 6446 owner.removeUriPermissionLocked(uri, mode); 6447 } 6448 } 6449 } 6450 6451 private void schedulePersistUriGrants() { 6452 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6453 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6454 10 * DateUtils.SECOND_IN_MILLIS); 6455 } 6456 } 6457 6458 private void writeGrantedUriPermissions() { 6459 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6460 6461 // Snapshot permissions so we can persist without lock 6462 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6463 synchronized (this) { 6464 final int size = mGrantedUriPermissions.size(); 6465 for (int i = 0 ; i < size; i++) { 6466 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6467 if (perm.persistedModeFlags != 0) { 6468 persist.add(perm.snapshot()); 6469 } 6470 } 6471 } 6472 } 6473 6474 FileOutputStream fos = null; 6475 try { 6476 fos = mGrantFile.startWrite(); 6477 6478 XmlSerializer out = new FastXmlSerializer(); 6479 out.setOutput(fos, "utf-8"); 6480 out.startDocument(null, true); 6481 out.startTag(null, TAG_URI_GRANTS); 6482 for (UriPermission.Snapshot perm : persist) { 6483 out.startTag(null, TAG_URI_GRANT); 6484 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6485 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6486 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6487 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6488 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6489 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6490 out.endTag(null, TAG_URI_GRANT); 6491 } 6492 out.endTag(null, TAG_URI_GRANTS); 6493 out.endDocument(); 6494 6495 mGrantFile.finishWrite(fos); 6496 } catch (IOException e) { 6497 if (fos != null) { 6498 mGrantFile.failWrite(fos); 6499 } 6500 } 6501 } 6502 6503 private void readGrantedUriPermissionsLocked() { 6504 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6505 6506 final long now = System.currentTimeMillis(); 6507 6508 FileInputStream fis = null; 6509 try { 6510 fis = mGrantFile.openRead(); 6511 final XmlPullParser in = Xml.newPullParser(); 6512 in.setInput(fis, null); 6513 6514 int type; 6515 while ((type = in.next()) != END_DOCUMENT) { 6516 final String tag = in.getName(); 6517 if (type == START_TAG) { 6518 if (TAG_URI_GRANT.equals(tag)) { 6519 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6520 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6521 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6522 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6523 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6524 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6525 6526 // Sanity check that provider still belongs to source package 6527 final ProviderInfo pi = getProviderInfoLocked( 6528 uri.getAuthority(), userHandle); 6529 if (pi != null && sourcePkg.equals(pi.packageName)) { 6530 int targetUid = -1; 6531 try { 6532 targetUid = AppGlobals.getPackageManager() 6533 .getPackageUid(targetPkg, userHandle); 6534 } catch (RemoteException e) { 6535 } 6536 if (targetUid != -1) { 6537 final UriPermission perm = findOrCreateUriPermissionLocked( 6538 sourcePkg, targetPkg, targetUid, uri); 6539 perm.initPersistedModes(modeFlags, createdTime); 6540 } 6541 } else { 6542 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6543 + " but instead found " + pi); 6544 } 6545 } 6546 } 6547 } 6548 } catch (FileNotFoundException e) { 6549 // Missing grants is okay 6550 } catch (IOException e) { 6551 Log.wtf(TAG, "Failed reading Uri grants", e); 6552 } catch (XmlPullParserException e) { 6553 Log.wtf(TAG, "Failed reading Uri grants", e); 6554 } finally { 6555 IoUtils.closeQuietly(fis); 6556 } 6557 } 6558 6559 @Override 6560 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6561 enforceNotIsolatedCaller("takePersistableUriPermission"); 6562 6563 Preconditions.checkFlagsArgument(modeFlags, 6564 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6565 6566 synchronized (this) { 6567 final int callingUid = Binder.getCallingUid(); 6568 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6569 if (perm == null) { 6570 throw new SecurityException("No permission grant found for UID " + callingUid 6571 + " and Uri " + uri.toSafeString()); 6572 } 6573 6574 boolean persistChanged = perm.takePersistableModes(modeFlags); 6575 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6576 6577 if (persistChanged) { 6578 schedulePersistUriGrants(); 6579 } 6580 } 6581 } 6582 6583 @Override 6584 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6585 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6586 6587 Preconditions.checkFlagsArgument(modeFlags, 6588 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6589 6590 synchronized (this) { 6591 final int callingUid = Binder.getCallingUid(); 6592 6593 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6594 if (perm == null) { 6595 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6596 + uri.toSafeString()); 6597 return; 6598 } 6599 6600 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6601 removeUriPermissionIfNeededLocked(perm); 6602 if (persistChanged) { 6603 schedulePersistUriGrants(); 6604 } 6605 } 6606 } 6607 6608 /** 6609 * Prune any older {@link UriPermission} for the given UID until outstanding 6610 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6611 * 6612 * @return if any mutations occured that require persisting. 6613 */ 6614 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6615 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6616 if (perms == null) return false; 6617 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6618 6619 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6620 for (UriPermission perm : perms.values()) { 6621 if (perm.persistedModeFlags != 0) { 6622 persisted.add(perm); 6623 } 6624 } 6625 6626 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6627 if (trimCount <= 0) return false; 6628 6629 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6630 for (int i = 0; i < trimCount; i++) { 6631 final UriPermission perm = persisted.get(i); 6632 6633 if (DEBUG_URI_PERMISSION) { 6634 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6635 } 6636 6637 perm.releasePersistableModes(~0); 6638 removeUriPermissionIfNeededLocked(perm); 6639 } 6640 6641 return true; 6642 } 6643 6644 @Override 6645 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6646 String packageName, boolean incoming) { 6647 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6648 Preconditions.checkNotNull(packageName, "packageName"); 6649 6650 final int callingUid = Binder.getCallingUid(); 6651 final IPackageManager pm = AppGlobals.getPackageManager(); 6652 try { 6653 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6654 if (packageUid != callingUid) { 6655 throw new SecurityException( 6656 "Package " + packageName + " does not belong to calling UID " + callingUid); 6657 } 6658 } catch (RemoteException e) { 6659 throw new SecurityException("Failed to verify package name ownership"); 6660 } 6661 6662 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6663 synchronized (this) { 6664 if (incoming) { 6665 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6666 if (perms == null) { 6667 Slog.w(TAG, "No permission grants found for " + packageName); 6668 } else { 6669 final int size = perms.size(); 6670 for (int i = 0; i < size; i++) { 6671 final UriPermission perm = perms.valueAt(i); 6672 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6673 result.add(perm.buildPersistedPublicApiObject()); 6674 } 6675 } 6676 } 6677 } else { 6678 final int size = mGrantedUriPermissions.size(); 6679 for (int i = 0; i < size; i++) { 6680 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6681 final int permsSize = perms.size(); 6682 for (int j = 0; j < permsSize; j++) { 6683 final UriPermission perm = perms.valueAt(j); 6684 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6685 result.add(perm.buildPersistedPublicApiObject()); 6686 } 6687 } 6688 } 6689 } 6690 } 6691 return new ParceledListSlice<android.content.UriPermission>(result); 6692 } 6693 6694 @Override 6695 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6696 synchronized (this) { 6697 ProcessRecord app = 6698 who != null ? getRecordForAppLocked(who) : null; 6699 if (app == null) return; 6700 6701 Message msg = Message.obtain(); 6702 msg.what = WAIT_FOR_DEBUGGER_MSG; 6703 msg.obj = app; 6704 msg.arg1 = waiting ? 1 : 0; 6705 mHandler.sendMessage(msg); 6706 } 6707 } 6708 6709 @Override 6710 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6711 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6712 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6713 outInfo.availMem = Process.getFreeMemory(); 6714 outInfo.totalMem = Process.getTotalMemory(); 6715 outInfo.threshold = homeAppMem; 6716 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6717 outInfo.hiddenAppThreshold = cachedAppMem; 6718 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6719 ProcessList.SERVICE_ADJ); 6720 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6721 ProcessList.VISIBLE_APP_ADJ); 6722 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6723 ProcessList.FOREGROUND_APP_ADJ); 6724 } 6725 6726 // ========================================================= 6727 // TASK MANAGEMENT 6728 // ========================================================= 6729 6730 @Override 6731 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6732 IThumbnailReceiver receiver) { 6733 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6734 6735 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6736 ActivityRecord topRecord = null; 6737 6738 synchronized(this) { 6739 if (localLOGV) Slog.v( 6740 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6741 + ", receiver=" + receiver); 6742 6743 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6744 != PackageManager.PERMISSION_GRANTED) { 6745 if (receiver != null) { 6746 // If the caller wants to wait for pending thumbnails, 6747 // it ain't gonna get them. 6748 try { 6749 receiver.finished(); 6750 } catch (RemoteException ex) { 6751 } 6752 } 6753 String msg = "Permission Denial: getTasks() from pid=" 6754 + Binder.getCallingPid() 6755 + ", uid=" + Binder.getCallingUid() 6756 + " requires " + android.Manifest.permission.GET_TASKS; 6757 Slog.w(TAG, msg); 6758 throw new SecurityException(msg); 6759 } 6760 6761 // TODO: Improve with MRU list from all ActivityStacks. 6762 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6763 6764 if (!pending.pendingRecords.isEmpty()) { 6765 mPendingThumbnails.add(pending); 6766 } 6767 } 6768 6769 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6770 6771 if (topRecord != null) { 6772 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6773 try { 6774 IApplicationThread topThumbnail = topRecord.app.thread; 6775 topThumbnail.requestThumbnail(topRecord.appToken); 6776 } catch (Exception e) { 6777 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6778 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6779 } 6780 } 6781 6782 if (pending == null && receiver != null) { 6783 // In this case all thumbnails were available and the client 6784 // is being asked to be told when the remaining ones come in... 6785 // which is unusually, since the top-most currently running 6786 // activity should never have a canned thumbnail! Oh well. 6787 try { 6788 receiver.finished(); 6789 } catch (RemoteException ex) { 6790 } 6791 } 6792 6793 return list; 6794 } 6795 6796 TaskRecord getMostRecentTask() { 6797 return mRecentTasks.get(0); 6798 } 6799 6800 @Override 6801 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6802 int flags, int userId) { 6803 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6804 false, true, "getRecentTasks", null); 6805 6806 synchronized (this) { 6807 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6808 "getRecentTasks()"); 6809 final boolean detailed = checkCallingPermission( 6810 android.Manifest.permission.GET_DETAILED_TASKS) 6811 == PackageManager.PERMISSION_GRANTED; 6812 6813 IPackageManager pm = AppGlobals.getPackageManager(); 6814 6815 final int N = mRecentTasks.size(); 6816 ArrayList<ActivityManager.RecentTaskInfo> res 6817 = new ArrayList<ActivityManager.RecentTaskInfo>( 6818 maxNum < N ? maxNum : N); 6819 for (int i=0; i<N && maxNum > 0; i++) { 6820 TaskRecord tr = mRecentTasks.get(i); 6821 // Only add calling user's recent tasks 6822 if (tr.userId != userId) continue; 6823 // Return the entry if desired by the caller. We always return 6824 // the first entry, because callers always expect this to be the 6825 // foreground app. We may filter others if the caller has 6826 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6827 // we should exclude the entry. 6828 6829 if (i == 0 6830 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6831 || (tr.intent == null) 6832 || ((tr.intent.getFlags() 6833 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6834 ActivityManager.RecentTaskInfo rti 6835 = new ActivityManager.RecentTaskInfo(); 6836 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6837 rti.persistentId = tr.taskId; 6838 rti.baseIntent = new Intent( 6839 tr.intent != null ? tr.intent : tr.affinityIntent); 6840 if (!detailed) { 6841 rti.baseIntent.replaceExtras((Bundle)null); 6842 } 6843 rti.origActivity = tr.origActivity; 6844 rti.description = tr.lastDescription; 6845 rti.stackId = tr.stack.mStackId; 6846 6847 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6848 // Check whether this activity is currently available. 6849 try { 6850 if (rti.origActivity != null) { 6851 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6852 == null) { 6853 continue; 6854 } 6855 } else if (rti.baseIntent != null) { 6856 if (pm.queryIntentActivities(rti.baseIntent, 6857 null, 0, userId) == null) { 6858 continue; 6859 } 6860 } 6861 } catch (RemoteException e) { 6862 // Will never happen. 6863 } 6864 } 6865 6866 res.add(rti); 6867 maxNum--; 6868 } 6869 } 6870 return res; 6871 } 6872 } 6873 6874 private TaskRecord recentTaskForIdLocked(int id) { 6875 final int N = mRecentTasks.size(); 6876 for (int i=0; i<N; i++) { 6877 TaskRecord tr = mRecentTasks.get(i); 6878 if (tr.taskId == id) { 6879 return tr; 6880 } 6881 } 6882 return null; 6883 } 6884 6885 @Override 6886 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6887 synchronized (this) { 6888 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6889 "getTaskThumbnails()"); 6890 TaskRecord tr = recentTaskForIdLocked(id); 6891 if (tr != null) { 6892 return tr.getTaskThumbnailsLocked(); 6893 } 6894 } 6895 return null; 6896 } 6897 6898 @Override 6899 public Bitmap getTaskTopThumbnail(int id) { 6900 synchronized (this) { 6901 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6902 "getTaskTopThumbnail()"); 6903 TaskRecord tr = recentTaskForIdLocked(id); 6904 if (tr != null) { 6905 return tr.getTaskTopThumbnailLocked(); 6906 } 6907 } 6908 return null; 6909 } 6910 6911 @Override 6912 public boolean removeSubTask(int taskId, int subTaskIndex) { 6913 synchronized (this) { 6914 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6915 "removeSubTask()"); 6916 long ident = Binder.clearCallingIdentity(); 6917 try { 6918 TaskRecord tr = recentTaskForIdLocked(taskId); 6919 if (tr != null) { 6920 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6921 } 6922 return false; 6923 } finally { 6924 Binder.restoreCallingIdentity(ident); 6925 } 6926 } 6927 } 6928 6929 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6930 if (!pr.killedByAm) { 6931 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6932 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6933 pr.processName, pr.setAdj, reason); 6934 pr.killedByAm = true; 6935 Process.killProcessQuiet(pr.pid); 6936 } 6937 } 6938 6939 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6940 tr.disposeThumbnail(); 6941 mRecentTasks.remove(tr); 6942 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6943 Intent baseIntent = new Intent( 6944 tr.intent != null ? tr.intent : tr.affinityIntent); 6945 ComponentName component = baseIntent.getComponent(); 6946 if (component == null) { 6947 Slog.w(TAG, "Now component for base intent of task: " + tr); 6948 return; 6949 } 6950 6951 // Find any running services associated with this app. 6952 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6953 6954 if (killProcesses) { 6955 // Find any running processes associated with this app. 6956 final String pkg = component.getPackageName(); 6957 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6958 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 6959 for (int i=0; i<pmap.size(); i++) { 6960 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 6961 for (int j=0; j<uids.size(); j++) { 6962 ProcessRecord proc = uids.valueAt(j); 6963 if (proc.userId != tr.userId) { 6964 continue; 6965 } 6966 if (!proc.pkgList.containsKey(pkg)) { 6967 continue; 6968 } 6969 procs.add(proc); 6970 } 6971 } 6972 6973 // Kill the running processes. 6974 for (int i=0; i<procs.size(); i++) { 6975 ProcessRecord pr = procs.get(i); 6976 if (pr == mHomeProcess) { 6977 // Don't kill the home process along with tasks from the same package. 6978 continue; 6979 } 6980 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 6981 killUnneededProcessLocked(pr, "remove task"); 6982 } else { 6983 pr.waitingToKill = "remove task"; 6984 } 6985 } 6986 } 6987 } 6988 6989 @Override 6990 public boolean removeTask(int taskId, int flags) { 6991 synchronized (this) { 6992 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6993 "removeTask()"); 6994 long ident = Binder.clearCallingIdentity(); 6995 try { 6996 TaskRecord tr = recentTaskForIdLocked(taskId); 6997 if (tr != null) { 6998 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 6999 if (r != null) { 7000 cleanUpRemovedTaskLocked(tr, flags); 7001 return true; 7002 } 7003 if (tr.mActivities.size() == 0) { 7004 // Caller is just removing a recent task that is 7005 // not actively running. That is easy! 7006 cleanUpRemovedTaskLocked(tr, flags); 7007 return true; 7008 } 7009 Slog.w(TAG, "removeTask: task " + taskId 7010 + " does not have activities to remove, " 7011 + " but numActivities=" + tr.numActivities 7012 + ": " + tr); 7013 } 7014 } finally { 7015 Binder.restoreCallingIdentity(ident); 7016 } 7017 } 7018 return false; 7019 } 7020 7021 /** 7022 * TODO: Add mController hook 7023 */ 7024 @Override 7025 public void moveTaskToFront(int task, int flags, Bundle options) { 7026 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7027 "moveTaskToFront()"); 7028 7029 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task); 7030 synchronized(this) { 7031 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7032 Binder.getCallingUid(), "Task to front")) { 7033 ActivityOptions.abort(options); 7034 return; 7035 } 7036 final long origId = Binder.clearCallingIdentity(); 7037 try { 7038 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7039 } finally { 7040 Binder.restoreCallingIdentity(origId); 7041 } 7042 ActivityOptions.abort(options); 7043 } 7044 } 7045 7046 @Override 7047 public void moveTaskToBack(int taskId) { 7048 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7049 "moveTaskToBack()"); 7050 7051 synchronized(this) { 7052 TaskRecord tr = recentTaskForIdLocked(taskId); 7053 if (tr != null) { 7054 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7055 ActivityStack stack = tr.stack; 7056 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7057 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7058 Binder.getCallingUid(), "Task to back")) { 7059 return; 7060 } 7061 } 7062 final long origId = Binder.clearCallingIdentity(); 7063 try { 7064 stack.moveTaskToBackLocked(taskId, null); 7065 } finally { 7066 Binder.restoreCallingIdentity(origId); 7067 } 7068 } 7069 } 7070 } 7071 7072 /** 7073 * Moves an activity, and all of the other activities within the same task, to the bottom 7074 * of the history stack. The activity's order within the task is unchanged. 7075 * 7076 * @param token A reference to the activity we wish to move 7077 * @param nonRoot If false then this only works if the activity is the root 7078 * of a task; if true it will work for any activity in a task. 7079 * @return Returns true if the move completed, false if not. 7080 */ 7081 @Override 7082 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7083 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7084 synchronized(this) { 7085 final long origId = Binder.clearCallingIdentity(); 7086 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7087 if (taskId >= 0) { 7088 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7089 } 7090 Binder.restoreCallingIdentity(origId); 7091 } 7092 return false; 7093 } 7094 7095 @Override 7096 public void moveTaskBackwards(int task) { 7097 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7098 "moveTaskBackwards()"); 7099 7100 synchronized(this) { 7101 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7102 Binder.getCallingUid(), "Task backwards")) { 7103 return; 7104 } 7105 final long origId = Binder.clearCallingIdentity(); 7106 moveTaskBackwardsLocked(task); 7107 Binder.restoreCallingIdentity(origId); 7108 } 7109 } 7110 7111 private final void moveTaskBackwardsLocked(int task) { 7112 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7113 } 7114 7115 @Override 7116 public IBinder getHomeActivityToken() throws RemoteException { 7117 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7118 "getHomeActivityToken()"); 7119 synchronized (this) { 7120 return mStackSupervisor.getHomeActivityToken(); 7121 } 7122 } 7123 7124 @Override 7125 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7126 IActivityContainerCallback callback) throws RemoteException { 7127 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7128 "createActivityContainer()"); 7129 synchronized (this) { 7130 if (parentActivityToken == null) { 7131 throw new IllegalArgumentException("parent token must not be null"); 7132 } 7133 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7134 if (r == null) { 7135 return null; 7136 } 7137 return mStackSupervisor.createActivityContainer(r, callback); 7138 } 7139 } 7140 7141 @Override 7142 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7143 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7144 "deleteActivityContainer()"); 7145 synchronized (this) { 7146 mStackSupervisor.deleteActivityContainer(container); 7147 } 7148 } 7149 7150 @Override 7151 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7152 throws RemoteException { 7153 synchronized (this) { 7154 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7155 if (stack != null) { 7156 return stack.mActivityContainer; 7157 } 7158 return null; 7159 } 7160 } 7161 7162 @Override 7163 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7164 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7165 "moveTaskToStack()"); 7166 if (stackId == HOME_STACK_ID) { 7167 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7168 new RuntimeException("here").fillInStackTrace()); 7169 } 7170 synchronized (this) { 7171 long ident = Binder.clearCallingIdentity(); 7172 try { 7173 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7174 + stackId + " toTop=" + toTop); 7175 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7176 } finally { 7177 Binder.restoreCallingIdentity(ident); 7178 } 7179 } 7180 } 7181 7182 @Override 7183 public void resizeStack(int stackBoxId, Rect bounds) { 7184 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7185 "resizeStackBox()"); 7186 long ident = Binder.clearCallingIdentity(); 7187 try { 7188 mWindowManager.resizeStack(stackBoxId, bounds); 7189 } finally { 7190 Binder.restoreCallingIdentity(ident); 7191 } 7192 } 7193 7194 @Override 7195 public List<StackInfo> getAllStackInfos() { 7196 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7197 "getAllStackInfos()"); 7198 long ident = Binder.clearCallingIdentity(); 7199 try { 7200 synchronized (this) { 7201 return mStackSupervisor.getAllStackInfosLocked(); 7202 } 7203 } finally { 7204 Binder.restoreCallingIdentity(ident); 7205 } 7206 } 7207 7208 @Override 7209 public StackInfo getStackInfo(int stackId) { 7210 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7211 "getStackInfo()"); 7212 long ident = Binder.clearCallingIdentity(); 7213 try { 7214 synchronized (this) { 7215 return mStackSupervisor.getStackInfoLocked(stackId); 7216 } 7217 } finally { 7218 Binder.restoreCallingIdentity(ident); 7219 } 7220 } 7221 7222 @Override 7223 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7224 synchronized(this) { 7225 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7226 } 7227 } 7228 7229 // ========================================================= 7230 // THUMBNAILS 7231 // ========================================================= 7232 7233 public void reportThumbnail(IBinder token, 7234 Bitmap thumbnail, CharSequence description) { 7235 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7236 final long origId = Binder.clearCallingIdentity(); 7237 sendPendingThumbnail(null, token, thumbnail, description, true); 7238 Binder.restoreCallingIdentity(origId); 7239 } 7240 7241 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7242 Bitmap thumbnail, CharSequence description, boolean always) { 7243 TaskRecord task; 7244 ArrayList<PendingThumbnailsRecord> receivers = null; 7245 7246 //System.out.println("Send pending thumbnail: " + r); 7247 7248 synchronized(this) { 7249 if (r == null) { 7250 r = ActivityRecord.isInStackLocked(token); 7251 if (r == null) { 7252 return; 7253 } 7254 } 7255 if (thumbnail == null && r.thumbHolder != null) { 7256 thumbnail = r.thumbHolder.lastThumbnail; 7257 description = r.thumbHolder.lastDescription; 7258 } 7259 if (thumbnail == null && !always) { 7260 // If there is no thumbnail, and this entry is not actually 7261 // going away, then abort for now and pick up the next 7262 // thumbnail we get. 7263 return; 7264 } 7265 task = r.task; 7266 7267 int N = mPendingThumbnails.size(); 7268 int i=0; 7269 while (i<N) { 7270 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7271 //System.out.println("Looking in " + pr.pendingRecords); 7272 if (pr.pendingRecords.remove(r)) { 7273 if (receivers == null) { 7274 receivers = new ArrayList<PendingThumbnailsRecord>(); 7275 } 7276 receivers.add(pr); 7277 if (pr.pendingRecords.size() == 0) { 7278 pr.finished = true; 7279 mPendingThumbnails.remove(i); 7280 N--; 7281 continue; 7282 } 7283 } 7284 i++; 7285 } 7286 } 7287 7288 if (receivers != null) { 7289 final int N = receivers.size(); 7290 for (int i=0; i<N; i++) { 7291 try { 7292 PendingThumbnailsRecord pr = receivers.get(i); 7293 pr.receiver.newThumbnail( 7294 task != null ? task.taskId : -1, thumbnail, description); 7295 if (pr.finished) { 7296 pr.receiver.finished(); 7297 } 7298 } catch (Exception e) { 7299 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7300 } 7301 } 7302 } 7303 } 7304 7305 // ========================================================= 7306 // CONTENT PROVIDERS 7307 // ========================================================= 7308 7309 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7310 List<ProviderInfo> providers = null; 7311 try { 7312 providers = AppGlobals.getPackageManager(). 7313 queryContentProviders(app.processName, app.uid, 7314 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7315 } catch (RemoteException ex) { 7316 } 7317 if (DEBUG_MU) 7318 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7319 int userId = app.userId; 7320 if (providers != null) { 7321 int N = providers.size(); 7322 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7323 for (int i=0; i<N; i++) { 7324 ProviderInfo cpi = 7325 (ProviderInfo)providers.get(i); 7326 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7327 cpi.name, cpi.flags); 7328 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7329 // This is a singleton provider, but a user besides the 7330 // default user is asking to initialize a process it runs 7331 // in... well, no, it doesn't actually run in this process, 7332 // it runs in the process of the default user. Get rid of it. 7333 providers.remove(i); 7334 N--; 7335 i--; 7336 continue; 7337 } 7338 7339 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7340 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7341 if (cpr == null) { 7342 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7343 mProviderMap.putProviderByClass(comp, cpr); 7344 } 7345 if (DEBUG_MU) 7346 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7347 app.pubProviders.put(cpi.name, cpr); 7348 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7349 // Don't add this if it is a platform component that is marked 7350 // to run in multiple processes, because this is actually 7351 // part of the framework so doesn't make sense to track as a 7352 // separate apk in the process. 7353 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7354 } 7355 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7356 } 7357 } 7358 return providers; 7359 } 7360 7361 /** 7362 * Check if {@link ProcessRecord} has a possible chance at accessing the 7363 * given {@link ProviderInfo}. Final permission checking is always done 7364 * in {@link ContentProvider}. 7365 */ 7366 private final String checkContentProviderPermissionLocked( 7367 ProviderInfo cpi, ProcessRecord r) { 7368 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7369 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7370 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7371 cpi.applicationInfo.uid, cpi.exported) 7372 == PackageManager.PERMISSION_GRANTED) { 7373 return null; 7374 } 7375 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7376 cpi.applicationInfo.uid, cpi.exported) 7377 == PackageManager.PERMISSION_GRANTED) { 7378 return null; 7379 } 7380 7381 PathPermission[] pps = cpi.pathPermissions; 7382 if (pps != null) { 7383 int i = pps.length; 7384 while (i > 0) { 7385 i--; 7386 PathPermission pp = pps[i]; 7387 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7388 cpi.applicationInfo.uid, cpi.exported) 7389 == PackageManager.PERMISSION_GRANTED) { 7390 return null; 7391 } 7392 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7393 cpi.applicationInfo.uid, cpi.exported) 7394 == PackageManager.PERMISSION_GRANTED) { 7395 return null; 7396 } 7397 } 7398 } 7399 7400 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7401 if (perms != null) { 7402 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7403 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7404 return null; 7405 } 7406 } 7407 } 7408 7409 String msg; 7410 if (!cpi.exported) { 7411 msg = "Permission Denial: opening provider " + cpi.name 7412 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7413 + ", uid=" + callingUid + ") that is not exported from uid " 7414 + cpi.applicationInfo.uid; 7415 } else { 7416 msg = "Permission Denial: opening provider " + cpi.name 7417 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7418 + ", uid=" + callingUid + ") requires " 7419 + cpi.readPermission + " or " + cpi.writePermission; 7420 } 7421 Slog.w(TAG, msg); 7422 return msg; 7423 } 7424 7425 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7426 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7427 if (r != null) { 7428 for (int i=0; i<r.conProviders.size(); i++) { 7429 ContentProviderConnection conn = r.conProviders.get(i); 7430 if (conn.provider == cpr) { 7431 if (DEBUG_PROVIDER) Slog.v(TAG, 7432 "Adding provider requested by " 7433 + r.processName + " from process " 7434 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7435 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7436 if (stable) { 7437 conn.stableCount++; 7438 conn.numStableIncs++; 7439 } else { 7440 conn.unstableCount++; 7441 conn.numUnstableIncs++; 7442 } 7443 return conn; 7444 } 7445 } 7446 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7447 if (stable) { 7448 conn.stableCount = 1; 7449 conn.numStableIncs = 1; 7450 } else { 7451 conn.unstableCount = 1; 7452 conn.numUnstableIncs = 1; 7453 } 7454 cpr.connections.add(conn); 7455 r.conProviders.add(conn); 7456 return conn; 7457 } 7458 cpr.addExternalProcessHandleLocked(externalProcessToken); 7459 return null; 7460 } 7461 7462 boolean decProviderCountLocked(ContentProviderConnection conn, 7463 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7464 if (conn != null) { 7465 cpr = conn.provider; 7466 if (DEBUG_PROVIDER) Slog.v(TAG, 7467 "Removing provider requested by " 7468 + conn.client.processName + " from process " 7469 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7470 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7471 if (stable) { 7472 conn.stableCount--; 7473 } else { 7474 conn.unstableCount--; 7475 } 7476 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7477 cpr.connections.remove(conn); 7478 conn.client.conProviders.remove(conn); 7479 return true; 7480 } 7481 return false; 7482 } 7483 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7484 return false; 7485 } 7486 7487 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7488 String name, IBinder token, boolean stable, int userId) { 7489 ContentProviderRecord cpr; 7490 ContentProviderConnection conn = null; 7491 ProviderInfo cpi = null; 7492 7493 synchronized(this) { 7494 ProcessRecord r = null; 7495 if (caller != null) { 7496 r = getRecordForAppLocked(caller); 7497 if (r == null) { 7498 throw new SecurityException( 7499 "Unable to find app for caller " + caller 7500 + " (pid=" + Binder.getCallingPid() 7501 + ") when getting content provider " + name); 7502 } 7503 } 7504 7505 // First check if this content provider has been published... 7506 cpr = mProviderMap.getProviderByName(name, userId); 7507 boolean providerRunning = cpr != null; 7508 if (providerRunning) { 7509 cpi = cpr.info; 7510 String msg; 7511 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7512 throw new SecurityException(msg); 7513 } 7514 7515 if (r != null && cpr.canRunHere(r)) { 7516 // This provider has been published or is in the process 7517 // of being published... but it is also allowed to run 7518 // in the caller's process, so don't make a connection 7519 // and just let the caller instantiate its own instance. 7520 ContentProviderHolder holder = cpr.newHolder(null); 7521 // don't give caller the provider object, it needs 7522 // to make its own. 7523 holder.provider = null; 7524 return holder; 7525 } 7526 7527 final long origId = Binder.clearCallingIdentity(); 7528 7529 // In this case the provider instance already exists, so we can 7530 // return it right away. 7531 conn = incProviderCountLocked(r, cpr, token, stable); 7532 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7533 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7534 // If this is a perceptible app accessing the provider, 7535 // make sure to count it as being accessed and thus 7536 // back up on the LRU list. This is good because 7537 // content providers are often expensive to start. 7538 updateLruProcessLocked(cpr.proc, false, null); 7539 } 7540 } 7541 7542 if (cpr.proc != null) { 7543 if (false) { 7544 if (cpr.name.flattenToShortString().equals( 7545 "com.android.providers.calendar/.CalendarProvider2")) { 7546 Slog.v(TAG, "****************** KILLING " 7547 + cpr.name.flattenToShortString()); 7548 Process.killProcess(cpr.proc.pid); 7549 } 7550 } 7551 boolean success = updateOomAdjLocked(cpr.proc); 7552 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7553 // NOTE: there is still a race here where a signal could be 7554 // pending on the process even though we managed to update its 7555 // adj level. Not sure what to do about this, but at least 7556 // the race is now smaller. 7557 if (!success) { 7558 // Uh oh... it looks like the provider's process 7559 // has been killed on us. We need to wait for a new 7560 // process to be started, and make sure its death 7561 // doesn't kill our process. 7562 Slog.i(TAG, 7563 "Existing provider " + cpr.name.flattenToShortString() 7564 + " is crashing; detaching " + r); 7565 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7566 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7567 if (!lastRef) { 7568 // This wasn't the last ref our process had on 7569 // the provider... we have now been killed, bail. 7570 return null; 7571 } 7572 providerRunning = false; 7573 conn = null; 7574 } 7575 } 7576 7577 Binder.restoreCallingIdentity(origId); 7578 } 7579 7580 boolean singleton; 7581 if (!providerRunning) { 7582 try { 7583 cpi = AppGlobals.getPackageManager(). 7584 resolveContentProvider(name, 7585 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7586 } catch (RemoteException ex) { 7587 } 7588 if (cpi == null) { 7589 return null; 7590 } 7591 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7592 cpi.name, cpi.flags); 7593 if (singleton) { 7594 userId = 0; 7595 } 7596 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7597 7598 String msg; 7599 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7600 throw new SecurityException(msg); 7601 } 7602 7603 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7604 && !cpi.processName.equals("system")) { 7605 // If this content provider does not run in the system 7606 // process, and the system is not yet ready to run other 7607 // processes, then fail fast instead of hanging. 7608 throw new IllegalArgumentException( 7609 "Attempt to launch content provider before system ready"); 7610 } 7611 7612 // Make sure that the user who owns this provider is started. If not, 7613 // we don't want to allow it to run. 7614 if (mStartedUsers.get(userId) == null) { 7615 Slog.w(TAG, "Unable to launch app " 7616 + cpi.applicationInfo.packageName + "/" 7617 + cpi.applicationInfo.uid + " for provider " 7618 + name + ": user " + userId + " is stopped"); 7619 return null; 7620 } 7621 7622 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7623 cpr = mProviderMap.getProviderByClass(comp, userId); 7624 final boolean firstClass = cpr == null; 7625 if (firstClass) { 7626 try { 7627 ApplicationInfo ai = 7628 AppGlobals.getPackageManager(). 7629 getApplicationInfo( 7630 cpi.applicationInfo.packageName, 7631 STOCK_PM_FLAGS, userId); 7632 if (ai == null) { 7633 Slog.w(TAG, "No package info for content provider " 7634 + cpi.name); 7635 return null; 7636 } 7637 ai = getAppInfoForUser(ai, userId); 7638 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7639 } catch (RemoteException ex) { 7640 // pm is in same process, this will never happen. 7641 } 7642 } 7643 7644 if (r != null && cpr.canRunHere(r)) { 7645 // If this is a multiprocess provider, then just return its 7646 // info and allow the caller to instantiate it. Only do 7647 // this if the provider is the same user as the caller's 7648 // process, or can run as root (so can be in any process). 7649 return cpr.newHolder(null); 7650 } 7651 7652 if (DEBUG_PROVIDER) { 7653 RuntimeException e = new RuntimeException("here"); 7654 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7655 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7656 } 7657 7658 // This is single process, and our app is now connecting to it. 7659 // See if we are already in the process of launching this 7660 // provider. 7661 final int N = mLaunchingProviders.size(); 7662 int i; 7663 for (i=0; i<N; i++) { 7664 if (mLaunchingProviders.get(i) == cpr) { 7665 break; 7666 } 7667 } 7668 7669 // If the provider is not already being launched, then get it 7670 // started. 7671 if (i >= N) { 7672 final long origId = Binder.clearCallingIdentity(); 7673 7674 try { 7675 // Content provider is now in use, its package can't be stopped. 7676 try { 7677 AppGlobals.getPackageManager().setPackageStoppedState( 7678 cpr.appInfo.packageName, false, userId); 7679 } catch (RemoteException e) { 7680 } catch (IllegalArgumentException e) { 7681 Slog.w(TAG, "Failed trying to unstop package " 7682 + cpr.appInfo.packageName + ": " + e); 7683 } 7684 7685 // Use existing process if already started 7686 ProcessRecord proc = getProcessRecordLocked( 7687 cpi.processName, cpr.appInfo.uid, false); 7688 if (proc != null && proc.thread != null) { 7689 if (DEBUG_PROVIDER) { 7690 Slog.d(TAG, "Installing in existing process " + proc); 7691 } 7692 proc.pubProviders.put(cpi.name, cpr); 7693 try { 7694 proc.thread.scheduleInstallProvider(cpi); 7695 } catch (RemoteException e) { 7696 } 7697 } else { 7698 proc = startProcessLocked(cpi.processName, 7699 cpr.appInfo, false, 0, "content provider", 7700 new ComponentName(cpi.applicationInfo.packageName, 7701 cpi.name), false, false, false); 7702 if (proc == null) { 7703 Slog.w(TAG, "Unable to launch app " 7704 + cpi.applicationInfo.packageName + "/" 7705 + cpi.applicationInfo.uid + " for provider " 7706 + name + ": process is bad"); 7707 return null; 7708 } 7709 } 7710 cpr.launchingApp = proc; 7711 mLaunchingProviders.add(cpr); 7712 } finally { 7713 Binder.restoreCallingIdentity(origId); 7714 } 7715 } 7716 7717 // Make sure the provider is published (the same provider class 7718 // may be published under multiple names). 7719 if (firstClass) { 7720 mProviderMap.putProviderByClass(comp, cpr); 7721 } 7722 7723 mProviderMap.putProviderByName(name, cpr); 7724 conn = incProviderCountLocked(r, cpr, token, stable); 7725 if (conn != null) { 7726 conn.waiting = true; 7727 } 7728 } 7729 } 7730 7731 // Wait for the provider to be published... 7732 synchronized (cpr) { 7733 while (cpr.provider == null) { 7734 if (cpr.launchingApp == null) { 7735 Slog.w(TAG, "Unable to launch app " 7736 + cpi.applicationInfo.packageName + "/" 7737 + cpi.applicationInfo.uid + " for provider " 7738 + name + ": launching app became null"); 7739 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7740 UserHandle.getUserId(cpi.applicationInfo.uid), 7741 cpi.applicationInfo.packageName, 7742 cpi.applicationInfo.uid, name); 7743 return null; 7744 } 7745 try { 7746 if (DEBUG_MU) { 7747 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7748 + cpr.launchingApp); 7749 } 7750 if (conn != null) { 7751 conn.waiting = true; 7752 } 7753 cpr.wait(); 7754 } catch (InterruptedException ex) { 7755 } finally { 7756 if (conn != null) { 7757 conn.waiting = false; 7758 } 7759 } 7760 } 7761 } 7762 return cpr != null ? cpr.newHolder(conn) : null; 7763 } 7764 7765 public final ContentProviderHolder getContentProvider( 7766 IApplicationThread caller, String name, int userId, boolean stable) { 7767 enforceNotIsolatedCaller("getContentProvider"); 7768 if (caller == null) { 7769 String msg = "null IApplicationThread when getting content provider " 7770 + name; 7771 Slog.w(TAG, msg); 7772 throw new SecurityException(msg); 7773 } 7774 7775 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7776 false, true, "getContentProvider", null); 7777 return getContentProviderImpl(caller, name, null, stable, userId); 7778 } 7779 7780 public ContentProviderHolder getContentProviderExternal( 7781 String name, int userId, IBinder token) { 7782 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7783 "Do not have permission in call getContentProviderExternal()"); 7784 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7785 false, true, "getContentProvider", null); 7786 return getContentProviderExternalUnchecked(name, token, userId); 7787 } 7788 7789 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7790 IBinder token, int userId) { 7791 return getContentProviderImpl(null, name, token, true, userId); 7792 } 7793 7794 /** 7795 * Drop a content provider from a ProcessRecord's bookkeeping 7796 */ 7797 public void removeContentProvider(IBinder connection, boolean stable) { 7798 enforceNotIsolatedCaller("removeContentProvider"); 7799 long ident = Binder.clearCallingIdentity(); 7800 try { 7801 synchronized (this) { 7802 ContentProviderConnection conn; 7803 try { 7804 conn = (ContentProviderConnection)connection; 7805 } catch (ClassCastException e) { 7806 String msg ="removeContentProvider: " + connection 7807 + " not a ContentProviderConnection"; 7808 Slog.w(TAG, msg); 7809 throw new IllegalArgumentException(msg); 7810 } 7811 if (conn == null) { 7812 throw new NullPointerException("connection is null"); 7813 } 7814 if (decProviderCountLocked(conn, null, null, stable)) { 7815 updateOomAdjLocked(); 7816 } 7817 } 7818 } finally { 7819 Binder.restoreCallingIdentity(ident); 7820 } 7821 } 7822 7823 public void removeContentProviderExternal(String name, IBinder token) { 7824 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7825 "Do not have permission in call removeContentProviderExternal()"); 7826 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7827 } 7828 7829 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7830 synchronized (this) { 7831 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7832 if(cpr == null) { 7833 //remove from mProvidersByClass 7834 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7835 return; 7836 } 7837 7838 //update content provider record entry info 7839 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7840 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7841 if (localCpr.hasExternalProcessHandles()) { 7842 if (localCpr.removeExternalProcessHandleLocked(token)) { 7843 updateOomAdjLocked(); 7844 } else { 7845 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7846 + " with no external reference for token: " 7847 + token + "."); 7848 } 7849 } else { 7850 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7851 + " with no external references."); 7852 } 7853 } 7854 } 7855 7856 public final void publishContentProviders(IApplicationThread caller, 7857 List<ContentProviderHolder> providers) { 7858 if (providers == null) { 7859 return; 7860 } 7861 7862 enforceNotIsolatedCaller("publishContentProviders"); 7863 synchronized (this) { 7864 final ProcessRecord r = getRecordForAppLocked(caller); 7865 if (DEBUG_MU) 7866 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 7867 if (r == null) { 7868 throw new SecurityException( 7869 "Unable to find app for caller " + caller 7870 + " (pid=" + Binder.getCallingPid() 7871 + ") when publishing content providers"); 7872 } 7873 7874 final long origId = Binder.clearCallingIdentity(); 7875 7876 final int N = providers.size(); 7877 for (int i=0; i<N; i++) { 7878 ContentProviderHolder src = providers.get(i); 7879 if (src == null || src.info == null || src.provider == null) { 7880 continue; 7881 } 7882 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 7883 if (DEBUG_MU) 7884 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 7885 if (dst != null) { 7886 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 7887 mProviderMap.putProviderByClass(comp, dst); 7888 String names[] = dst.info.authority.split(";"); 7889 for (int j = 0; j < names.length; j++) { 7890 mProviderMap.putProviderByName(names[j], dst); 7891 } 7892 7893 int NL = mLaunchingProviders.size(); 7894 int j; 7895 for (j=0; j<NL; j++) { 7896 if (mLaunchingProviders.get(j) == dst) { 7897 mLaunchingProviders.remove(j); 7898 j--; 7899 NL--; 7900 } 7901 } 7902 synchronized (dst) { 7903 dst.provider = src.provider; 7904 dst.proc = r; 7905 dst.notifyAll(); 7906 } 7907 updateOomAdjLocked(r); 7908 } 7909 } 7910 7911 Binder.restoreCallingIdentity(origId); 7912 } 7913 } 7914 7915 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 7916 ContentProviderConnection conn; 7917 try { 7918 conn = (ContentProviderConnection)connection; 7919 } catch (ClassCastException e) { 7920 String msg ="refContentProvider: " + connection 7921 + " not a ContentProviderConnection"; 7922 Slog.w(TAG, msg); 7923 throw new IllegalArgumentException(msg); 7924 } 7925 if (conn == null) { 7926 throw new NullPointerException("connection is null"); 7927 } 7928 7929 synchronized (this) { 7930 if (stable > 0) { 7931 conn.numStableIncs += stable; 7932 } 7933 stable = conn.stableCount + stable; 7934 if (stable < 0) { 7935 throw new IllegalStateException("stableCount < 0: " + stable); 7936 } 7937 7938 if (unstable > 0) { 7939 conn.numUnstableIncs += unstable; 7940 } 7941 unstable = conn.unstableCount + unstable; 7942 if (unstable < 0) { 7943 throw new IllegalStateException("unstableCount < 0: " + unstable); 7944 } 7945 7946 if ((stable+unstable) <= 0) { 7947 throw new IllegalStateException("ref counts can't go to zero here: stable=" 7948 + stable + " unstable=" + unstable); 7949 } 7950 conn.stableCount = stable; 7951 conn.unstableCount = unstable; 7952 return !conn.dead; 7953 } 7954 } 7955 7956 public void unstableProviderDied(IBinder connection) { 7957 ContentProviderConnection conn; 7958 try { 7959 conn = (ContentProviderConnection)connection; 7960 } catch (ClassCastException e) { 7961 String msg ="refContentProvider: " + connection 7962 + " not a ContentProviderConnection"; 7963 Slog.w(TAG, msg); 7964 throw new IllegalArgumentException(msg); 7965 } 7966 if (conn == null) { 7967 throw new NullPointerException("connection is null"); 7968 } 7969 7970 // Safely retrieve the content provider associated with the connection. 7971 IContentProvider provider; 7972 synchronized (this) { 7973 provider = conn.provider.provider; 7974 } 7975 7976 if (provider == null) { 7977 // Um, yeah, we're way ahead of you. 7978 return; 7979 } 7980 7981 // Make sure the caller is being honest with us. 7982 if (provider.asBinder().pingBinder()) { 7983 // Er, no, still looks good to us. 7984 synchronized (this) { 7985 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 7986 + " says " + conn + " died, but we don't agree"); 7987 return; 7988 } 7989 } 7990 7991 // Well look at that! It's dead! 7992 synchronized (this) { 7993 if (conn.provider.provider != provider) { 7994 // But something changed... good enough. 7995 return; 7996 } 7997 7998 ProcessRecord proc = conn.provider.proc; 7999 if (proc == null || proc.thread == null) { 8000 // Seems like the process is already cleaned up. 8001 return; 8002 } 8003 8004 // As far as we're concerned, this is just like receiving a 8005 // death notification... just a bit prematurely. 8006 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8007 + ") early provider death"); 8008 final long ident = Binder.clearCallingIdentity(); 8009 try { 8010 appDiedLocked(proc, proc.pid, proc.thread); 8011 } finally { 8012 Binder.restoreCallingIdentity(ident); 8013 } 8014 } 8015 } 8016 8017 @Override 8018 public void appNotRespondingViaProvider(IBinder connection) { 8019 enforceCallingPermission( 8020 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8021 8022 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8023 if (conn == null) { 8024 Slog.w(TAG, "ContentProviderConnection is null"); 8025 return; 8026 } 8027 8028 final ProcessRecord host = conn.provider.proc; 8029 if (host == null) { 8030 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8031 return; 8032 } 8033 8034 final long token = Binder.clearCallingIdentity(); 8035 try { 8036 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8037 } finally { 8038 Binder.restoreCallingIdentity(token); 8039 } 8040 } 8041 8042 public final void installSystemProviders() { 8043 List<ProviderInfo> providers; 8044 synchronized (this) { 8045 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8046 providers = generateApplicationProvidersLocked(app); 8047 if (providers != null) { 8048 for (int i=providers.size()-1; i>=0; i--) { 8049 ProviderInfo pi = (ProviderInfo)providers.get(i); 8050 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8051 Slog.w(TAG, "Not installing system proc provider " + pi.name 8052 + ": not system .apk"); 8053 providers.remove(i); 8054 } 8055 } 8056 } 8057 } 8058 if (providers != null) { 8059 mSystemThread.installSystemProviders(providers); 8060 } 8061 8062 mCoreSettingsObserver = new CoreSettingsObserver(this); 8063 8064 mUsageStatsService.monitorPackages(); 8065 } 8066 8067 /** 8068 * Allows app to retrieve the MIME type of a URI without having permission 8069 * to access its content provider. 8070 * 8071 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8072 * 8073 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8074 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8075 */ 8076 public String getProviderMimeType(Uri uri, int userId) { 8077 enforceNotIsolatedCaller("getProviderMimeType"); 8078 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8079 userId, false, true, "getProviderMimeType", null); 8080 final String name = uri.getAuthority(); 8081 final long ident = Binder.clearCallingIdentity(); 8082 ContentProviderHolder holder = null; 8083 8084 try { 8085 holder = getContentProviderExternalUnchecked(name, null, userId); 8086 if (holder != null) { 8087 return holder.provider.getType(uri); 8088 } 8089 } catch (RemoteException e) { 8090 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8091 return null; 8092 } finally { 8093 if (holder != null) { 8094 removeContentProviderExternalUnchecked(name, null, userId); 8095 } 8096 Binder.restoreCallingIdentity(ident); 8097 } 8098 8099 return null; 8100 } 8101 8102 // ========================================================= 8103 // GLOBAL MANAGEMENT 8104 // ========================================================= 8105 8106 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8107 boolean isolated) { 8108 String proc = customProcess != null ? customProcess : info.processName; 8109 BatteryStatsImpl.Uid.Proc ps = null; 8110 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8111 int uid = info.uid; 8112 if (isolated) { 8113 int userId = UserHandle.getUserId(uid); 8114 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8115 while (true) { 8116 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8117 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8118 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8119 } 8120 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8121 mNextIsolatedProcessUid++; 8122 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8123 // No process for this uid, use it. 8124 break; 8125 } 8126 stepsLeft--; 8127 if (stepsLeft <= 0) { 8128 return null; 8129 } 8130 } 8131 } 8132 return new ProcessRecord(stats, info, proc, uid); 8133 } 8134 8135 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8136 ProcessRecord app; 8137 if (!isolated) { 8138 app = getProcessRecordLocked(info.processName, info.uid, true); 8139 } else { 8140 app = null; 8141 } 8142 8143 if (app == null) { 8144 app = newProcessRecordLocked(info, null, isolated); 8145 mProcessNames.put(info.processName, app.uid, app); 8146 if (isolated) { 8147 mIsolatedProcesses.put(app.uid, app); 8148 } 8149 updateLruProcessLocked(app, false, null); 8150 updateOomAdjLocked(); 8151 } 8152 8153 // This package really, really can not be stopped. 8154 try { 8155 AppGlobals.getPackageManager().setPackageStoppedState( 8156 info.packageName, false, UserHandle.getUserId(app.uid)); 8157 } catch (RemoteException e) { 8158 } catch (IllegalArgumentException e) { 8159 Slog.w(TAG, "Failed trying to unstop package " 8160 + info.packageName + ": " + e); 8161 } 8162 8163 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8164 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8165 app.persistent = true; 8166 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8167 } 8168 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8169 mPersistentStartingProcesses.add(app); 8170 startProcessLocked(app, "added application", app.processName); 8171 } 8172 8173 return app; 8174 } 8175 8176 public void unhandledBack() { 8177 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8178 "unhandledBack()"); 8179 8180 synchronized(this) { 8181 final long origId = Binder.clearCallingIdentity(); 8182 try { 8183 getFocusedStack().unhandledBackLocked(); 8184 } finally { 8185 Binder.restoreCallingIdentity(origId); 8186 } 8187 } 8188 } 8189 8190 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8191 enforceNotIsolatedCaller("openContentUri"); 8192 final int userId = UserHandle.getCallingUserId(); 8193 String name = uri.getAuthority(); 8194 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8195 ParcelFileDescriptor pfd = null; 8196 if (cph != null) { 8197 // We record the binder invoker's uid in thread-local storage before 8198 // going to the content provider to open the file. Later, in the code 8199 // that handles all permissions checks, we look for this uid and use 8200 // that rather than the Activity Manager's own uid. The effect is that 8201 // we do the check against the caller's permissions even though it looks 8202 // to the content provider like the Activity Manager itself is making 8203 // the request. 8204 sCallerIdentity.set(new Identity( 8205 Binder.getCallingPid(), Binder.getCallingUid())); 8206 try { 8207 pfd = cph.provider.openFile(null, uri, "r", null); 8208 } catch (FileNotFoundException e) { 8209 // do nothing; pfd will be returned null 8210 } finally { 8211 // Ensure that whatever happens, we clean up the identity state 8212 sCallerIdentity.remove(); 8213 } 8214 8215 // We've got the fd now, so we're done with the provider. 8216 removeContentProviderExternalUnchecked(name, null, userId); 8217 } else { 8218 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8219 } 8220 return pfd; 8221 } 8222 8223 // Actually is sleeping or shutting down or whatever else in the future 8224 // is an inactive state. 8225 public boolean isSleepingOrShuttingDown() { 8226 return mSleeping || mShuttingDown; 8227 } 8228 8229 public void goingToSleep() { 8230 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8231 != PackageManager.PERMISSION_GRANTED) { 8232 throw new SecurityException("Requires permission " 8233 + android.Manifest.permission.DEVICE_POWER); 8234 } 8235 8236 synchronized(this) { 8237 mWentToSleep = true; 8238 updateEventDispatchingLocked(); 8239 8240 if (!mSleeping) { 8241 mSleeping = true; 8242 mStackSupervisor.goingToSleepLocked(); 8243 8244 // Initialize the wake times of all processes. 8245 checkExcessivePowerUsageLocked(false); 8246 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8247 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8248 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8249 } 8250 } 8251 } 8252 8253 @Override 8254 public boolean shutdown(int timeout) { 8255 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8256 != PackageManager.PERMISSION_GRANTED) { 8257 throw new SecurityException("Requires permission " 8258 + android.Manifest.permission.SHUTDOWN); 8259 } 8260 8261 boolean timedout = false; 8262 8263 synchronized(this) { 8264 mShuttingDown = true; 8265 updateEventDispatchingLocked(); 8266 timedout = mStackSupervisor.shutdownLocked(timeout); 8267 } 8268 8269 mAppOpsService.shutdown(); 8270 mUsageStatsService.shutdown(); 8271 mBatteryStatsService.shutdown(); 8272 synchronized (this) { 8273 mProcessStats.shutdownLocked(); 8274 } 8275 8276 return timedout; 8277 } 8278 8279 public final void activitySlept(IBinder token) { 8280 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8281 8282 final long origId = Binder.clearCallingIdentity(); 8283 8284 synchronized (this) { 8285 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8286 if (r != null) { 8287 mStackSupervisor.activitySleptLocked(r); 8288 } 8289 } 8290 8291 Binder.restoreCallingIdentity(origId); 8292 } 8293 8294 void logLockScreen(String msg) { 8295 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8296 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8297 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8298 mStackSupervisor.mDismissKeyguardOnNextActivity); 8299 } 8300 8301 private void comeOutOfSleepIfNeededLocked() { 8302 if (!mWentToSleep && !mLockScreenShown) { 8303 if (mSleeping) { 8304 mSleeping = false; 8305 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8306 } 8307 } 8308 } 8309 8310 public void wakingUp() { 8311 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8312 != PackageManager.PERMISSION_GRANTED) { 8313 throw new SecurityException("Requires permission " 8314 + android.Manifest.permission.DEVICE_POWER); 8315 } 8316 8317 synchronized(this) { 8318 mWentToSleep = false; 8319 updateEventDispatchingLocked(); 8320 comeOutOfSleepIfNeededLocked(); 8321 } 8322 } 8323 8324 private void updateEventDispatchingLocked() { 8325 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8326 } 8327 8328 public void setLockScreenShown(boolean shown) { 8329 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8330 != PackageManager.PERMISSION_GRANTED) { 8331 throw new SecurityException("Requires permission " 8332 + android.Manifest.permission.DEVICE_POWER); 8333 } 8334 8335 synchronized(this) { 8336 long ident = Binder.clearCallingIdentity(); 8337 try { 8338 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8339 mLockScreenShown = shown; 8340 comeOutOfSleepIfNeededLocked(); 8341 } finally { 8342 Binder.restoreCallingIdentity(ident); 8343 } 8344 } 8345 } 8346 8347 public void stopAppSwitches() { 8348 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8349 != PackageManager.PERMISSION_GRANTED) { 8350 throw new SecurityException("Requires permission " 8351 + android.Manifest.permission.STOP_APP_SWITCHES); 8352 } 8353 8354 synchronized(this) { 8355 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8356 + APP_SWITCH_DELAY_TIME; 8357 mDidAppSwitch = false; 8358 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8359 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8360 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8361 } 8362 } 8363 8364 public void resumeAppSwitches() { 8365 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8366 != PackageManager.PERMISSION_GRANTED) { 8367 throw new SecurityException("Requires permission " 8368 + android.Manifest.permission.STOP_APP_SWITCHES); 8369 } 8370 8371 synchronized(this) { 8372 // Note that we don't execute any pending app switches... we will 8373 // let those wait until either the timeout, or the next start 8374 // activity request. 8375 mAppSwitchesAllowedTime = 0; 8376 } 8377 } 8378 8379 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8380 String name) { 8381 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8382 return true; 8383 } 8384 8385 final int perm = checkComponentPermission( 8386 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8387 callingUid, -1, true); 8388 if (perm == PackageManager.PERMISSION_GRANTED) { 8389 return true; 8390 } 8391 8392 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8393 return false; 8394 } 8395 8396 public void setDebugApp(String packageName, boolean waitForDebugger, 8397 boolean persistent) { 8398 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8399 "setDebugApp()"); 8400 8401 long ident = Binder.clearCallingIdentity(); 8402 try { 8403 // Note that this is not really thread safe if there are multiple 8404 // callers into it at the same time, but that's not a situation we 8405 // care about. 8406 if (persistent) { 8407 final ContentResolver resolver = mContext.getContentResolver(); 8408 Settings.Global.putString( 8409 resolver, Settings.Global.DEBUG_APP, 8410 packageName); 8411 Settings.Global.putInt( 8412 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8413 waitForDebugger ? 1 : 0); 8414 } 8415 8416 synchronized (this) { 8417 if (!persistent) { 8418 mOrigDebugApp = mDebugApp; 8419 mOrigWaitForDebugger = mWaitForDebugger; 8420 } 8421 mDebugApp = packageName; 8422 mWaitForDebugger = waitForDebugger; 8423 mDebugTransient = !persistent; 8424 if (packageName != null) { 8425 forceStopPackageLocked(packageName, -1, false, false, true, true, 8426 false, UserHandle.USER_ALL, "set debug app"); 8427 } 8428 } 8429 } finally { 8430 Binder.restoreCallingIdentity(ident); 8431 } 8432 } 8433 8434 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8435 synchronized (this) { 8436 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8437 if (!isDebuggable) { 8438 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8439 throw new SecurityException("Process not debuggable: " + app.packageName); 8440 } 8441 } 8442 8443 mOpenGlTraceApp = processName; 8444 } 8445 } 8446 8447 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8448 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8449 synchronized (this) { 8450 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8451 if (!isDebuggable) { 8452 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8453 throw new SecurityException("Process not debuggable: " + app.packageName); 8454 } 8455 } 8456 mProfileApp = processName; 8457 mProfileFile = profileFile; 8458 if (mProfileFd != null) { 8459 try { 8460 mProfileFd.close(); 8461 } catch (IOException e) { 8462 } 8463 mProfileFd = null; 8464 } 8465 mProfileFd = profileFd; 8466 mProfileType = 0; 8467 mAutoStopProfiler = autoStopProfiler; 8468 } 8469 } 8470 8471 @Override 8472 public void setAlwaysFinish(boolean enabled) { 8473 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8474 "setAlwaysFinish()"); 8475 8476 Settings.Global.putInt( 8477 mContext.getContentResolver(), 8478 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8479 8480 synchronized (this) { 8481 mAlwaysFinishActivities = enabled; 8482 } 8483 } 8484 8485 @Override 8486 public void setActivityController(IActivityController controller) { 8487 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8488 "setActivityController()"); 8489 synchronized (this) { 8490 mController = controller; 8491 Watchdog.getInstance().setActivityController(controller); 8492 } 8493 } 8494 8495 @Override 8496 public void setUserIsMonkey(boolean userIsMonkey) { 8497 synchronized (this) { 8498 synchronized (mPidsSelfLocked) { 8499 final int callingPid = Binder.getCallingPid(); 8500 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8501 if (precessRecord == null) { 8502 throw new SecurityException("Unknown process: " + callingPid); 8503 } 8504 if (precessRecord.instrumentationUiAutomationConnection == null) { 8505 throw new SecurityException("Only an instrumentation process " 8506 + "with a UiAutomation can call setUserIsMonkey"); 8507 } 8508 } 8509 mUserIsMonkey = userIsMonkey; 8510 } 8511 } 8512 8513 @Override 8514 public boolean isUserAMonkey() { 8515 synchronized (this) { 8516 // If there is a controller also implies the user is a monkey. 8517 return (mUserIsMonkey || mController != null); 8518 } 8519 } 8520 8521 public void requestBugReport() { 8522 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8523 SystemProperties.set("ctl.start", "bugreport"); 8524 } 8525 8526 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8527 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8528 } 8529 8530 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8531 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8532 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8533 } 8534 return KEY_DISPATCHING_TIMEOUT; 8535 } 8536 8537 @Override 8538 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8539 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8540 != PackageManager.PERMISSION_GRANTED) { 8541 throw new SecurityException("Requires permission " 8542 + android.Manifest.permission.FILTER_EVENTS); 8543 } 8544 ProcessRecord proc; 8545 long timeout; 8546 synchronized (this) { 8547 synchronized (mPidsSelfLocked) { 8548 proc = mPidsSelfLocked.get(pid); 8549 } 8550 timeout = getInputDispatchingTimeoutLocked(proc); 8551 } 8552 8553 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8554 return -1; 8555 } 8556 8557 return timeout; 8558 } 8559 8560 /** 8561 * Handle input dispatching timeouts. 8562 * Returns whether input dispatching should be aborted or not. 8563 */ 8564 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8565 final ActivityRecord activity, final ActivityRecord parent, 8566 final boolean aboveSystem, String reason) { 8567 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8568 != PackageManager.PERMISSION_GRANTED) { 8569 throw new SecurityException("Requires permission " 8570 + android.Manifest.permission.FILTER_EVENTS); 8571 } 8572 8573 final String annotation; 8574 if (reason == null) { 8575 annotation = "Input dispatching timed out"; 8576 } else { 8577 annotation = "Input dispatching timed out (" + reason + ")"; 8578 } 8579 8580 if (proc != null) { 8581 synchronized (this) { 8582 if (proc.debugging) { 8583 return false; 8584 } 8585 8586 if (mDidDexOpt) { 8587 // Give more time since we were dexopting. 8588 mDidDexOpt = false; 8589 return false; 8590 } 8591 8592 if (proc.instrumentationClass != null) { 8593 Bundle info = new Bundle(); 8594 info.putString("shortMsg", "keyDispatchingTimedOut"); 8595 info.putString("longMsg", annotation); 8596 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8597 return true; 8598 } 8599 } 8600 mHandler.post(new Runnable() { 8601 @Override 8602 public void run() { 8603 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8604 } 8605 }); 8606 } 8607 8608 return true; 8609 } 8610 8611 public Bundle getAssistContextExtras(int requestType) { 8612 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8613 "getAssistContextExtras()"); 8614 PendingAssistExtras pae; 8615 Bundle extras = new Bundle(); 8616 synchronized (this) { 8617 ActivityRecord activity = getFocusedStack().mResumedActivity; 8618 if (activity == null) { 8619 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8620 return null; 8621 } 8622 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8623 if (activity.app == null || activity.app.thread == null) { 8624 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8625 return extras; 8626 } 8627 if (activity.app.pid == Binder.getCallingPid()) { 8628 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8629 return extras; 8630 } 8631 pae = new PendingAssistExtras(activity); 8632 try { 8633 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8634 requestType); 8635 mPendingAssistExtras.add(pae); 8636 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8637 } catch (RemoteException e) { 8638 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8639 return extras; 8640 } 8641 } 8642 synchronized (pae) { 8643 while (!pae.haveResult) { 8644 try { 8645 pae.wait(); 8646 } catch (InterruptedException e) { 8647 } 8648 } 8649 if (pae.result != null) { 8650 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8651 } 8652 } 8653 synchronized (this) { 8654 mPendingAssistExtras.remove(pae); 8655 mHandler.removeCallbacks(pae); 8656 } 8657 return extras; 8658 } 8659 8660 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8661 PendingAssistExtras pae = (PendingAssistExtras)token; 8662 synchronized (pae) { 8663 pae.result = extras; 8664 pae.haveResult = true; 8665 pae.notifyAll(); 8666 } 8667 } 8668 8669 public void registerProcessObserver(IProcessObserver observer) { 8670 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8671 "registerProcessObserver()"); 8672 synchronized (this) { 8673 mProcessObservers.register(observer); 8674 } 8675 } 8676 8677 @Override 8678 public void unregisterProcessObserver(IProcessObserver observer) { 8679 synchronized (this) { 8680 mProcessObservers.unregister(observer); 8681 } 8682 } 8683 8684 @Override 8685 public boolean convertFromTranslucent(IBinder token) { 8686 final long origId = Binder.clearCallingIdentity(); 8687 try { 8688 synchronized (this) { 8689 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8690 if (r == null) { 8691 return false; 8692 } 8693 if (r.changeWindowTranslucency(true)) { 8694 mWindowManager.setAppFullscreen(token, true); 8695 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8696 return true; 8697 } 8698 return false; 8699 } 8700 } finally { 8701 Binder.restoreCallingIdentity(origId); 8702 } 8703 } 8704 8705 @Override 8706 public boolean convertToTranslucent(IBinder token) { 8707 final long origId = Binder.clearCallingIdentity(); 8708 try { 8709 synchronized (this) { 8710 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8711 if (r == null) { 8712 return false; 8713 } 8714 if (r.changeWindowTranslucency(false)) { 8715 r.task.stack.convertToTranslucent(r); 8716 mWindowManager.setAppFullscreen(token, false); 8717 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8718 return true; 8719 } 8720 return false; 8721 } 8722 } finally { 8723 Binder.restoreCallingIdentity(origId); 8724 } 8725 } 8726 8727 @Override 8728 public void setImmersive(IBinder token, boolean immersive) { 8729 synchronized(this) { 8730 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8731 if (r == null) { 8732 throw new IllegalArgumentException(); 8733 } 8734 r.immersive = immersive; 8735 8736 // update associated state if we're frontmost 8737 if (r == mFocusedActivity) { 8738 if (DEBUG_IMMERSIVE) { 8739 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8740 } 8741 applyUpdateLockStateLocked(r); 8742 } 8743 } 8744 } 8745 8746 @Override 8747 public boolean isImmersive(IBinder token) { 8748 synchronized (this) { 8749 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8750 if (r == null) { 8751 throw new IllegalArgumentException(); 8752 } 8753 return r.immersive; 8754 } 8755 } 8756 8757 public boolean isTopActivityImmersive() { 8758 enforceNotIsolatedCaller("startActivity"); 8759 synchronized (this) { 8760 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8761 return (r != null) ? r.immersive : false; 8762 } 8763 } 8764 8765 public final void enterSafeMode() { 8766 synchronized(this) { 8767 // It only makes sense to do this before the system is ready 8768 // and started launching other packages. 8769 if (!mSystemReady) { 8770 try { 8771 AppGlobals.getPackageManager().enterSafeMode(); 8772 } catch (RemoteException e) { 8773 } 8774 } 8775 } 8776 } 8777 8778 public final void showSafeModeOverlay() { 8779 View v = LayoutInflater.from(mContext).inflate( 8780 com.android.internal.R.layout.safe_mode, null); 8781 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8782 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8783 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8784 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8785 lp.gravity = Gravity.BOTTOM | Gravity.START; 8786 lp.format = v.getBackground().getOpacity(); 8787 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8788 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8789 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8790 ((WindowManager)mContext.getSystemService( 8791 Context.WINDOW_SERVICE)).addView(v, lp); 8792 } 8793 8794 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 8795 if (!(sender instanceof PendingIntentRecord)) { 8796 return; 8797 } 8798 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8799 synchronized (stats) { 8800 if (mBatteryStatsService.isOnBattery()) { 8801 mBatteryStatsService.enforceCallingPermission(); 8802 PendingIntentRecord rec = (PendingIntentRecord)sender; 8803 int MY_UID = Binder.getCallingUid(); 8804 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8805 BatteryStatsImpl.Uid.Pkg pkg = 8806 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 8807 sourcePkg != null ? sourcePkg : rec.key.packageName); 8808 pkg.incWakeupsLocked(); 8809 } 8810 } 8811 } 8812 8813 public boolean killPids(int[] pids, String pReason, boolean secure) { 8814 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8815 throw new SecurityException("killPids only available to the system"); 8816 } 8817 String reason = (pReason == null) ? "Unknown" : pReason; 8818 // XXX Note: don't acquire main activity lock here, because the window 8819 // manager calls in with its locks held. 8820 8821 boolean killed = false; 8822 synchronized (mPidsSelfLocked) { 8823 int[] types = new int[pids.length]; 8824 int worstType = 0; 8825 for (int i=0; i<pids.length; i++) { 8826 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8827 if (proc != null) { 8828 int type = proc.setAdj; 8829 types[i] = type; 8830 if (type > worstType) { 8831 worstType = type; 8832 } 8833 } 8834 } 8835 8836 // If the worst oom_adj is somewhere in the cached proc LRU range, 8837 // then constrain it so we will kill all cached procs. 8838 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8839 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8840 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8841 } 8842 8843 // If this is not a secure call, don't let it kill processes that 8844 // are important. 8845 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8846 worstType = ProcessList.SERVICE_ADJ; 8847 } 8848 8849 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8850 for (int i=0; i<pids.length; i++) { 8851 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8852 if (proc == null) { 8853 continue; 8854 } 8855 int adj = proc.setAdj; 8856 if (adj >= worstType && !proc.killedByAm) { 8857 killUnneededProcessLocked(proc, reason); 8858 killed = true; 8859 } 8860 } 8861 } 8862 return killed; 8863 } 8864 8865 @Override 8866 public void killUid(int uid, String reason) { 8867 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8868 throw new SecurityException("killUid only available to the system"); 8869 } 8870 synchronized (this) { 8871 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 8872 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 8873 reason != null ? reason : "kill uid"); 8874 } 8875 } 8876 8877 @Override 8878 public boolean killProcessesBelowForeground(String reason) { 8879 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8880 throw new SecurityException("killProcessesBelowForeground() only available to system"); 8881 } 8882 8883 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 8884 } 8885 8886 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 8887 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8888 throw new SecurityException("killProcessesBelowAdj() only available to system"); 8889 } 8890 8891 boolean killed = false; 8892 synchronized (mPidsSelfLocked) { 8893 final int size = mPidsSelfLocked.size(); 8894 for (int i = 0; i < size; i++) { 8895 final int pid = mPidsSelfLocked.keyAt(i); 8896 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8897 if (proc == null) continue; 8898 8899 final int adj = proc.setAdj; 8900 if (adj > belowAdj && !proc.killedByAm) { 8901 killUnneededProcessLocked(proc, reason); 8902 killed = true; 8903 } 8904 } 8905 } 8906 return killed; 8907 } 8908 8909 @Override 8910 public void hang(final IBinder who, boolean allowRestart) { 8911 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8912 != PackageManager.PERMISSION_GRANTED) { 8913 throw new SecurityException("Requires permission " 8914 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8915 } 8916 8917 final IBinder.DeathRecipient death = new DeathRecipient() { 8918 @Override 8919 public void binderDied() { 8920 synchronized (this) { 8921 notifyAll(); 8922 } 8923 } 8924 }; 8925 8926 try { 8927 who.linkToDeath(death, 0); 8928 } catch (RemoteException e) { 8929 Slog.w(TAG, "hang: given caller IBinder is already dead."); 8930 return; 8931 } 8932 8933 synchronized (this) { 8934 Watchdog.getInstance().setAllowRestart(allowRestart); 8935 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 8936 synchronized (death) { 8937 while (who.isBinderAlive()) { 8938 try { 8939 death.wait(); 8940 } catch (InterruptedException e) { 8941 } 8942 } 8943 } 8944 Watchdog.getInstance().setAllowRestart(true); 8945 } 8946 } 8947 8948 @Override 8949 public void restart() { 8950 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8951 != PackageManager.PERMISSION_GRANTED) { 8952 throw new SecurityException("Requires permission " 8953 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8954 } 8955 8956 Log.i(TAG, "Sending shutdown broadcast..."); 8957 8958 BroadcastReceiver br = new BroadcastReceiver() { 8959 @Override public void onReceive(Context context, Intent intent) { 8960 // Now the broadcast is done, finish up the low-level shutdown. 8961 Log.i(TAG, "Shutting down activity manager..."); 8962 shutdown(10000); 8963 Log.i(TAG, "Shutdown complete, restarting!"); 8964 Process.killProcess(Process.myPid()); 8965 System.exit(10); 8966 } 8967 }; 8968 8969 // First send the high-level shut down broadcast. 8970 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 8971 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 8972 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 8973 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 8974 mContext.sendOrderedBroadcastAsUser(intent, 8975 UserHandle.ALL, null, br, mHandler, 0, null, null); 8976 */ 8977 br.onReceive(mContext, intent); 8978 } 8979 8980 private long getLowRamTimeSinceIdle(long now) { 8981 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 8982 } 8983 8984 @Override 8985 public void performIdleMaintenance() { 8986 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8987 != PackageManager.PERMISSION_GRANTED) { 8988 throw new SecurityException("Requires permission " 8989 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8990 } 8991 8992 synchronized (this) { 8993 final long now = SystemClock.uptimeMillis(); 8994 final long timeSinceLastIdle = now - mLastIdleTime; 8995 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 8996 mLastIdleTime = now; 8997 mLowRamTimeSinceLastIdle = 0; 8998 if (mLowRamStartTime != 0) { 8999 mLowRamStartTime = now; 9000 } 9001 9002 StringBuilder sb = new StringBuilder(128); 9003 sb.append("Idle maintenance over "); 9004 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9005 sb.append(" low RAM for "); 9006 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9007 Slog.i(TAG, sb.toString()); 9008 9009 // If at least 1/3 of our time since the last idle period has been spent 9010 // with RAM low, then we want to kill processes. 9011 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9012 9013 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9014 ProcessRecord proc = mLruProcesses.get(i); 9015 if (proc.notCachedSinceIdle) { 9016 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9017 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9018 if (doKilling && proc.initialIdlePss != 0 9019 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9020 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9021 + " from " + proc.initialIdlePss + ")"); 9022 } 9023 } 9024 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9025 proc.notCachedSinceIdle = true; 9026 proc.initialIdlePss = 0; 9027 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9028 mSleeping, now); 9029 } 9030 } 9031 9032 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9033 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9034 } 9035 } 9036 9037 public final void startRunning(String pkg, String cls, String action, 9038 String data) { 9039 synchronized(this) { 9040 if (mStartRunning) { 9041 return; 9042 } 9043 mStartRunning = true; 9044 mTopComponent = pkg != null && cls != null 9045 ? new ComponentName(pkg, cls) : null; 9046 mTopAction = action != null ? action : Intent.ACTION_MAIN; 9047 mTopData = data; 9048 if (!mSystemReady) { 9049 return; 9050 } 9051 } 9052 9053 systemReady(null); 9054 } 9055 9056 private void retrieveSettings() { 9057 final ContentResolver resolver = mContext.getContentResolver(); 9058 String debugApp = Settings.Global.getString( 9059 resolver, Settings.Global.DEBUG_APP); 9060 boolean waitForDebugger = Settings.Global.getInt( 9061 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9062 boolean alwaysFinishActivities = Settings.Global.getInt( 9063 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9064 boolean forceRtl = Settings.Global.getInt( 9065 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9066 // Transfer any global setting for forcing RTL layout, into a System Property 9067 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9068 9069 Configuration configuration = new Configuration(); 9070 Settings.System.getConfiguration(resolver, configuration); 9071 if (forceRtl) { 9072 // This will take care of setting the correct layout direction flags 9073 configuration.setLayoutDirection(configuration.locale); 9074 } 9075 9076 synchronized (this) { 9077 mDebugApp = mOrigDebugApp = debugApp; 9078 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9079 mAlwaysFinishActivities = alwaysFinishActivities; 9080 // This happens before any activities are started, so we can 9081 // change mConfiguration in-place. 9082 updateConfigurationLocked(configuration, null, false, true); 9083 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9084 } 9085 } 9086 9087 public boolean testIsSystemReady() { 9088 // no need to synchronize(this) just to read & return the value 9089 return mSystemReady; 9090 } 9091 9092 private static File getCalledPreBootReceiversFile() { 9093 File dataDir = Environment.getDataDirectory(); 9094 File systemDir = new File(dataDir, "system"); 9095 File fname = new File(systemDir, "called_pre_boots.dat"); 9096 return fname; 9097 } 9098 9099 static final int LAST_DONE_VERSION = 10000; 9100 9101 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9102 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9103 File file = getCalledPreBootReceiversFile(); 9104 FileInputStream fis = null; 9105 try { 9106 fis = new FileInputStream(file); 9107 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9108 int fvers = dis.readInt(); 9109 if (fvers == LAST_DONE_VERSION) { 9110 String vers = dis.readUTF(); 9111 String codename = dis.readUTF(); 9112 String build = dis.readUTF(); 9113 if (android.os.Build.VERSION.RELEASE.equals(vers) 9114 && android.os.Build.VERSION.CODENAME.equals(codename) 9115 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9116 int num = dis.readInt(); 9117 while (num > 0) { 9118 num--; 9119 String pkg = dis.readUTF(); 9120 String cls = dis.readUTF(); 9121 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9122 } 9123 } 9124 } 9125 } catch (FileNotFoundException e) { 9126 } catch (IOException e) { 9127 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9128 } finally { 9129 if (fis != null) { 9130 try { 9131 fis.close(); 9132 } catch (IOException e) { 9133 } 9134 } 9135 } 9136 return lastDoneReceivers; 9137 } 9138 9139 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9140 File file = getCalledPreBootReceiversFile(); 9141 FileOutputStream fos = null; 9142 DataOutputStream dos = null; 9143 try { 9144 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9145 fos = new FileOutputStream(file); 9146 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9147 dos.writeInt(LAST_DONE_VERSION); 9148 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9149 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9150 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9151 dos.writeInt(list.size()); 9152 for (int i=0; i<list.size(); i++) { 9153 dos.writeUTF(list.get(i).getPackageName()); 9154 dos.writeUTF(list.get(i).getClassName()); 9155 } 9156 } catch (IOException e) { 9157 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9158 file.delete(); 9159 } finally { 9160 FileUtils.sync(fos); 9161 if (dos != null) { 9162 try { 9163 dos.close(); 9164 } catch (IOException e) { 9165 // TODO Auto-generated catch block 9166 e.printStackTrace(); 9167 } 9168 } 9169 } 9170 } 9171 9172 public void systemReady(final Runnable goingCallback) { 9173 synchronized(this) { 9174 if (mSystemReady) { 9175 if (goingCallback != null) goingCallback.run(); 9176 return; 9177 } 9178 9179 // Check to see if there are any update receivers to run. 9180 if (!mDidUpdate) { 9181 if (mWaitingUpdate) { 9182 return; 9183 } 9184 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9185 List<ResolveInfo> ris = null; 9186 try { 9187 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9188 intent, null, 0, 0); 9189 } catch (RemoteException e) { 9190 } 9191 if (ris != null) { 9192 for (int i=ris.size()-1; i>=0; i--) { 9193 if ((ris.get(i).activityInfo.applicationInfo.flags 9194 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9195 ris.remove(i); 9196 } 9197 } 9198 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9199 9200 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9201 9202 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9203 for (int i=0; i<ris.size(); i++) { 9204 ActivityInfo ai = ris.get(i).activityInfo; 9205 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9206 if (lastDoneReceivers.contains(comp)) { 9207 ris.remove(i); 9208 i--; 9209 } 9210 } 9211 9212 final int[] users = getUsersLocked(); 9213 for (int i=0; i<ris.size(); i++) { 9214 ActivityInfo ai = ris.get(i).activityInfo; 9215 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9216 doneReceivers.add(comp); 9217 intent.setComponent(comp); 9218 for (int j=0; j<users.length; j++) { 9219 IIntentReceiver finisher = null; 9220 if (i == ris.size()-1 && j == users.length-1) { 9221 finisher = new IIntentReceiver.Stub() { 9222 public void performReceive(Intent intent, int resultCode, 9223 String data, Bundle extras, boolean ordered, 9224 boolean sticky, int sendingUser) { 9225 // The raw IIntentReceiver interface is called 9226 // with the AM lock held, so redispatch to 9227 // execute our code without the lock. 9228 mHandler.post(new Runnable() { 9229 public void run() { 9230 synchronized (ActivityManagerService.this) { 9231 mDidUpdate = true; 9232 } 9233 writeLastDonePreBootReceivers(doneReceivers); 9234 showBootMessage(mContext.getText( 9235 R.string.android_upgrading_complete), 9236 false); 9237 systemReady(goingCallback); 9238 } 9239 }); 9240 } 9241 }; 9242 } 9243 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9244 + " for user " + users[j]); 9245 broadcastIntentLocked(null, null, intent, null, finisher, 9246 0, null, null, null, AppOpsManager.OP_NONE, 9247 true, false, MY_PID, Process.SYSTEM_UID, 9248 users[j]); 9249 if (finisher != null) { 9250 mWaitingUpdate = true; 9251 } 9252 } 9253 } 9254 } 9255 if (mWaitingUpdate) { 9256 return; 9257 } 9258 mDidUpdate = true; 9259 } 9260 9261 mAppOpsService.systemReady(); 9262 mSystemReady = true; 9263 if (!mStartRunning) { 9264 return; 9265 } 9266 } 9267 9268 ArrayList<ProcessRecord> procsToKill = null; 9269 synchronized(mPidsSelfLocked) { 9270 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9271 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9272 if (!isAllowedWhileBooting(proc.info)){ 9273 if (procsToKill == null) { 9274 procsToKill = new ArrayList<ProcessRecord>(); 9275 } 9276 procsToKill.add(proc); 9277 } 9278 } 9279 } 9280 9281 synchronized(this) { 9282 if (procsToKill != null) { 9283 for (int i=procsToKill.size()-1; i>=0; i--) { 9284 ProcessRecord proc = procsToKill.get(i); 9285 Slog.i(TAG, "Removing system update proc: " + proc); 9286 removeProcessLocked(proc, true, false, "system update done"); 9287 } 9288 } 9289 9290 // Now that we have cleaned up any update processes, we 9291 // are ready to start launching real processes and know that 9292 // we won't trample on them any more. 9293 mProcessesReady = true; 9294 } 9295 9296 Slog.i(TAG, "System now ready"); 9297 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9298 SystemClock.uptimeMillis()); 9299 9300 synchronized(this) { 9301 // Make sure we have no pre-ready processes sitting around. 9302 9303 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9304 ResolveInfo ri = mContext.getPackageManager() 9305 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9306 STOCK_PM_FLAGS); 9307 CharSequence errorMsg = null; 9308 if (ri != null) { 9309 ActivityInfo ai = ri.activityInfo; 9310 ApplicationInfo app = ai.applicationInfo; 9311 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9312 mTopAction = Intent.ACTION_FACTORY_TEST; 9313 mTopData = null; 9314 mTopComponent = new ComponentName(app.packageName, 9315 ai.name); 9316 } else { 9317 errorMsg = mContext.getResources().getText( 9318 com.android.internal.R.string.factorytest_not_system); 9319 } 9320 } else { 9321 errorMsg = mContext.getResources().getText( 9322 com.android.internal.R.string.factorytest_no_action); 9323 } 9324 if (errorMsg != null) { 9325 mTopAction = null; 9326 mTopData = null; 9327 mTopComponent = null; 9328 Message msg = Message.obtain(); 9329 msg.what = SHOW_FACTORY_ERROR_MSG; 9330 msg.getData().putCharSequence("msg", errorMsg); 9331 mHandler.sendMessage(msg); 9332 } 9333 } 9334 } 9335 9336 retrieveSettings(); 9337 9338 synchronized (this) { 9339 readGrantedUriPermissionsLocked(); 9340 } 9341 9342 if (goingCallback != null) goingCallback.run(); 9343 9344 synchronized (this) { 9345 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9346 try { 9347 List apps = AppGlobals.getPackageManager(). 9348 getPersistentApplications(STOCK_PM_FLAGS); 9349 if (apps != null) { 9350 int N = apps.size(); 9351 int i; 9352 for (i=0; i<N; i++) { 9353 ApplicationInfo info 9354 = (ApplicationInfo)apps.get(i); 9355 if (info != null && 9356 !info.packageName.equals("android")) { 9357 addAppLocked(info, false); 9358 } 9359 } 9360 } 9361 } catch (RemoteException ex) { 9362 // pm is in same process, this will never happen. 9363 } 9364 } 9365 9366 // Start up initial activity. 9367 mBooting = true; 9368 9369 try { 9370 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9371 Message msg = Message.obtain(); 9372 msg.what = SHOW_UID_ERROR_MSG; 9373 mHandler.sendMessage(msg); 9374 } 9375 } catch (RemoteException e) { 9376 } 9377 9378 long ident = Binder.clearCallingIdentity(); 9379 try { 9380 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9381 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9382 | Intent.FLAG_RECEIVER_FOREGROUND); 9383 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9384 broadcastIntentLocked(null, null, intent, 9385 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9386 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9387 intent = new Intent(Intent.ACTION_USER_STARTING); 9388 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9389 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9390 broadcastIntentLocked(null, null, intent, 9391 null, new IIntentReceiver.Stub() { 9392 @Override 9393 public void performReceive(Intent intent, int resultCode, String data, 9394 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9395 throws RemoteException { 9396 } 9397 }, 0, null, null, 9398 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9399 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9400 } finally { 9401 Binder.restoreCallingIdentity(ident); 9402 } 9403 mStackSupervisor.resumeTopActivitiesLocked(); 9404 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9405 } 9406 } 9407 9408 private boolean makeAppCrashingLocked(ProcessRecord app, 9409 String shortMsg, String longMsg, String stackTrace) { 9410 app.crashing = true; 9411 app.crashingReport = generateProcessError(app, 9412 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9413 startAppProblemLocked(app); 9414 app.stopFreezingAllLocked(); 9415 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9416 } 9417 9418 private void makeAppNotRespondingLocked(ProcessRecord app, 9419 String activity, String shortMsg, String longMsg) { 9420 app.notResponding = true; 9421 app.notRespondingReport = generateProcessError(app, 9422 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9423 activity, shortMsg, longMsg, null); 9424 startAppProblemLocked(app); 9425 app.stopFreezingAllLocked(); 9426 } 9427 9428 /** 9429 * Generate a process error record, suitable for attachment to a ProcessRecord. 9430 * 9431 * @param app The ProcessRecord in which the error occurred. 9432 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9433 * ActivityManager.AppErrorStateInfo 9434 * @param activity The activity associated with the crash, if known. 9435 * @param shortMsg Short message describing the crash. 9436 * @param longMsg Long message describing the crash. 9437 * @param stackTrace Full crash stack trace, may be null. 9438 * 9439 * @return Returns a fully-formed AppErrorStateInfo record. 9440 */ 9441 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9442 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9443 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9444 9445 report.condition = condition; 9446 report.processName = app.processName; 9447 report.pid = app.pid; 9448 report.uid = app.info.uid; 9449 report.tag = activity; 9450 report.shortMsg = shortMsg; 9451 report.longMsg = longMsg; 9452 report.stackTrace = stackTrace; 9453 9454 return report; 9455 } 9456 9457 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9458 synchronized (this) { 9459 app.crashing = false; 9460 app.crashingReport = null; 9461 app.notResponding = false; 9462 app.notRespondingReport = null; 9463 if (app.anrDialog == fromDialog) { 9464 app.anrDialog = null; 9465 } 9466 if (app.waitDialog == fromDialog) { 9467 app.waitDialog = null; 9468 } 9469 if (app.pid > 0 && app.pid != MY_PID) { 9470 handleAppCrashLocked(app, null, null, null); 9471 killUnneededProcessLocked(app, "user request after error"); 9472 } 9473 } 9474 } 9475 9476 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9477 String stackTrace) { 9478 long now = SystemClock.uptimeMillis(); 9479 9480 Long crashTime; 9481 if (!app.isolated) { 9482 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9483 } else { 9484 crashTime = null; 9485 } 9486 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9487 // This process loses! 9488 Slog.w(TAG, "Process " + app.info.processName 9489 + " has crashed too many times: killing!"); 9490 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9491 app.userId, app.info.processName, app.uid); 9492 mStackSupervisor.handleAppCrashLocked(app); 9493 if (!app.persistent) { 9494 // We don't want to start this process again until the user 9495 // explicitly does so... but for persistent process, we really 9496 // need to keep it running. If a persistent process is actually 9497 // repeatedly crashing, then badness for everyone. 9498 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9499 app.info.processName); 9500 if (!app.isolated) { 9501 // XXX We don't have a way to mark isolated processes 9502 // as bad, since they don't have a peristent identity. 9503 mBadProcesses.put(app.info.processName, app.uid, 9504 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9505 mProcessCrashTimes.remove(app.info.processName, app.uid); 9506 } 9507 app.bad = true; 9508 app.removed = true; 9509 // Don't let services in this process be restarted and potentially 9510 // annoy the user repeatedly. Unless it is persistent, since those 9511 // processes run critical code. 9512 removeProcessLocked(app, false, false, "crash"); 9513 mStackSupervisor.resumeTopActivitiesLocked(); 9514 return false; 9515 } 9516 mStackSupervisor.resumeTopActivitiesLocked(); 9517 } else { 9518 mStackSupervisor.finishTopRunningActivityLocked(app); 9519 } 9520 9521 // Bump up the crash count of any services currently running in the proc. 9522 for (int i=app.services.size()-1; i>=0; i--) { 9523 // Any services running in the application need to be placed 9524 // back in the pending list. 9525 ServiceRecord sr = app.services.valueAt(i); 9526 sr.crashCount++; 9527 } 9528 9529 // If the crashing process is what we consider to be the "home process" and it has been 9530 // replaced by a third-party app, clear the package preferred activities from packages 9531 // with a home activity running in the process to prevent a repeatedly crashing app 9532 // from blocking the user to manually clear the list. 9533 final ArrayList<ActivityRecord> activities = app.activities; 9534 if (app == mHomeProcess && activities.size() > 0 9535 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9536 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9537 final ActivityRecord r = activities.get(activityNdx); 9538 if (r.isHomeActivity()) { 9539 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9540 try { 9541 ActivityThread.getPackageManager() 9542 .clearPackagePreferredActivities(r.packageName); 9543 } catch (RemoteException c) { 9544 // pm is in same process, this will never happen. 9545 } 9546 } 9547 } 9548 } 9549 9550 if (!app.isolated) { 9551 // XXX Can't keep track of crash times for isolated processes, 9552 // because they don't have a perisistent identity. 9553 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9554 } 9555 9556 return true; 9557 } 9558 9559 void startAppProblemLocked(ProcessRecord app) { 9560 if (app.userId == mCurrentUserId) { 9561 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9562 mContext, app.info.packageName, app.info.flags); 9563 } else { 9564 // If this app is not running under the current user, then we 9565 // can't give it a report button because that would require 9566 // launching the report UI under a different user. 9567 app.errorReportReceiver = null; 9568 } 9569 skipCurrentReceiverLocked(app); 9570 } 9571 9572 void skipCurrentReceiverLocked(ProcessRecord app) { 9573 for (BroadcastQueue queue : mBroadcastQueues) { 9574 queue.skipCurrentReceiverLocked(app); 9575 } 9576 } 9577 9578 /** 9579 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9580 * The application process will exit immediately after this call returns. 9581 * @param app object of the crashing app, null for the system server 9582 * @param crashInfo describing the exception 9583 */ 9584 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9585 ProcessRecord r = findAppProcess(app, "Crash"); 9586 final String processName = app == null ? "system_server" 9587 : (r == null ? "unknown" : r.processName); 9588 9589 handleApplicationCrashInner("crash", r, processName, crashInfo); 9590 } 9591 9592 /* Native crash reporting uses this inner version because it needs to be somewhat 9593 * decoupled from the AM-managed cleanup lifecycle 9594 */ 9595 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9596 ApplicationErrorReport.CrashInfo crashInfo) { 9597 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9598 UserHandle.getUserId(Binder.getCallingUid()), processName, 9599 r == null ? -1 : r.info.flags, 9600 crashInfo.exceptionClassName, 9601 crashInfo.exceptionMessage, 9602 crashInfo.throwFileName, 9603 crashInfo.throwLineNumber); 9604 9605 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9606 9607 crashApplication(r, crashInfo); 9608 } 9609 9610 public void handleApplicationStrictModeViolation( 9611 IBinder app, 9612 int violationMask, 9613 StrictMode.ViolationInfo info) { 9614 ProcessRecord r = findAppProcess(app, "StrictMode"); 9615 if (r == null) { 9616 return; 9617 } 9618 9619 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9620 Integer stackFingerprint = info.hashCode(); 9621 boolean logIt = true; 9622 synchronized (mAlreadyLoggedViolatedStacks) { 9623 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9624 logIt = false; 9625 // TODO: sub-sample into EventLog for these, with 9626 // the info.durationMillis? Then we'd get 9627 // the relative pain numbers, without logging all 9628 // the stack traces repeatedly. We'd want to do 9629 // likewise in the client code, which also does 9630 // dup suppression, before the Binder call. 9631 } else { 9632 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9633 mAlreadyLoggedViolatedStacks.clear(); 9634 } 9635 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9636 } 9637 } 9638 if (logIt) { 9639 logStrictModeViolationToDropBox(r, info); 9640 } 9641 } 9642 9643 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9644 AppErrorResult result = new AppErrorResult(); 9645 synchronized (this) { 9646 final long origId = Binder.clearCallingIdentity(); 9647 9648 Message msg = Message.obtain(); 9649 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9650 HashMap<String, Object> data = new HashMap<String, Object>(); 9651 data.put("result", result); 9652 data.put("app", r); 9653 data.put("violationMask", violationMask); 9654 data.put("info", info); 9655 msg.obj = data; 9656 mHandler.sendMessage(msg); 9657 9658 Binder.restoreCallingIdentity(origId); 9659 } 9660 int res = result.get(); 9661 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9662 } 9663 } 9664 9665 // Depending on the policy in effect, there could be a bunch of 9666 // these in quick succession so we try to batch these together to 9667 // minimize disk writes, number of dropbox entries, and maximize 9668 // compression, by having more fewer, larger records. 9669 private void logStrictModeViolationToDropBox( 9670 ProcessRecord process, 9671 StrictMode.ViolationInfo info) { 9672 if (info == null) { 9673 return; 9674 } 9675 final boolean isSystemApp = process == null || 9676 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9677 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9678 final String processName = process == null ? "unknown" : process.processName; 9679 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9680 final DropBoxManager dbox = (DropBoxManager) 9681 mContext.getSystemService(Context.DROPBOX_SERVICE); 9682 9683 // Exit early if the dropbox isn't configured to accept this report type. 9684 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9685 9686 boolean bufferWasEmpty; 9687 boolean needsFlush; 9688 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9689 synchronized (sb) { 9690 bufferWasEmpty = sb.length() == 0; 9691 appendDropBoxProcessHeaders(process, processName, sb); 9692 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9693 sb.append("System-App: ").append(isSystemApp).append("\n"); 9694 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9695 if (info.violationNumThisLoop != 0) { 9696 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9697 } 9698 if (info.numAnimationsRunning != 0) { 9699 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9700 } 9701 if (info.broadcastIntentAction != null) { 9702 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9703 } 9704 if (info.durationMillis != -1) { 9705 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9706 } 9707 if (info.numInstances != -1) { 9708 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9709 } 9710 if (info.tags != null) { 9711 for (String tag : info.tags) { 9712 sb.append("Span-Tag: ").append(tag).append("\n"); 9713 } 9714 } 9715 sb.append("\n"); 9716 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9717 sb.append(info.crashInfo.stackTrace); 9718 } 9719 sb.append("\n"); 9720 9721 // Only buffer up to ~64k. Various logging bits truncate 9722 // things at 128k. 9723 needsFlush = (sb.length() > 64 * 1024); 9724 } 9725 9726 // Flush immediately if the buffer's grown too large, or this 9727 // is a non-system app. Non-system apps are isolated with a 9728 // different tag & policy and not batched. 9729 // 9730 // Batching is useful during internal testing with 9731 // StrictMode settings turned up high. Without batching, 9732 // thousands of separate files could be created on boot. 9733 if (!isSystemApp || needsFlush) { 9734 new Thread("Error dump: " + dropboxTag) { 9735 @Override 9736 public void run() { 9737 String report; 9738 synchronized (sb) { 9739 report = sb.toString(); 9740 sb.delete(0, sb.length()); 9741 sb.trimToSize(); 9742 } 9743 if (report.length() != 0) { 9744 dbox.addText(dropboxTag, report); 9745 } 9746 } 9747 }.start(); 9748 return; 9749 } 9750 9751 // System app batching: 9752 if (!bufferWasEmpty) { 9753 // An existing dropbox-writing thread is outstanding, so 9754 // we don't need to start it up. The existing thread will 9755 // catch the buffer appends we just did. 9756 return; 9757 } 9758 9759 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9760 // (After this point, we shouldn't access AMS internal data structures.) 9761 new Thread("Error dump: " + dropboxTag) { 9762 @Override 9763 public void run() { 9764 // 5 second sleep to let stacks arrive and be batched together 9765 try { 9766 Thread.sleep(5000); // 5 seconds 9767 } catch (InterruptedException e) {} 9768 9769 String errorReport; 9770 synchronized (mStrictModeBuffer) { 9771 errorReport = mStrictModeBuffer.toString(); 9772 if (errorReport.length() == 0) { 9773 return; 9774 } 9775 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9776 mStrictModeBuffer.trimToSize(); 9777 } 9778 dbox.addText(dropboxTag, errorReport); 9779 } 9780 }.start(); 9781 } 9782 9783 /** 9784 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9785 * @param app object of the crashing app, null for the system server 9786 * @param tag reported by the caller 9787 * @param crashInfo describing the context of the error 9788 * @return true if the process should exit immediately (WTF is fatal) 9789 */ 9790 public boolean handleApplicationWtf(IBinder app, String tag, 9791 ApplicationErrorReport.CrashInfo crashInfo) { 9792 ProcessRecord r = findAppProcess(app, "WTF"); 9793 final String processName = app == null ? "system_server" 9794 : (r == null ? "unknown" : r.processName); 9795 9796 EventLog.writeEvent(EventLogTags.AM_WTF, 9797 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9798 processName, 9799 r == null ? -1 : r.info.flags, 9800 tag, crashInfo.exceptionMessage); 9801 9802 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9803 9804 if (r != null && r.pid != Process.myPid() && 9805 Settings.Global.getInt(mContext.getContentResolver(), 9806 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9807 crashApplication(r, crashInfo); 9808 return true; 9809 } else { 9810 return false; 9811 } 9812 } 9813 9814 /** 9815 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9816 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9817 */ 9818 private ProcessRecord findAppProcess(IBinder app, String reason) { 9819 if (app == null) { 9820 return null; 9821 } 9822 9823 synchronized (this) { 9824 final int NP = mProcessNames.getMap().size(); 9825 for (int ip=0; ip<NP; ip++) { 9826 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9827 final int NA = apps.size(); 9828 for (int ia=0; ia<NA; ia++) { 9829 ProcessRecord p = apps.valueAt(ia); 9830 if (p.thread != null && p.thread.asBinder() == app) { 9831 return p; 9832 } 9833 } 9834 } 9835 9836 Slog.w(TAG, "Can't find mystery application for " + reason 9837 + " from pid=" + Binder.getCallingPid() 9838 + " uid=" + Binder.getCallingUid() + ": " + app); 9839 return null; 9840 } 9841 } 9842 9843 /** 9844 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9845 * to append various headers to the dropbox log text. 9846 */ 9847 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9848 StringBuilder sb) { 9849 // Watchdog thread ends up invoking this function (with 9850 // a null ProcessRecord) to add the stack file to dropbox. 9851 // Do not acquire a lock on this (am) in such cases, as it 9852 // could cause a potential deadlock, if and when watchdog 9853 // is invoked due to unavailability of lock on am and it 9854 // would prevent watchdog from killing system_server. 9855 if (process == null) { 9856 sb.append("Process: ").append(processName).append("\n"); 9857 return; 9858 } 9859 // Note: ProcessRecord 'process' is guarded by the service 9860 // instance. (notably process.pkgList, which could otherwise change 9861 // concurrently during execution of this method) 9862 synchronized (this) { 9863 sb.append("Process: ").append(processName).append("\n"); 9864 int flags = process.info.flags; 9865 IPackageManager pm = AppGlobals.getPackageManager(); 9866 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 9867 for (int ip=0; ip<process.pkgList.size(); ip++) { 9868 String pkg = process.pkgList.keyAt(ip); 9869 sb.append("Package: ").append(pkg); 9870 try { 9871 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 9872 if (pi != null) { 9873 sb.append(" v").append(pi.versionCode); 9874 if (pi.versionName != null) { 9875 sb.append(" (").append(pi.versionName).append(")"); 9876 } 9877 } 9878 } catch (RemoteException e) { 9879 Slog.e(TAG, "Error getting package info: " + pkg, e); 9880 } 9881 sb.append("\n"); 9882 } 9883 } 9884 } 9885 9886 private static String processClass(ProcessRecord process) { 9887 if (process == null || process.pid == MY_PID) { 9888 return "system_server"; 9889 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9890 return "system_app"; 9891 } else { 9892 return "data_app"; 9893 } 9894 } 9895 9896 /** 9897 * Write a description of an error (crash, WTF, ANR) to the drop box. 9898 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 9899 * @param process which caused the error, null means the system server 9900 * @param activity which triggered the error, null if unknown 9901 * @param parent activity related to the error, null if unknown 9902 * @param subject line related to the error, null if absent 9903 * @param report in long form describing the error, null if absent 9904 * @param logFile to include in the report, null if none 9905 * @param crashInfo giving an application stack trace, null if absent 9906 */ 9907 public void addErrorToDropBox(String eventType, 9908 ProcessRecord process, String processName, ActivityRecord activity, 9909 ActivityRecord parent, String subject, 9910 final String report, final File logFile, 9911 final ApplicationErrorReport.CrashInfo crashInfo) { 9912 // NOTE -- this must never acquire the ActivityManagerService lock, 9913 // otherwise the watchdog may be prevented from resetting the system. 9914 9915 final String dropboxTag = processClass(process) + "_" + eventType; 9916 final DropBoxManager dbox = (DropBoxManager) 9917 mContext.getSystemService(Context.DROPBOX_SERVICE); 9918 9919 // Exit early if the dropbox isn't configured to accept this report type. 9920 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9921 9922 final StringBuilder sb = new StringBuilder(1024); 9923 appendDropBoxProcessHeaders(process, processName, sb); 9924 if (activity != null) { 9925 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 9926 } 9927 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 9928 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 9929 } 9930 if (parent != null && parent != activity) { 9931 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 9932 } 9933 if (subject != null) { 9934 sb.append("Subject: ").append(subject).append("\n"); 9935 } 9936 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9937 if (Debug.isDebuggerConnected()) { 9938 sb.append("Debugger: Connected\n"); 9939 } 9940 sb.append("\n"); 9941 9942 // Do the rest in a worker thread to avoid blocking the caller on I/O 9943 // (After this point, we shouldn't access AMS internal data structures.) 9944 Thread worker = new Thread("Error dump: " + dropboxTag) { 9945 @Override 9946 public void run() { 9947 if (report != null) { 9948 sb.append(report); 9949 } 9950 if (logFile != null) { 9951 try { 9952 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 9953 "\n\n[[TRUNCATED]]")); 9954 } catch (IOException e) { 9955 Slog.e(TAG, "Error reading " + logFile, e); 9956 } 9957 } 9958 if (crashInfo != null && crashInfo.stackTrace != null) { 9959 sb.append(crashInfo.stackTrace); 9960 } 9961 9962 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 9963 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 9964 if (lines > 0) { 9965 sb.append("\n"); 9966 9967 // Merge several logcat streams, and take the last N lines 9968 InputStreamReader input = null; 9969 try { 9970 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 9971 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 9972 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 9973 9974 try { logcat.getOutputStream().close(); } catch (IOException e) {} 9975 try { logcat.getErrorStream().close(); } catch (IOException e) {} 9976 input = new InputStreamReader(logcat.getInputStream()); 9977 9978 int num; 9979 char[] buf = new char[8192]; 9980 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 9981 } catch (IOException e) { 9982 Slog.e(TAG, "Error running logcat", e); 9983 } finally { 9984 if (input != null) try { input.close(); } catch (IOException e) {} 9985 } 9986 } 9987 9988 dbox.addText(dropboxTag, sb.toString()); 9989 } 9990 }; 9991 9992 if (process == null) { 9993 // If process is null, we are being called from some internal code 9994 // and may be about to die -- run this synchronously. 9995 worker.run(); 9996 } else { 9997 worker.start(); 9998 } 9999 } 10000 10001 /** 10002 * Bring up the "unexpected error" dialog box for a crashing app. 10003 * Deal with edge cases (intercepts from instrumented applications, 10004 * ActivityController, error intent receivers, that sort of thing). 10005 * @param r the application crashing 10006 * @param crashInfo describing the failure 10007 */ 10008 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10009 long timeMillis = System.currentTimeMillis(); 10010 String shortMsg = crashInfo.exceptionClassName; 10011 String longMsg = crashInfo.exceptionMessage; 10012 String stackTrace = crashInfo.stackTrace; 10013 if (shortMsg != null && longMsg != null) { 10014 longMsg = shortMsg + ": " + longMsg; 10015 } else if (shortMsg != null) { 10016 longMsg = shortMsg; 10017 } 10018 10019 AppErrorResult result = new AppErrorResult(); 10020 synchronized (this) { 10021 if (mController != null) { 10022 try { 10023 String name = r != null ? r.processName : null; 10024 int pid = r != null ? r.pid : Binder.getCallingPid(); 10025 if (!mController.appCrashed(name, pid, 10026 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10027 Slog.w(TAG, "Force-killing crashed app " + name 10028 + " at watcher's request"); 10029 Process.killProcess(pid); 10030 return; 10031 } 10032 } catch (RemoteException e) { 10033 mController = null; 10034 Watchdog.getInstance().setActivityController(null); 10035 } 10036 } 10037 10038 final long origId = Binder.clearCallingIdentity(); 10039 10040 // If this process is running instrumentation, finish it. 10041 if (r != null && r.instrumentationClass != null) { 10042 Slog.w(TAG, "Error in app " + r.processName 10043 + " running instrumentation " + r.instrumentationClass + ":"); 10044 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10045 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10046 Bundle info = new Bundle(); 10047 info.putString("shortMsg", shortMsg); 10048 info.putString("longMsg", longMsg); 10049 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10050 Binder.restoreCallingIdentity(origId); 10051 return; 10052 } 10053 10054 // If we can't identify the process or it's already exceeded its crash quota, 10055 // quit right away without showing a crash dialog. 10056 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10057 Binder.restoreCallingIdentity(origId); 10058 return; 10059 } 10060 10061 Message msg = Message.obtain(); 10062 msg.what = SHOW_ERROR_MSG; 10063 HashMap data = new HashMap(); 10064 data.put("result", result); 10065 data.put("app", r); 10066 msg.obj = data; 10067 mHandler.sendMessage(msg); 10068 10069 Binder.restoreCallingIdentity(origId); 10070 } 10071 10072 int res = result.get(); 10073 10074 Intent appErrorIntent = null; 10075 synchronized (this) { 10076 if (r != null && !r.isolated) { 10077 // XXX Can't keep track of crash time for isolated processes, 10078 // since they don't have a persistent identity. 10079 mProcessCrashTimes.put(r.info.processName, r.uid, 10080 SystemClock.uptimeMillis()); 10081 } 10082 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10083 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10084 } 10085 } 10086 10087 if (appErrorIntent != null) { 10088 try { 10089 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10090 } catch (ActivityNotFoundException e) { 10091 Slog.w(TAG, "bug report receiver dissappeared", e); 10092 } 10093 } 10094 } 10095 10096 Intent createAppErrorIntentLocked(ProcessRecord r, 10097 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10098 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10099 if (report == null) { 10100 return null; 10101 } 10102 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10103 result.setComponent(r.errorReportReceiver); 10104 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10105 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10106 return result; 10107 } 10108 10109 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10110 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10111 if (r.errorReportReceiver == null) { 10112 return null; 10113 } 10114 10115 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10116 return null; 10117 } 10118 10119 ApplicationErrorReport report = new ApplicationErrorReport(); 10120 report.packageName = r.info.packageName; 10121 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10122 report.processName = r.processName; 10123 report.time = timeMillis; 10124 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10125 10126 if (r.crashing || r.forceCrashReport) { 10127 report.type = ApplicationErrorReport.TYPE_CRASH; 10128 report.crashInfo = crashInfo; 10129 } else if (r.notResponding) { 10130 report.type = ApplicationErrorReport.TYPE_ANR; 10131 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10132 10133 report.anrInfo.activity = r.notRespondingReport.tag; 10134 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10135 report.anrInfo.info = r.notRespondingReport.longMsg; 10136 } 10137 10138 return report; 10139 } 10140 10141 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10142 enforceNotIsolatedCaller("getProcessesInErrorState"); 10143 // assume our apps are happy - lazy create the list 10144 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10145 10146 final boolean allUsers = ActivityManager.checkUidPermission( 10147 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10148 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10149 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10150 10151 synchronized (this) { 10152 10153 // iterate across all processes 10154 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10155 ProcessRecord app = mLruProcesses.get(i); 10156 if (!allUsers && app.userId != userId) { 10157 continue; 10158 } 10159 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10160 // This one's in trouble, so we'll generate a report for it 10161 // crashes are higher priority (in case there's a crash *and* an anr) 10162 ActivityManager.ProcessErrorStateInfo report = null; 10163 if (app.crashing) { 10164 report = app.crashingReport; 10165 } else if (app.notResponding) { 10166 report = app.notRespondingReport; 10167 } 10168 10169 if (report != null) { 10170 if (errList == null) { 10171 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10172 } 10173 errList.add(report); 10174 } else { 10175 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10176 " crashing = " + app.crashing + 10177 " notResponding = " + app.notResponding); 10178 } 10179 } 10180 } 10181 } 10182 10183 return errList; 10184 } 10185 10186 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10187 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10188 if (currApp != null) { 10189 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10190 } 10191 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10192 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10193 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10194 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10195 if (currApp != null) { 10196 currApp.lru = 0; 10197 } 10198 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10199 } else if (adj >= ProcessList.SERVICE_ADJ) { 10200 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10201 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10202 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10203 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10204 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10205 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10206 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10207 } else { 10208 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10209 } 10210 } 10211 10212 private void fillInProcMemInfo(ProcessRecord app, 10213 ActivityManager.RunningAppProcessInfo outInfo) { 10214 outInfo.pid = app.pid; 10215 outInfo.uid = app.info.uid; 10216 if (mHeavyWeightProcess == app) { 10217 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10218 } 10219 if (app.persistent) { 10220 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10221 } 10222 if (app.activities.size() > 0) { 10223 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10224 } 10225 outInfo.lastTrimLevel = app.trimMemoryLevel; 10226 int adj = app.curAdj; 10227 outInfo.importance = oomAdjToImportance(adj, outInfo); 10228 outInfo.importanceReasonCode = app.adjTypeCode; 10229 } 10230 10231 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10232 enforceNotIsolatedCaller("getRunningAppProcesses"); 10233 // Lazy instantiation of list 10234 List<ActivityManager.RunningAppProcessInfo> runList = null; 10235 final boolean allUsers = ActivityManager.checkUidPermission( 10236 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10237 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10238 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10239 synchronized (this) { 10240 // Iterate across all processes 10241 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10242 ProcessRecord app = mLruProcesses.get(i); 10243 if (!allUsers && app.userId != userId) { 10244 continue; 10245 } 10246 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10247 // Generate process state info for running application 10248 ActivityManager.RunningAppProcessInfo currApp = 10249 new ActivityManager.RunningAppProcessInfo(app.processName, 10250 app.pid, app.getPackageList()); 10251 fillInProcMemInfo(app, currApp); 10252 if (app.adjSource instanceof ProcessRecord) { 10253 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10254 currApp.importanceReasonImportance = oomAdjToImportance( 10255 app.adjSourceOom, null); 10256 } else if (app.adjSource instanceof ActivityRecord) { 10257 ActivityRecord r = (ActivityRecord)app.adjSource; 10258 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10259 } 10260 if (app.adjTarget instanceof ComponentName) { 10261 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10262 } 10263 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10264 // + " lru=" + currApp.lru); 10265 if (runList == null) { 10266 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10267 } 10268 runList.add(currApp); 10269 } 10270 } 10271 } 10272 return runList; 10273 } 10274 10275 public List<ApplicationInfo> getRunningExternalApplications() { 10276 enforceNotIsolatedCaller("getRunningExternalApplications"); 10277 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10278 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10279 if (runningApps != null && runningApps.size() > 0) { 10280 Set<String> extList = new HashSet<String>(); 10281 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10282 if (app.pkgList != null) { 10283 for (String pkg : app.pkgList) { 10284 extList.add(pkg); 10285 } 10286 } 10287 } 10288 IPackageManager pm = AppGlobals.getPackageManager(); 10289 for (String pkg : extList) { 10290 try { 10291 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10292 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10293 retList.add(info); 10294 } 10295 } catch (RemoteException e) { 10296 } 10297 } 10298 } 10299 return retList; 10300 } 10301 10302 @Override 10303 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10304 enforceNotIsolatedCaller("getMyMemoryState"); 10305 synchronized (this) { 10306 ProcessRecord proc; 10307 synchronized (mPidsSelfLocked) { 10308 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10309 } 10310 fillInProcMemInfo(proc, outInfo); 10311 } 10312 } 10313 10314 @Override 10315 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10316 if (checkCallingPermission(android.Manifest.permission.DUMP) 10317 != PackageManager.PERMISSION_GRANTED) { 10318 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10319 + Binder.getCallingPid() 10320 + ", uid=" + Binder.getCallingUid() 10321 + " without permission " 10322 + android.Manifest.permission.DUMP); 10323 return; 10324 } 10325 10326 boolean dumpAll = false; 10327 boolean dumpClient = false; 10328 String dumpPackage = null; 10329 10330 int opti = 0; 10331 while (opti < args.length) { 10332 String opt = args[opti]; 10333 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10334 break; 10335 } 10336 opti++; 10337 if ("-a".equals(opt)) { 10338 dumpAll = true; 10339 } else if ("-c".equals(opt)) { 10340 dumpClient = true; 10341 } else if ("-h".equals(opt)) { 10342 pw.println("Activity manager dump options:"); 10343 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10344 pw.println(" cmd may be one of:"); 10345 pw.println(" a[ctivities]: activity stack state"); 10346 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10347 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10348 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10349 pw.println(" o[om]: out of memory management"); 10350 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10351 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10352 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10353 pw.println(" service [COMP_SPEC]: service client-side state"); 10354 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10355 pw.println(" all: dump all activities"); 10356 pw.println(" top: dump the top activity"); 10357 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10358 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10359 pw.println(" a partial substring in a component name, a"); 10360 pw.println(" hex object identifier."); 10361 pw.println(" -a: include all available server state."); 10362 pw.println(" -c: include client state."); 10363 return; 10364 } else { 10365 pw.println("Unknown argument: " + opt + "; use -h for help"); 10366 } 10367 } 10368 10369 long origId = Binder.clearCallingIdentity(); 10370 boolean more = false; 10371 // Is the caller requesting to dump a particular piece of data? 10372 if (opti < args.length) { 10373 String cmd = args[opti]; 10374 opti++; 10375 if ("activities".equals(cmd) || "a".equals(cmd)) { 10376 synchronized (this) { 10377 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10378 } 10379 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10380 String[] newArgs; 10381 String name; 10382 if (opti >= args.length) { 10383 name = null; 10384 newArgs = EMPTY_STRING_ARRAY; 10385 } else { 10386 name = args[opti]; 10387 opti++; 10388 newArgs = new String[args.length - opti]; 10389 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10390 args.length - opti); 10391 } 10392 synchronized (this) { 10393 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10394 } 10395 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10396 String[] newArgs; 10397 String name; 10398 if (opti >= args.length) { 10399 name = null; 10400 newArgs = EMPTY_STRING_ARRAY; 10401 } else { 10402 name = args[opti]; 10403 opti++; 10404 newArgs = new String[args.length - opti]; 10405 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10406 args.length - opti); 10407 } 10408 synchronized (this) { 10409 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10410 } 10411 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10412 String[] newArgs; 10413 String name; 10414 if (opti >= args.length) { 10415 name = null; 10416 newArgs = EMPTY_STRING_ARRAY; 10417 } else { 10418 name = args[opti]; 10419 opti++; 10420 newArgs = new String[args.length - opti]; 10421 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10422 args.length - opti); 10423 } 10424 synchronized (this) { 10425 dumpProcessesLocked(fd, pw, args, opti, true, name); 10426 } 10427 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10428 synchronized (this) { 10429 dumpOomLocked(fd, pw, args, opti, true); 10430 } 10431 } else if ("provider".equals(cmd)) { 10432 String[] newArgs; 10433 String name; 10434 if (opti >= args.length) { 10435 name = null; 10436 newArgs = EMPTY_STRING_ARRAY; 10437 } else { 10438 name = args[opti]; 10439 opti++; 10440 newArgs = new String[args.length - opti]; 10441 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10442 } 10443 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10444 pw.println("No providers match: " + name); 10445 pw.println("Use -h for help."); 10446 } 10447 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10448 synchronized (this) { 10449 dumpProvidersLocked(fd, pw, args, opti, true, null); 10450 } 10451 } else if ("service".equals(cmd)) { 10452 String[] newArgs; 10453 String name; 10454 if (opti >= args.length) { 10455 name = null; 10456 newArgs = EMPTY_STRING_ARRAY; 10457 } else { 10458 name = args[opti]; 10459 opti++; 10460 newArgs = new String[args.length - opti]; 10461 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10462 args.length - opti); 10463 } 10464 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10465 pw.println("No services match: " + name); 10466 pw.println("Use -h for help."); 10467 } 10468 } else if ("package".equals(cmd)) { 10469 String[] newArgs; 10470 if (opti >= args.length) { 10471 pw.println("package: no package name specified"); 10472 pw.println("Use -h for help."); 10473 } else { 10474 dumpPackage = args[opti]; 10475 opti++; 10476 newArgs = new String[args.length - opti]; 10477 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10478 args.length - opti); 10479 args = newArgs; 10480 opti = 0; 10481 more = true; 10482 } 10483 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10484 synchronized (this) { 10485 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10486 } 10487 } else { 10488 // Dumping a single activity? 10489 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10490 pw.println("Bad activity command, or no activities match: " + cmd); 10491 pw.println("Use -h for help."); 10492 } 10493 } 10494 if (!more) { 10495 Binder.restoreCallingIdentity(origId); 10496 return; 10497 } 10498 } 10499 10500 // No piece of data specified, dump everything. 10501 synchronized (this) { 10502 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10503 pw.println(); 10504 if (dumpAll) { 10505 pw.println("-------------------------------------------------------------------------------"); 10506 } 10507 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10508 pw.println(); 10509 if (dumpAll) { 10510 pw.println("-------------------------------------------------------------------------------"); 10511 } 10512 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10513 pw.println(); 10514 if (dumpAll) { 10515 pw.println("-------------------------------------------------------------------------------"); 10516 } 10517 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10518 pw.println(); 10519 if (dumpAll) { 10520 pw.println("-------------------------------------------------------------------------------"); 10521 } 10522 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10523 pw.println(); 10524 if (dumpAll) { 10525 pw.println("-------------------------------------------------------------------------------"); 10526 } 10527 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10528 } 10529 Binder.restoreCallingIdentity(origId); 10530 } 10531 10532 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10533 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10534 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10535 10536 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10537 dumpPackage); 10538 boolean needSep = printedAnything; 10539 10540 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10541 dumpPackage, needSep, " mFocusedActivity: "); 10542 if (printed) { 10543 printedAnything = true; 10544 needSep = false; 10545 } 10546 10547 if (dumpPackage == null) { 10548 if (needSep) { 10549 pw.println(); 10550 } 10551 needSep = true; 10552 printedAnything = true; 10553 mStackSupervisor.dump(pw, " "); 10554 } 10555 10556 if (mRecentTasks.size() > 0) { 10557 boolean printedHeader = false; 10558 10559 final int N = mRecentTasks.size(); 10560 for (int i=0; i<N; i++) { 10561 TaskRecord tr = mRecentTasks.get(i); 10562 if (dumpPackage != null) { 10563 if (tr.realActivity == null || 10564 !dumpPackage.equals(tr.realActivity)) { 10565 continue; 10566 } 10567 } 10568 if (!printedHeader) { 10569 if (needSep) { 10570 pw.println(); 10571 } 10572 pw.println(" Recent tasks:"); 10573 printedHeader = true; 10574 printedAnything = true; 10575 } 10576 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10577 pw.println(tr); 10578 if (dumpAll) { 10579 mRecentTasks.get(i).dump(pw, " "); 10580 } 10581 } 10582 } 10583 10584 if (!printedAnything) { 10585 pw.println(" (nothing)"); 10586 } 10587 } 10588 10589 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10590 int opti, boolean dumpAll, String dumpPackage) { 10591 boolean needSep = false; 10592 boolean printedAnything = false; 10593 int numPers = 0; 10594 10595 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10596 10597 if (dumpAll) { 10598 final int NP = mProcessNames.getMap().size(); 10599 for (int ip=0; ip<NP; ip++) { 10600 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10601 final int NA = procs.size(); 10602 for (int ia=0; ia<NA; ia++) { 10603 ProcessRecord r = procs.valueAt(ia); 10604 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10605 continue; 10606 } 10607 if (!needSep) { 10608 pw.println(" All known processes:"); 10609 needSep = true; 10610 printedAnything = true; 10611 } 10612 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10613 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10614 pw.print(" "); pw.println(r); 10615 r.dump(pw, " "); 10616 if (r.persistent) { 10617 numPers++; 10618 } 10619 } 10620 } 10621 } 10622 10623 if (mIsolatedProcesses.size() > 0) { 10624 boolean printed = false; 10625 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10626 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10627 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10628 continue; 10629 } 10630 if (!printed) { 10631 if (needSep) { 10632 pw.println(); 10633 } 10634 pw.println(" Isolated process list (sorted by uid):"); 10635 printedAnything = true; 10636 printed = true; 10637 needSep = true; 10638 } 10639 pw.println(String.format("%sIsolated #%2d: %s", 10640 " ", i, r.toString())); 10641 } 10642 } 10643 10644 if (mLruProcesses.size() > 0) { 10645 if (needSep) { 10646 pw.println(); 10647 } 10648 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10649 pw.print(" total, non-act at "); 10650 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10651 pw.print(", non-svc at "); 10652 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10653 pw.println("):"); 10654 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10655 needSep = true; 10656 printedAnything = true; 10657 } 10658 10659 if (dumpAll || dumpPackage != null) { 10660 synchronized (mPidsSelfLocked) { 10661 boolean printed = false; 10662 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10663 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10664 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10665 continue; 10666 } 10667 if (!printed) { 10668 if (needSep) pw.println(); 10669 needSep = true; 10670 pw.println(" PID mappings:"); 10671 printed = true; 10672 printedAnything = true; 10673 } 10674 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10675 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10676 } 10677 } 10678 } 10679 10680 if (mForegroundProcesses.size() > 0) { 10681 synchronized (mPidsSelfLocked) { 10682 boolean printed = false; 10683 for (int i=0; i<mForegroundProcesses.size(); i++) { 10684 ProcessRecord r = mPidsSelfLocked.get( 10685 mForegroundProcesses.valueAt(i).pid); 10686 if (dumpPackage != null && (r == null 10687 || !r.pkgList.containsKey(dumpPackage))) { 10688 continue; 10689 } 10690 if (!printed) { 10691 if (needSep) pw.println(); 10692 needSep = true; 10693 pw.println(" Foreground Processes:"); 10694 printed = true; 10695 printedAnything = true; 10696 } 10697 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10698 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10699 } 10700 } 10701 } 10702 10703 if (mPersistentStartingProcesses.size() > 0) { 10704 if (needSep) pw.println(); 10705 needSep = true; 10706 printedAnything = true; 10707 pw.println(" Persisent processes that are starting:"); 10708 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10709 "Starting Norm", "Restarting PERS", dumpPackage); 10710 } 10711 10712 if (mRemovedProcesses.size() > 0) { 10713 if (needSep) pw.println(); 10714 needSep = true; 10715 printedAnything = true; 10716 pw.println(" Processes that are being removed:"); 10717 dumpProcessList(pw, this, mRemovedProcesses, " ", 10718 "Removed Norm", "Removed PERS", dumpPackage); 10719 } 10720 10721 if (mProcessesOnHold.size() > 0) { 10722 if (needSep) pw.println(); 10723 needSep = true; 10724 printedAnything = true; 10725 pw.println(" Processes that are on old until the system is ready:"); 10726 dumpProcessList(pw, this, mProcessesOnHold, " ", 10727 "OnHold Norm", "OnHold PERS", dumpPackage); 10728 } 10729 10730 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10731 10732 if (mProcessCrashTimes.getMap().size() > 0) { 10733 boolean printed = false; 10734 long now = SystemClock.uptimeMillis(); 10735 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10736 final int NP = pmap.size(); 10737 for (int ip=0; ip<NP; ip++) { 10738 String pname = pmap.keyAt(ip); 10739 SparseArray<Long> uids = pmap.valueAt(ip); 10740 final int N = uids.size(); 10741 for (int i=0; i<N; i++) { 10742 int puid = uids.keyAt(i); 10743 ProcessRecord r = mProcessNames.get(pname, puid); 10744 if (dumpPackage != null && (r == null 10745 || !r.pkgList.containsKey(dumpPackage))) { 10746 continue; 10747 } 10748 if (!printed) { 10749 if (needSep) pw.println(); 10750 needSep = true; 10751 pw.println(" Time since processes crashed:"); 10752 printed = true; 10753 printedAnything = true; 10754 } 10755 pw.print(" Process "); pw.print(pname); 10756 pw.print(" uid "); pw.print(puid); 10757 pw.print(": last crashed "); 10758 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10759 pw.println(" ago"); 10760 } 10761 } 10762 } 10763 10764 if (mBadProcesses.getMap().size() > 0) { 10765 boolean printed = false; 10766 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10767 final int NP = pmap.size(); 10768 for (int ip=0; ip<NP; ip++) { 10769 String pname = pmap.keyAt(ip); 10770 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10771 final int N = uids.size(); 10772 for (int i=0; i<N; i++) { 10773 int puid = uids.keyAt(i); 10774 ProcessRecord r = mProcessNames.get(pname, puid); 10775 if (dumpPackage != null && (r == null 10776 || !r.pkgList.containsKey(dumpPackage))) { 10777 continue; 10778 } 10779 if (!printed) { 10780 if (needSep) pw.println(); 10781 needSep = true; 10782 pw.println(" Bad processes:"); 10783 printedAnything = true; 10784 } 10785 BadProcessInfo info = uids.valueAt(i); 10786 pw.print(" Bad process "); pw.print(pname); 10787 pw.print(" uid "); pw.print(puid); 10788 pw.print(": crashed at time "); pw.println(info.time); 10789 if (info.shortMsg != null) { 10790 pw.print(" Short msg: "); pw.println(info.shortMsg); 10791 } 10792 if (info.longMsg != null) { 10793 pw.print(" Long msg: "); pw.println(info.longMsg); 10794 } 10795 if (info.stack != null) { 10796 pw.println(" Stack:"); 10797 int lastPos = 0; 10798 for (int pos=0; pos<info.stack.length(); pos++) { 10799 if (info.stack.charAt(pos) == '\n') { 10800 pw.print(" "); 10801 pw.write(info.stack, lastPos, pos-lastPos); 10802 pw.println(); 10803 lastPos = pos+1; 10804 } 10805 } 10806 if (lastPos < info.stack.length()) { 10807 pw.print(" "); 10808 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10809 pw.println(); 10810 } 10811 } 10812 } 10813 } 10814 } 10815 10816 if (dumpPackage == null) { 10817 pw.println(); 10818 needSep = false; 10819 pw.println(" mStartedUsers:"); 10820 for (int i=0; i<mStartedUsers.size(); i++) { 10821 UserStartedState uss = mStartedUsers.valueAt(i); 10822 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10823 pw.print(": "); uss.dump("", pw); 10824 } 10825 pw.print(" mStartedUserArray: ["); 10826 for (int i=0; i<mStartedUserArray.length; i++) { 10827 if (i > 0) pw.print(", "); 10828 pw.print(mStartedUserArray[i]); 10829 } 10830 pw.println("]"); 10831 pw.print(" mUserLru: ["); 10832 for (int i=0; i<mUserLru.size(); i++) { 10833 if (i > 0) pw.print(", "); 10834 pw.print(mUserLru.get(i)); 10835 } 10836 pw.println("]"); 10837 if (dumpAll) { 10838 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10839 } 10840 } 10841 if (mHomeProcess != null && (dumpPackage == null 10842 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10843 if (needSep) { 10844 pw.println(); 10845 needSep = false; 10846 } 10847 pw.println(" mHomeProcess: " + mHomeProcess); 10848 } 10849 if (mPreviousProcess != null && (dumpPackage == null 10850 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 10851 if (needSep) { 10852 pw.println(); 10853 needSep = false; 10854 } 10855 pw.println(" mPreviousProcess: " + mPreviousProcess); 10856 } 10857 if (dumpAll) { 10858 StringBuilder sb = new StringBuilder(128); 10859 sb.append(" mPreviousProcessVisibleTime: "); 10860 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 10861 pw.println(sb); 10862 } 10863 if (mHeavyWeightProcess != null && (dumpPackage == null 10864 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 10865 if (needSep) { 10866 pw.println(); 10867 needSep = false; 10868 } 10869 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10870 } 10871 if (dumpPackage == null) { 10872 pw.println(" mConfiguration: " + mConfiguration); 10873 } 10874 if (dumpAll) { 10875 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 10876 if (mCompatModePackages.getPackages().size() > 0) { 10877 boolean printed = false; 10878 for (Map.Entry<String, Integer> entry 10879 : mCompatModePackages.getPackages().entrySet()) { 10880 String pkg = entry.getKey(); 10881 int mode = entry.getValue(); 10882 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 10883 continue; 10884 } 10885 if (!printed) { 10886 pw.println(" mScreenCompatPackages:"); 10887 printed = true; 10888 } 10889 pw.print(" "); pw.print(pkg); pw.print(": "); 10890 pw.print(mode); pw.println(); 10891 } 10892 } 10893 } 10894 if (dumpPackage == null) { 10895 if (mSleeping || mWentToSleep || mLockScreenShown) { 10896 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 10897 + " mLockScreenShown " + mLockScreenShown); 10898 } 10899 if (mShuttingDown) { 10900 pw.println(" mShuttingDown=" + mShuttingDown); 10901 } 10902 } 10903 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 10904 || mOrigWaitForDebugger) { 10905 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 10906 || dumpPackage.equals(mOrigDebugApp)) { 10907 if (needSep) { 10908 pw.println(); 10909 needSep = false; 10910 } 10911 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 10912 + " mDebugTransient=" + mDebugTransient 10913 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 10914 } 10915 } 10916 if (mOpenGlTraceApp != null) { 10917 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 10918 if (needSep) { 10919 pw.println(); 10920 needSep = false; 10921 } 10922 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 10923 } 10924 } 10925 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 10926 || mProfileFd != null) { 10927 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 10928 if (needSep) { 10929 pw.println(); 10930 needSep = false; 10931 } 10932 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 10933 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 10934 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 10935 + mAutoStopProfiler); 10936 } 10937 } 10938 if (dumpPackage == null) { 10939 if (mAlwaysFinishActivities || mController != null) { 10940 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 10941 + " mController=" + mController); 10942 } 10943 if (dumpAll) { 10944 pw.println(" Total persistent processes: " + numPers); 10945 pw.println(" mStartRunning=" + mStartRunning 10946 + " mProcessesReady=" + mProcessesReady 10947 + " mSystemReady=" + mSystemReady); 10948 pw.println(" mBooting=" + mBooting 10949 + " mBooted=" + mBooted 10950 + " mFactoryTest=" + mFactoryTest); 10951 pw.print(" mLastPowerCheckRealtime="); 10952 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 10953 pw.println(""); 10954 pw.print(" mLastPowerCheckUptime="); 10955 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 10956 pw.println(""); 10957 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 10958 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 10959 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 10960 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 10961 + " (" + mLruProcesses.size() + " total)" 10962 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 10963 + " mNumServiceProcs=" + mNumServiceProcs 10964 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 10965 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 10966 + " mLastMemoryLevel" + mLastMemoryLevel 10967 + " mLastNumProcesses" + mLastNumProcesses); 10968 long now = SystemClock.uptimeMillis(); 10969 pw.print(" mLastIdleTime="); 10970 TimeUtils.formatDuration(now, mLastIdleTime, pw); 10971 pw.print(" mLowRamSinceLastIdle="); 10972 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 10973 pw.println(); 10974 } 10975 } 10976 10977 if (!printedAnything) { 10978 pw.println(" (nothing)"); 10979 } 10980 } 10981 10982 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 10983 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 10984 if (mProcessesToGc.size() > 0) { 10985 boolean printed = false; 10986 long now = SystemClock.uptimeMillis(); 10987 for (int i=0; i<mProcessesToGc.size(); i++) { 10988 ProcessRecord proc = mProcessesToGc.get(i); 10989 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 10990 continue; 10991 } 10992 if (!printed) { 10993 if (needSep) pw.println(); 10994 needSep = true; 10995 pw.println(" Processes that are waiting to GC:"); 10996 printed = true; 10997 } 10998 pw.print(" Process "); pw.println(proc); 10999 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11000 pw.print(", last gced="); 11001 pw.print(now-proc.lastRequestedGc); 11002 pw.print(" ms ago, last lowMem="); 11003 pw.print(now-proc.lastLowMemory); 11004 pw.println(" ms ago"); 11005 11006 } 11007 } 11008 return needSep; 11009 } 11010 11011 void printOomLevel(PrintWriter pw, String name, int adj) { 11012 pw.print(" "); 11013 if (adj >= 0) { 11014 pw.print(' '); 11015 if (adj < 10) pw.print(' '); 11016 } else { 11017 if (adj > -10) pw.print(' '); 11018 } 11019 pw.print(adj); 11020 pw.print(": "); 11021 pw.print(name); 11022 pw.print(" ("); 11023 pw.print(mProcessList.getMemLevel(adj)/1024); 11024 pw.println(" kB)"); 11025 } 11026 11027 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11028 int opti, boolean dumpAll) { 11029 boolean needSep = false; 11030 11031 if (mLruProcesses.size() > 0) { 11032 if (needSep) pw.println(); 11033 needSep = true; 11034 pw.println(" OOM levels:"); 11035 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11036 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11037 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11038 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11039 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11040 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11041 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11042 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11043 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11044 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11045 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11046 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11047 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11048 11049 if (needSep) pw.println(); 11050 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11051 pw.print(" total, non-act at "); 11052 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11053 pw.print(", non-svc at "); 11054 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11055 pw.println("):"); 11056 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11057 needSep = true; 11058 } 11059 11060 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11061 11062 pw.println(); 11063 pw.println(" mHomeProcess: " + mHomeProcess); 11064 pw.println(" mPreviousProcess: " + mPreviousProcess); 11065 if (mHeavyWeightProcess != null) { 11066 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11067 } 11068 11069 return true; 11070 } 11071 11072 /** 11073 * There are three ways to call this: 11074 * - no provider specified: dump all the providers 11075 * - a flattened component name that matched an existing provider was specified as the 11076 * first arg: dump that one provider 11077 * - the first arg isn't the flattened component name of an existing provider: 11078 * dump all providers whose component contains the first arg as a substring 11079 */ 11080 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11081 int opti, boolean dumpAll) { 11082 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11083 } 11084 11085 static class ItemMatcher { 11086 ArrayList<ComponentName> components; 11087 ArrayList<String> strings; 11088 ArrayList<Integer> objects; 11089 boolean all; 11090 11091 ItemMatcher() { 11092 all = true; 11093 } 11094 11095 void build(String name) { 11096 ComponentName componentName = ComponentName.unflattenFromString(name); 11097 if (componentName != null) { 11098 if (components == null) { 11099 components = new ArrayList<ComponentName>(); 11100 } 11101 components.add(componentName); 11102 all = false; 11103 } else { 11104 int objectId = 0; 11105 // Not a '/' separated full component name; maybe an object ID? 11106 try { 11107 objectId = Integer.parseInt(name, 16); 11108 if (objects == null) { 11109 objects = new ArrayList<Integer>(); 11110 } 11111 objects.add(objectId); 11112 all = false; 11113 } catch (RuntimeException e) { 11114 // Not an integer; just do string match. 11115 if (strings == null) { 11116 strings = new ArrayList<String>(); 11117 } 11118 strings.add(name); 11119 all = false; 11120 } 11121 } 11122 } 11123 11124 int build(String[] args, int opti) { 11125 for (; opti<args.length; opti++) { 11126 String name = args[opti]; 11127 if ("--".equals(name)) { 11128 return opti+1; 11129 } 11130 build(name); 11131 } 11132 return opti; 11133 } 11134 11135 boolean match(Object object, ComponentName comp) { 11136 if (all) { 11137 return true; 11138 } 11139 if (components != null) { 11140 for (int i=0; i<components.size(); i++) { 11141 if (components.get(i).equals(comp)) { 11142 return true; 11143 } 11144 } 11145 } 11146 if (objects != null) { 11147 for (int i=0; i<objects.size(); i++) { 11148 if (System.identityHashCode(object) == objects.get(i)) { 11149 return true; 11150 } 11151 } 11152 } 11153 if (strings != null) { 11154 String flat = comp.flattenToString(); 11155 for (int i=0; i<strings.size(); i++) { 11156 if (flat.contains(strings.get(i))) { 11157 return true; 11158 } 11159 } 11160 } 11161 return false; 11162 } 11163 } 11164 11165 /** 11166 * There are three things that cmd can be: 11167 * - a flattened component name that matches an existing activity 11168 * - the cmd arg isn't the flattened component name of an existing activity: 11169 * dump all activity whose component contains the cmd as a substring 11170 * - A hex number of the ActivityRecord object instance. 11171 */ 11172 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11173 int opti, boolean dumpAll) { 11174 ArrayList<ActivityRecord> activities; 11175 11176 synchronized (this) { 11177 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11178 } 11179 11180 if (activities.size() <= 0) { 11181 return false; 11182 } 11183 11184 String[] newArgs = new String[args.length - opti]; 11185 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11186 11187 TaskRecord lastTask = null; 11188 boolean needSep = false; 11189 for (int i=activities.size()-1; i>=0; i--) { 11190 ActivityRecord r = activities.get(i); 11191 if (needSep) { 11192 pw.println(); 11193 } 11194 needSep = true; 11195 synchronized (this) { 11196 if (lastTask != r.task) { 11197 lastTask = r.task; 11198 pw.print("TASK "); pw.print(lastTask.affinity); 11199 pw.print(" id="); pw.println(lastTask.taskId); 11200 if (dumpAll) { 11201 lastTask.dump(pw, " "); 11202 } 11203 } 11204 } 11205 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11206 } 11207 return true; 11208 } 11209 11210 /** 11211 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11212 * there is a thread associated with the activity. 11213 */ 11214 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11215 final ActivityRecord r, String[] args, boolean dumpAll) { 11216 String innerPrefix = prefix + " "; 11217 synchronized (this) { 11218 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11219 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11220 pw.print(" pid="); 11221 if (r.app != null) pw.println(r.app.pid); 11222 else pw.println("(not running)"); 11223 if (dumpAll) { 11224 r.dump(pw, innerPrefix); 11225 } 11226 } 11227 if (r.app != null && r.app.thread != null) { 11228 // flush anything that is already in the PrintWriter since the thread is going 11229 // to write to the file descriptor directly 11230 pw.flush(); 11231 try { 11232 TransferPipe tp = new TransferPipe(); 11233 try { 11234 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11235 r.appToken, innerPrefix, args); 11236 tp.go(fd); 11237 } finally { 11238 tp.kill(); 11239 } 11240 } catch (IOException e) { 11241 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11242 } catch (RemoteException e) { 11243 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11244 } 11245 } 11246 } 11247 11248 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11249 int opti, boolean dumpAll, String dumpPackage) { 11250 boolean needSep = false; 11251 boolean onlyHistory = false; 11252 boolean printedAnything = false; 11253 11254 if ("history".equals(dumpPackage)) { 11255 if (opti < args.length && "-s".equals(args[opti])) { 11256 dumpAll = false; 11257 } 11258 onlyHistory = true; 11259 dumpPackage = null; 11260 } 11261 11262 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11263 if (!onlyHistory && dumpAll) { 11264 if (mRegisteredReceivers.size() > 0) { 11265 boolean printed = false; 11266 Iterator it = mRegisteredReceivers.values().iterator(); 11267 while (it.hasNext()) { 11268 ReceiverList r = (ReceiverList)it.next(); 11269 if (dumpPackage != null && (r.app == null || 11270 !dumpPackage.equals(r.app.info.packageName))) { 11271 continue; 11272 } 11273 if (!printed) { 11274 pw.println(" Registered Receivers:"); 11275 needSep = true; 11276 printed = true; 11277 printedAnything = true; 11278 } 11279 pw.print(" * "); pw.println(r); 11280 r.dump(pw, " "); 11281 } 11282 } 11283 11284 if (mReceiverResolver.dump(pw, needSep ? 11285 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11286 " ", dumpPackage, false)) { 11287 needSep = true; 11288 printedAnything = true; 11289 } 11290 } 11291 11292 for (BroadcastQueue q : mBroadcastQueues) { 11293 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11294 printedAnything |= needSep; 11295 } 11296 11297 needSep = true; 11298 11299 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11300 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11301 if (needSep) { 11302 pw.println(); 11303 } 11304 needSep = true; 11305 printedAnything = true; 11306 pw.print(" Sticky broadcasts for user "); 11307 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11308 StringBuilder sb = new StringBuilder(128); 11309 for (Map.Entry<String, ArrayList<Intent>> ent 11310 : mStickyBroadcasts.valueAt(user).entrySet()) { 11311 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11312 if (dumpAll) { 11313 pw.println(":"); 11314 ArrayList<Intent> intents = ent.getValue(); 11315 final int N = intents.size(); 11316 for (int i=0; i<N; i++) { 11317 sb.setLength(0); 11318 sb.append(" Intent: "); 11319 intents.get(i).toShortString(sb, false, true, false, false); 11320 pw.println(sb.toString()); 11321 Bundle bundle = intents.get(i).getExtras(); 11322 if (bundle != null) { 11323 pw.print(" "); 11324 pw.println(bundle.toString()); 11325 } 11326 } 11327 } else { 11328 pw.println(""); 11329 } 11330 } 11331 } 11332 } 11333 11334 if (!onlyHistory && dumpAll) { 11335 pw.println(); 11336 for (BroadcastQueue queue : mBroadcastQueues) { 11337 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11338 + queue.mBroadcastsScheduled); 11339 } 11340 pw.println(" mHandler:"); 11341 mHandler.dump(new PrintWriterPrinter(pw), " "); 11342 needSep = true; 11343 printedAnything = true; 11344 } 11345 11346 if (!printedAnything) { 11347 pw.println(" (nothing)"); 11348 } 11349 } 11350 11351 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11352 int opti, boolean dumpAll, String dumpPackage) { 11353 boolean needSep; 11354 boolean printedAnything = false; 11355 11356 ItemMatcher matcher = new ItemMatcher(); 11357 matcher.build(args, opti); 11358 11359 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11360 11361 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11362 printedAnything |= needSep; 11363 11364 if (mLaunchingProviders.size() > 0) { 11365 boolean printed = false; 11366 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11367 ContentProviderRecord r = mLaunchingProviders.get(i); 11368 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11369 continue; 11370 } 11371 if (!printed) { 11372 if (needSep) pw.println(); 11373 needSep = true; 11374 pw.println(" Launching content providers:"); 11375 printed = true; 11376 printedAnything = true; 11377 } 11378 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11379 pw.println(r); 11380 } 11381 } 11382 11383 if (mGrantedUriPermissions.size() > 0) { 11384 boolean printed = false; 11385 int dumpUid = -2; 11386 if (dumpPackage != null) { 11387 try { 11388 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11389 } catch (NameNotFoundException e) { 11390 dumpUid = -1; 11391 } 11392 } 11393 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11394 int uid = mGrantedUriPermissions.keyAt(i); 11395 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11396 continue; 11397 } 11398 ArrayMap<Uri, UriPermission> perms 11399 = mGrantedUriPermissions.valueAt(i); 11400 if (!printed) { 11401 if (needSep) pw.println(); 11402 needSep = true; 11403 pw.println(" Granted Uri Permissions:"); 11404 printed = true; 11405 printedAnything = true; 11406 } 11407 pw.print(" * UID "); pw.print(uid); 11408 pw.println(" holds:"); 11409 for (UriPermission perm : perms.values()) { 11410 pw.print(" "); pw.println(perm); 11411 if (dumpAll) { 11412 perm.dump(pw, " "); 11413 } 11414 } 11415 } 11416 } 11417 11418 if (!printedAnything) { 11419 pw.println(" (nothing)"); 11420 } 11421 } 11422 11423 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11424 int opti, boolean dumpAll, String dumpPackage) { 11425 boolean printed = false; 11426 11427 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11428 11429 if (mIntentSenderRecords.size() > 0) { 11430 Iterator<WeakReference<PendingIntentRecord>> it 11431 = mIntentSenderRecords.values().iterator(); 11432 while (it.hasNext()) { 11433 WeakReference<PendingIntentRecord> ref = it.next(); 11434 PendingIntentRecord rec = ref != null ? ref.get(): null; 11435 if (dumpPackage != null && (rec == null 11436 || !dumpPackage.equals(rec.key.packageName))) { 11437 continue; 11438 } 11439 printed = true; 11440 if (rec != null) { 11441 pw.print(" * "); pw.println(rec); 11442 if (dumpAll) { 11443 rec.dump(pw, " "); 11444 } 11445 } else { 11446 pw.print(" * "); pw.println(ref); 11447 } 11448 } 11449 } 11450 11451 if (!printed) { 11452 pw.println(" (nothing)"); 11453 } 11454 } 11455 11456 private static final int dumpProcessList(PrintWriter pw, 11457 ActivityManagerService service, List list, 11458 String prefix, String normalLabel, String persistentLabel, 11459 String dumpPackage) { 11460 int numPers = 0; 11461 final int N = list.size()-1; 11462 for (int i=N; i>=0; i--) { 11463 ProcessRecord r = (ProcessRecord)list.get(i); 11464 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11465 continue; 11466 } 11467 pw.println(String.format("%s%s #%2d: %s", 11468 prefix, (r.persistent ? persistentLabel : normalLabel), 11469 i, r.toString())); 11470 if (r.persistent) { 11471 numPers++; 11472 } 11473 } 11474 return numPers; 11475 } 11476 11477 private static final boolean dumpProcessOomList(PrintWriter pw, 11478 ActivityManagerService service, List<ProcessRecord> origList, 11479 String prefix, String normalLabel, String persistentLabel, 11480 boolean inclDetails, String dumpPackage) { 11481 11482 ArrayList<Pair<ProcessRecord, Integer>> list 11483 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11484 for (int i=0; i<origList.size(); i++) { 11485 ProcessRecord r = origList.get(i); 11486 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11487 continue; 11488 } 11489 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11490 } 11491 11492 if (list.size() <= 0) { 11493 return false; 11494 } 11495 11496 Comparator<Pair<ProcessRecord, Integer>> comparator 11497 = new Comparator<Pair<ProcessRecord, Integer>>() { 11498 @Override 11499 public int compare(Pair<ProcessRecord, Integer> object1, 11500 Pair<ProcessRecord, Integer> object2) { 11501 if (object1.first.setAdj != object2.first.setAdj) { 11502 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11503 } 11504 if (object1.second.intValue() != object2.second.intValue()) { 11505 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11506 } 11507 return 0; 11508 } 11509 }; 11510 11511 Collections.sort(list, comparator); 11512 11513 final long curRealtime = SystemClock.elapsedRealtime(); 11514 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11515 final long curUptime = SystemClock.uptimeMillis(); 11516 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11517 11518 for (int i=list.size()-1; i>=0; i--) { 11519 ProcessRecord r = list.get(i).first; 11520 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11521 char schedGroup; 11522 switch (r.setSchedGroup) { 11523 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11524 schedGroup = 'B'; 11525 break; 11526 case Process.THREAD_GROUP_DEFAULT: 11527 schedGroup = 'F'; 11528 break; 11529 default: 11530 schedGroup = '?'; 11531 break; 11532 } 11533 char foreground; 11534 if (r.foregroundActivities) { 11535 foreground = 'A'; 11536 } else if (r.foregroundServices) { 11537 foreground = 'S'; 11538 } else { 11539 foreground = ' '; 11540 } 11541 String procState = ProcessList.makeProcStateString(r.curProcState); 11542 pw.print(prefix); 11543 pw.print(r.persistent ? persistentLabel : normalLabel); 11544 pw.print(" #"); 11545 int num = (origList.size()-1)-list.get(i).second; 11546 if (num < 10) pw.print(' '); 11547 pw.print(num); 11548 pw.print(": "); 11549 pw.print(oomAdj); 11550 pw.print(' '); 11551 pw.print(schedGroup); 11552 pw.print('/'); 11553 pw.print(foreground); 11554 pw.print('/'); 11555 pw.print(procState); 11556 pw.print(" trm:"); 11557 if (r.trimMemoryLevel < 10) pw.print(' '); 11558 pw.print(r.trimMemoryLevel); 11559 pw.print(' '); 11560 pw.print(r.toShortString()); 11561 pw.print(" ("); 11562 pw.print(r.adjType); 11563 pw.println(')'); 11564 if (r.adjSource != null || r.adjTarget != null) { 11565 pw.print(prefix); 11566 pw.print(" "); 11567 if (r.adjTarget instanceof ComponentName) { 11568 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11569 } else if (r.adjTarget != null) { 11570 pw.print(r.adjTarget.toString()); 11571 } else { 11572 pw.print("{null}"); 11573 } 11574 pw.print("<="); 11575 if (r.adjSource instanceof ProcessRecord) { 11576 pw.print("Proc{"); 11577 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11578 pw.println("}"); 11579 } else if (r.adjSource != null) { 11580 pw.println(r.adjSource.toString()); 11581 } else { 11582 pw.println("{null}"); 11583 } 11584 } 11585 if (inclDetails) { 11586 pw.print(prefix); 11587 pw.print(" "); 11588 pw.print("oom: max="); pw.print(r.maxAdj); 11589 pw.print(" curRaw="); pw.print(r.curRawAdj); 11590 pw.print(" setRaw="); pw.print(r.setRawAdj); 11591 pw.print(" cur="); pw.print(r.curAdj); 11592 pw.print(" set="); pw.println(r.setAdj); 11593 pw.print(prefix); 11594 pw.print(" "); 11595 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11596 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11597 pw.print(" lastPss="); pw.print(r.lastPss); 11598 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11599 pw.print(prefix); 11600 pw.print(" "); 11601 pw.print("keeping="); pw.print(r.keeping); 11602 pw.print(" cached="); pw.print(r.cached); 11603 pw.print(" empty="); pw.print(r.empty); 11604 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11605 11606 if (!r.keeping) { 11607 if (r.lastWakeTime != 0) { 11608 long wtime; 11609 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11610 synchronized (stats) { 11611 wtime = stats.getProcessWakeTime(r.info.uid, 11612 r.pid, curRealtime); 11613 } 11614 long timeUsed = wtime - r.lastWakeTime; 11615 pw.print(prefix); 11616 pw.print(" "); 11617 pw.print("keep awake over "); 11618 TimeUtils.formatDuration(realtimeSince, pw); 11619 pw.print(" used "); 11620 TimeUtils.formatDuration(timeUsed, pw); 11621 pw.print(" ("); 11622 pw.print((timeUsed*100)/realtimeSince); 11623 pw.println("%)"); 11624 } 11625 if (r.lastCpuTime != 0) { 11626 long timeUsed = r.curCpuTime - r.lastCpuTime; 11627 pw.print(prefix); 11628 pw.print(" "); 11629 pw.print("run cpu over "); 11630 TimeUtils.formatDuration(uptimeSince, pw); 11631 pw.print(" used "); 11632 TimeUtils.formatDuration(timeUsed, pw); 11633 pw.print(" ("); 11634 pw.print((timeUsed*100)/uptimeSince); 11635 pw.println("%)"); 11636 } 11637 } 11638 } 11639 } 11640 return true; 11641 } 11642 11643 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11644 ArrayList<ProcessRecord> procs; 11645 synchronized (this) { 11646 if (args != null && args.length > start 11647 && args[start].charAt(0) != '-') { 11648 procs = new ArrayList<ProcessRecord>(); 11649 int pid = -1; 11650 try { 11651 pid = Integer.parseInt(args[start]); 11652 } catch (NumberFormatException e) { 11653 } 11654 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11655 ProcessRecord proc = mLruProcesses.get(i); 11656 if (proc.pid == pid) { 11657 procs.add(proc); 11658 } else if (proc.processName.equals(args[start])) { 11659 procs.add(proc); 11660 } 11661 } 11662 if (procs.size() <= 0) { 11663 return null; 11664 } 11665 } else { 11666 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11667 } 11668 } 11669 return procs; 11670 } 11671 11672 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11673 PrintWriter pw, String[] args) { 11674 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11675 if (procs == null) { 11676 pw.println("No process found for: " + args[0]); 11677 return; 11678 } 11679 11680 long uptime = SystemClock.uptimeMillis(); 11681 long realtime = SystemClock.elapsedRealtime(); 11682 pw.println("Applications Graphics Acceleration Info:"); 11683 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11684 11685 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11686 ProcessRecord r = procs.get(i); 11687 if (r.thread != null) { 11688 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11689 pw.flush(); 11690 try { 11691 TransferPipe tp = new TransferPipe(); 11692 try { 11693 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11694 tp.go(fd); 11695 } finally { 11696 tp.kill(); 11697 } 11698 } catch (IOException e) { 11699 pw.println("Failure while dumping the app: " + r); 11700 pw.flush(); 11701 } catch (RemoteException e) { 11702 pw.println("Got a RemoteException while dumping the app " + r); 11703 pw.flush(); 11704 } 11705 } 11706 } 11707 } 11708 11709 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11710 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11711 if (procs == null) { 11712 pw.println("No process found for: " + args[0]); 11713 return; 11714 } 11715 11716 pw.println("Applications Database Info:"); 11717 11718 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11719 ProcessRecord r = procs.get(i); 11720 if (r.thread != null) { 11721 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11722 pw.flush(); 11723 try { 11724 TransferPipe tp = new TransferPipe(); 11725 try { 11726 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11727 tp.go(fd); 11728 } finally { 11729 tp.kill(); 11730 } 11731 } catch (IOException e) { 11732 pw.println("Failure while dumping the app: " + r); 11733 pw.flush(); 11734 } catch (RemoteException e) { 11735 pw.println("Got a RemoteException while dumping the app " + r); 11736 pw.flush(); 11737 } 11738 } 11739 } 11740 } 11741 11742 final static class MemItem { 11743 final boolean isProc; 11744 final String label; 11745 final String shortLabel; 11746 final long pss; 11747 final int id; 11748 final boolean hasActivities; 11749 ArrayList<MemItem> subitems; 11750 11751 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11752 boolean _hasActivities) { 11753 isProc = true; 11754 label = _label; 11755 shortLabel = _shortLabel; 11756 pss = _pss; 11757 id = _id; 11758 hasActivities = _hasActivities; 11759 } 11760 11761 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11762 isProc = false; 11763 label = _label; 11764 shortLabel = _shortLabel; 11765 pss = _pss; 11766 id = _id; 11767 hasActivities = false; 11768 } 11769 } 11770 11771 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11772 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11773 if (sort && !isCompact) { 11774 Collections.sort(items, new Comparator<MemItem>() { 11775 @Override 11776 public int compare(MemItem lhs, MemItem rhs) { 11777 if (lhs.pss < rhs.pss) { 11778 return 1; 11779 } else if (lhs.pss > rhs.pss) { 11780 return -1; 11781 } 11782 return 0; 11783 } 11784 }); 11785 } 11786 11787 for (int i=0; i<items.size(); i++) { 11788 MemItem mi = items.get(i); 11789 if (!isCompact) { 11790 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11791 } else if (mi.isProc) { 11792 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11793 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11794 pw.println(mi.hasActivities ? ",a" : ",e"); 11795 } else { 11796 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11797 pw.println(mi.pss); 11798 } 11799 if (mi.subitems != null) { 11800 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11801 true, isCompact); 11802 } 11803 } 11804 } 11805 11806 // These are in KB. 11807 static final long[] DUMP_MEM_BUCKETS = new long[] { 11808 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11809 120*1024, 160*1024, 200*1024, 11810 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11811 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11812 }; 11813 11814 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11815 boolean stackLike) { 11816 int start = label.lastIndexOf('.'); 11817 if (start >= 0) start++; 11818 else start = 0; 11819 int end = label.length(); 11820 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11821 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11822 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11823 out.append(bucket); 11824 out.append(stackLike ? "MB." : "MB "); 11825 out.append(label, start, end); 11826 return; 11827 } 11828 } 11829 out.append(memKB/1024); 11830 out.append(stackLike ? "MB." : "MB "); 11831 out.append(label, start, end); 11832 } 11833 11834 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11835 ProcessList.NATIVE_ADJ, 11836 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11837 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11838 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11839 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11840 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11841 }; 11842 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11843 "Native", 11844 "System", "Persistent", "Foreground", 11845 "Visible", "Perceptible", 11846 "Heavy Weight", "Backup", 11847 "A Services", "Home", 11848 "Previous", "B Services", "Cached" 11849 }; 11850 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 11851 "native", 11852 "sys", "pers", "fore", 11853 "vis", "percept", 11854 "heavy", "backup", 11855 "servicea", "home", 11856 "prev", "serviceb", "cached" 11857 }; 11858 11859 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 11860 long realtime, boolean isCheckinRequest, boolean isCompact) { 11861 if (isCheckinRequest || isCompact) { 11862 // short checkin version 11863 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 11864 } else { 11865 pw.println("Applications Memory Usage (kB):"); 11866 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11867 } 11868 } 11869 11870 final void dumpApplicationMemoryUsage(FileDescriptor fd, 11871 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 11872 boolean dumpDetails = false; 11873 boolean dumpFullDetails = false; 11874 boolean dumpDalvik = false; 11875 boolean oomOnly = false; 11876 boolean isCompact = false; 11877 boolean localOnly = false; 11878 11879 int opti = 0; 11880 while (opti < args.length) { 11881 String opt = args[opti]; 11882 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11883 break; 11884 } 11885 opti++; 11886 if ("-a".equals(opt)) { 11887 dumpDetails = true; 11888 dumpFullDetails = true; 11889 dumpDalvik = true; 11890 } else if ("-d".equals(opt)) { 11891 dumpDalvik = true; 11892 } else if ("-c".equals(opt)) { 11893 isCompact = true; 11894 } else if ("--oom".equals(opt)) { 11895 oomOnly = true; 11896 } else if ("--local".equals(opt)) { 11897 localOnly = true; 11898 } else if ("-h".equals(opt)) { 11899 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 11900 pw.println(" -a: include all available information for each process."); 11901 pw.println(" -d: include dalvik details when dumping process details."); 11902 pw.println(" -c: dump in a compact machine-parseable representation."); 11903 pw.println(" --oom: only show processes organized by oom adj."); 11904 pw.println(" --local: only collect details locally, don't call process."); 11905 pw.println("If [process] is specified it can be the name or "); 11906 pw.println("pid of a specific process to dump."); 11907 return; 11908 } else { 11909 pw.println("Unknown argument: " + opt + "; use -h for help"); 11910 } 11911 } 11912 11913 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 11914 long uptime = SystemClock.uptimeMillis(); 11915 long realtime = SystemClock.elapsedRealtime(); 11916 final long[] tmpLong = new long[1]; 11917 11918 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 11919 if (procs == null) { 11920 // No Java processes. Maybe they want to print a native process. 11921 if (args != null && args.length > opti 11922 && args[opti].charAt(0) != '-') { 11923 ArrayList<ProcessCpuTracker.Stats> nativeProcs 11924 = new ArrayList<ProcessCpuTracker.Stats>(); 11925 updateCpuStatsNow(); 11926 int findPid = -1; 11927 try { 11928 findPid = Integer.parseInt(args[opti]); 11929 } catch (NumberFormatException e) { 11930 } 11931 synchronized (mProcessCpuThread) { 11932 final int N = mProcessCpuTracker.countStats(); 11933 for (int i=0; i<N; i++) { 11934 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 11935 if (st.pid == findPid || (st.baseName != null 11936 && st.baseName.equals(args[opti]))) { 11937 nativeProcs.add(st); 11938 } 11939 } 11940 } 11941 if (nativeProcs.size() > 0) { 11942 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 11943 isCompact); 11944 Debug.MemoryInfo mi = null; 11945 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 11946 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 11947 final int pid = r.pid; 11948 if (!isCheckinRequest && dumpDetails) { 11949 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 11950 } 11951 if (mi == null) { 11952 mi = new Debug.MemoryInfo(); 11953 } 11954 if (dumpDetails || (!brief && !oomOnly)) { 11955 Debug.getMemoryInfo(pid, mi); 11956 } else { 11957 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11958 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11959 } 11960 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11961 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 11962 if (isCheckinRequest) { 11963 pw.println(); 11964 } 11965 } 11966 return; 11967 } 11968 } 11969 pw.println("No process found for: " + args[opti]); 11970 return; 11971 } 11972 11973 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 11974 dumpDetails = true; 11975 } 11976 11977 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 11978 11979 String[] innerArgs = new String[args.length-opti]; 11980 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 11981 11982 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 11983 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 11984 long nativePss=0, dalvikPss=0, otherPss=0; 11985 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 11986 11987 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 11988 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 11989 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 11990 11991 long totalPss = 0; 11992 long cachedPss = 0; 11993 11994 Debug.MemoryInfo mi = null; 11995 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11996 final ProcessRecord r = procs.get(i); 11997 final IApplicationThread thread; 11998 final int pid; 11999 final int oomAdj; 12000 final boolean hasActivities; 12001 synchronized (this) { 12002 thread = r.thread; 12003 pid = r.pid; 12004 oomAdj = r.getSetAdjWithServices(); 12005 hasActivities = r.activities.size() > 0; 12006 } 12007 if (thread != null) { 12008 if (!isCheckinRequest && dumpDetails) { 12009 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12010 } 12011 if (mi == null) { 12012 mi = new Debug.MemoryInfo(); 12013 } 12014 if (dumpDetails || (!brief && !oomOnly)) { 12015 Debug.getMemoryInfo(pid, mi); 12016 } else { 12017 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12018 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12019 } 12020 if (dumpDetails) { 12021 if (localOnly) { 12022 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12023 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12024 if (isCheckinRequest) { 12025 pw.println(); 12026 } 12027 } else { 12028 try { 12029 pw.flush(); 12030 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12031 dumpDalvik, innerArgs); 12032 } catch (RemoteException e) { 12033 if (!isCheckinRequest) { 12034 pw.println("Got RemoteException!"); 12035 pw.flush(); 12036 } 12037 } 12038 } 12039 } 12040 12041 final long myTotalPss = mi.getTotalPss(); 12042 final long myTotalUss = mi.getTotalUss(); 12043 12044 synchronized (this) { 12045 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12046 // Record this for posterity if the process has been stable. 12047 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12048 } 12049 } 12050 12051 if (!isCheckinRequest && mi != null) { 12052 totalPss += myTotalPss; 12053 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12054 (hasActivities ? " / activities)" : ")"), 12055 r.processName, myTotalPss, pid, hasActivities); 12056 procMems.add(pssItem); 12057 procMemsMap.put(pid, pssItem); 12058 12059 nativePss += mi.nativePss; 12060 dalvikPss += mi.dalvikPss; 12061 otherPss += mi.otherPss; 12062 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12063 long mem = mi.getOtherPss(j); 12064 miscPss[j] += mem; 12065 otherPss -= mem; 12066 } 12067 12068 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12069 cachedPss += myTotalPss; 12070 } 12071 12072 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12073 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12074 || oomIndex == (oomPss.length-1)) { 12075 oomPss[oomIndex] += myTotalPss; 12076 if (oomProcs[oomIndex] == null) { 12077 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12078 } 12079 oomProcs[oomIndex].add(pssItem); 12080 break; 12081 } 12082 } 12083 } 12084 } 12085 } 12086 12087 if (!isCheckinRequest && procs.size() > 1) { 12088 // If we are showing aggregations, also look for native processes to 12089 // include so that our aggregations are more accurate. 12090 updateCpuStatsNow(); 12091 synchronized (mProcessCpuThread) { 12092 final int N = mProcessCpuTracker.countStats(); 12093 for (int i=0; i<N; i++) { 12094 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12095 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12096 if (mi == null) { 12097 mi = new Debug.MemoryInfo(); 12098 } 12099 if (!brief && !oomOnly) { 12100 Debug.getMemoryInfo(st.pid, mi); 12101 } else { 12102 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12103 mi.nativePrivateDirty = (int)tmpLong[0]; 12104 } 12105 12106 final long myTotalPss = mi.getTotalPss(); 12107 totalPss += myTotalPss; 12108 12109 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12110 st.name, myTotalPss, st.pid, false); 12111 procMems.add(pssItem); 12112 12113 nativePss += mi.nativePss; 12114 dalvikPss += mi.dalvikPss; 12115 otherPss += mi.otherPss; 12116 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12117 long mem = mi.getOtherPss(j); 12118 miscPss[j] += mem; 12119 otherPss -= mem; 12120 } 12121 oomPss[0] += myTotalPss; 12122 if (oomProcs[0] == null) { 12123 oomProcs[0] = new ArrayList<MemItem>(); 12124 } 12125 oomProcs[0].add(pssItem); 12126 } 12127 } 12128 } 12129 12130 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12131 12132 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12133 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12134 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12135 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12136 String label = Debug.MemoryInfo.getOtherLabel(j); 12137 catMems.add(new MemItem(label, label, miscPss[j], j)); 12138 } 12139 12140 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12141 for (int j=0; j<oomPss.length; j++) { 12142 if (oomPss[j] != 0) { 12143 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12144 : DUMP_MEM_OOM_LABEL[j]; 12145 MemItem item = new MemItem(label, label, oomPss[j], 12146 DUMP_MEM_OOM_ADJ[j]); 12147 item.subitems = oomProcs[j]; 12148 oomMems.add(item); 12149 } 12150 } 12151 12152 if (!brief && !oomOnly && !isCompact) { 12153 pw.println(); 12154 pw.println("Total PSS by process:"); 12155 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12156 pw.println(); 12157 } 12158 if (!isCompact) { 12159 pw.println("Total PSS by OOM adjustment:"); 12160 } 12161 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12162 if (!brief && !oomOnly) { 12163 PrintWriter out = categoryPw != null ? categoryPw : pw; 12164 if (!isCompact) { 12165 out.println(); 12166 out.println("Total PSS by category:"); 12167 } 12168 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12169 } 12170 if (!isCompact) { 12171 pw.println(); 12172 } 12173 MemInfoReader memInfo = new MemInfoReader(); 12174 memInfo.readMemInfo(); 12175 if (!brief) { 12176 if (!isCompact) { 12177 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12178 pw.print(" kB (status "); 12179 switch (mLastMemoryLevel) { 12180 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12181 pw.println("normal)"); 12182 break; 12183 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12184 pw.println("moderate)"); 12185 break; 12186 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12187 pw.println("low)"); 12188 break; 12189 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12190 pw.println("critical)"); 12191 break; 12192 default: 12193 pw.print(mLastMemoryLevel); 12194 pw.println(")"); 12195 break; 12196 } 12197 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12198 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12199 pw.print(cachedPss); pw.print(" cached pss + "); 12200 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12201 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12202 } else { 12203 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12204 pw.print(cachedPss + memInfo.getCachedSizeKb() 12205 + memInfo.getFreeSizeKb()); pw.print(","); 12206 pw.println(totalPss - cachedPss); 12207 } 12208 } 12209 if (!isCompact) { 12210 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12211 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12212 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12213 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12214 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12215 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12216 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12217 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12218 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12219 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12220 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12221 } 12222 if (!brief) { 12223 if (memInfo.getZramTotalSizeKb() != 0) { 12224 if (!isCompact) { 12225 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12226 pw.print(" kB physical used for "); 12227 pw.print(memInfo.getSwapTotalSizeKb() 12228 - memInfo.getSwapFreeSizeKb()); 12229 pw.print(" kB in swap ("); 12230 pw.print(memInfo.getSwapTotalSizeKb()); 12231 pw.println(" kB total swap)"); 12232 } else { 12233 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12234 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12235 pw.println(memInfo.getSwapFreeSizeKb()); 12236 } 12237 } 12238 final int[] SINGLE_LONG_FORMAT = new int[] { 12239 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12240 }; 12241 long[] longOut = new long[1]; 12242 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12243 SINGLE_LONG_FORMAT, null, longOut, null); 12244 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12245 longOut[0] = 0; 12246 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12247 SINGLE_LONG_FORMAT, null, longOut, null); 12248 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12249 longOut[0] = 0; 12250 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12251 SINGLE_LONG_FORMAT, null, longOut, null); 12252 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12253 longOut[0] = 0; 12254 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12255 SINGLE_LONG_FORMAT, null, longOut, null); 12256 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12257 if (!isCompact) { 12258 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12259 pw.print(" KSM: "); pw.print(sharing); 12260 pw.print(" kB saved from shared "); 12261 pw.print(shared); pw.println(" kB"); 12262 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12263 pw.print(voltile); pw.println(" kB volatile"); 12264 } 12265 pw.print(" Tuning: "); 12266 pw.print(ActivityManager.staticGetMemoryClass()); 12267 pw.print(" (large "); 12268 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12269 pw.print("), oom "); 12270 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12271 pw.print(" kB"); 12272 pw.print(", restore limit "); 12273 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12274 pw.print(" kB"); 12275 if (ActivityManager.isLowRamDeviceStatic()) { 12276 pw.print(" (low-ram)"); 12277 } 12278 if (ActivityManager.isHighEndGfx()) { 12279 pw.print(" (high-end-gfx)"); 12280 } 12281 pw.println(); 12282 } else { 12283 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12284 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12285 pw.println(voltile); 12286 pw.print("tuning,"); 12287 pw.print(ActivityManager.staticGetMemoryClass()); 12288 pw.print(','); 12289 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12290 pw.print(','); 12291 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12292 if (ActivityManager.isLowRamDeviceStatic()) { 12293 pw.print(",low-ram"); 12294 } 12295 if (ActivityManager.isHighEndGfx()) { 12296 pw.print(",high-end-gfx"); 12297 } 12298 pw.println(); 12299 } 12300 } 12301 } 12302 } 12303 12304 /** 12305 * Searches array of arguments for the specified string 12306 * @param args array of argument strings 12307 * @param value value to search for 12308 * @return true if the value is contained in the array 12309 */ 12310 private static boolean scanArgs(String[] args, String value) { 12311 if (args != null) { 12312 for (String arg : args) { 12313 if (value.equals(arg)) { 12314 return true; 12315 } 12316 } 12317 } 12318 return false; 12319 } 12320 12321 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12322 ContentProviderRecord cpr, boolean always) { 12323 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12324 12325 if (!inLaunching || always) { 12326 synchronized (cpr) { 12327 cpr.launchingApp = null; 12328 cpr.notifyAll(); 12329 } 12330 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12331 String names[] = cpr.info.authority.split(";"); 12332 for (int j = 0; j < names.length; j++) { 12333 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12334 } 12335 } 12336 12337 for (int i=0; i<cpr.connections.size(); i++) { 12338 ContentProviderConnection conn = cpr.connections.get(i); 12339 if (conn.waiting) { 12340 // If this connection is waiting for the provider, then we don't 12341 // need to mess with its process unless we are always removing 12342 // or for some reason the provider is not currently launching. 12343 if (inLaunching && !always) { 12344 continue; 12345 } 12346 } 12347 ProcessRecord capp = conn.client; 12348 conn.dead = true; 12349 if (conn.stableCount > 0) { 12350 if (!capp.persistent && capp.thread != null 12351 && capp.pid != 0 12352 && capp.pid != MY_PID) { 12353 killUnneededProcessLocked(capp, "depends on provider " 12354 + cpr.name.flattenToShortString() 12355 + " in dying proc " + (proc != null ? proc.processName : "??")); 12356 } 12357 } else if (capp.thread != null && conn.provider.provider != null) { 12358 try { 12359 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12360 } catch (RemoteException e) { 12361 } 12362 // In the protocol here, we don't expect the client to correctly 12363 // clean up this connection, we'll just remove it. 12364 cpr.connections.remove(i); 12365 conn.client.conProviders.remove(conn); 12366 } 12367 } 12368 12369 if (inLaunching && always) { 12370 mLaunchingProviders.remove(cpr); 12371 } 12372 return inLaunching; 12373 } 12374 12375 /** 12376 * Main code for cleaning up a process when it has gone away. This is 12377 * called both as a result of the process dying, or directly when stopping 12378 * a process when running in single process mode. 12379 */ 12380 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12381 boolean restarting, boolean allowRestart, int index) { 12382 if (index >= 0) { 12383 removeLruProcessLocked(app); 12384 ProcessList.remove(app.pid); 12385 } 12386 12387 mProcessesToGc.remove(app); 12388 mPendingPssProcesses.remove(app); 12389 12390 // Dismiss any open dialogs. 12391 if (app.crashDialog != null && !app.forceCrashReport) { 12392 app.crashDialog.dismiss(); 12393 app.crashDialog = null; 12394 } 12395 if (app.anrDialog != null) { 12396 app.anrDialog.dismiss(); 12397 app.anrDialog = null; 12398 } 12399 if (app.waitDialog != null) { 12400 app.waitDialog.dismiss(); 12401 app.waitDialog = null; 12402 } 12403 12404 app.crashing = false; 12405 app.notResponding = false; 12406 12407 app.resetPackageList(mProcessStats); 12408 app.unlinkDeathRecipient(); 12409 app.makeInactive(mProcessStats); 12410 app.forcingToForeground = null; 12411 updateProcessForegroundLocked(app, false, false); 12412 app.foregroundActivities = false; 12413 app.hasShownUi = false; 12414 app.hasAboveClient = false; 12415 12416 mServices.killServicesLocked(app, allowRestart); 12417 12418 boolean restart = false; 12419 12420 // Remove published content providers. 12421 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12422 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12423 final boolean always = app.bad || !allowRestart; 12424 if (removeDyingProviderLocked(app, cpr, always) || always) { 12425 // We left the provider in the launching list, need to 12426 // restart it. 12427 restart = true; 12428 } 12429 12430 cpr.provider = null; 12431 cpr.proc = null; 12432 } 12433 app.pubProviders.clear(); 12434 12435 // Take care of any launching providers waiting for this process. 12436 if (checkAppInLaunchingProvidersLocked(app, false)) { 12437 restart = true; 12438 } 12439 12440 // Unregister from connected content providers. 12441 if (!app.conProviders.isEmpty()) { 12442 for (int i=0; i<app.conProviders.size(); i++) { 12443 ContentProviderConnection conn = app.conProviders.get(i); 12444 conn.provider.connections.remove(conn); 12445 } 12446 app.conProviders.clear(); 12447 } 12448 12449 // At this point there may be remaining entries in mLaunchingProviders 12450 // where we were the only one waiting, so they are no longer of use. 12451 // Look for these and clean up if found. 12452 // XXX Commented out for now. Trying to figure out a way to reproduce 12453 // the actual situation to identify what is actually going on. 12454 if (false) { 12455 for (int i=0; i<mLaunchingProviders.size(); i++) { 12456 ContentProviderRecord cpr = (ContentProviderRecord) 12457 mLaunchingProviders.get(i); 12458 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12459 synchronized (cpr) { 12460 cpr.launchingApp = null; 12461 cpr.notifyAll(); 12462 } 12463 } 12464 } 12465 } 12466 12467 skipCurrentReceiverLocked(app); 12468 12469 // Unregister any receivers. 12470 for (int i=app.receivers.size()-1; i>=0; i--) { 12471 removeReceiverLocked(app.receivers.valueAt(i)); 12472 } 12473 app.receivers.clear(); 12474 12475 // If the app is undergoing backup, tell the backup manager about it 12476 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12477 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12478 + mBackupTarget.appInfo + " died during backup"); 12479 try { 12480 IBackupManager bm = IBackupManager.Stub.asInterface( 12481 ServiceManager.getService(Context.BACKUP_SERVICE)); 12482 bm.agentDisconnected(app.info.packageName); 12483 } catch (RemoteException e) { 12484 // can't happen; backup manager is local 12485 } 12486 } 12487 12488 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12489 ProcessChangeItem item = mPendingProcessChanges.get(i); 12490 if (item.pid == app.pid) { 12491 mPendingProcessChanges.remove(i); 12492 mAvailProcessChanges.add(item); 12493 } 12494 } 12495 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12496 12497 // If the caller is restarting this app, then leave it in its 12498 // current lists and let the caller take care of it. 12499 if (restarting) { 12500 return; 12501 } 12502 12503 if (!app.persistent || app.isolated) { 12504 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12505 "Removing non-persistent process during cleanup: " + app); 12506 mProcessNames.remove(app.processName, app.uid); 12507 mIsolatedProcesses.remove(app.uid); 12508 if (mHeavyWeightProcess == app) { 12509 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12510 mHeavyWeightProcess.userId, 0)); 12511 mHeavyWeightProcess = null; 12512 } 12513 } else if (!app.removed) { 12514 // This app is persistent, so we need to keep its record around. 12515 // If it is not already on the pending app list, add it there 12516 // and start a new process for it. 12517 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12518 mPersistentStartingProcesses.add(app); 12519 restart = true; 12520 } 12521 } 12522 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12523 "Clean-up removing on hold: " + app); 12524 mProcessesOnHold.remove(app); 12525 12526 if (app == mHomeProcess) { 12527 mHomeProcess = null; 12528 } 12529 if (app == mPreviousProcess) { 12530 mPreviousProcess = null; 12531 } 12532 12533 if (restart && !app.isolated) { 12534 // We have components that still need to be running in the 12535 // process, so re-launch it. 12536 mProcessNames.put(app.processName, app.uid, app); 12537 startProcessLocked(app, "restart", app.processName); 12538 } else if (app.pid > 0 && app.pid != MY_PID) { 12539 // Goodbye! 12540 boolean removed; 12541 synchronized (mPidsSelfLocked) { 12542 mPidsSelfLocked.remove(app.pid); 12543 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12544 } 12545 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12546 app.processName, app.info.uid); 12547 if (app.isolated) { 12548 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12549 } 12550 app.setPid(0); 12551 } 12552 } 12553 12554 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12555 // Look through the content providers we are waiting to have launched, 12556 // and if any run in this process then either schedule a restart of 12557 // the process or kill the client waiting for it if this process has 12558 // gone bad. 12559 int NL = mLaunchingProviders.size(); 12560 boolean restart = false; 12561 for (int i=0; i<NL; i++) { 12562 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12563 if (cpr.launchingApp == app) { 12564 if (!alwaysBad && !app.bad) { 12565 restart = true; 12566 } else { 12567 removeDyingProviderLocked(app, cpr, true); 12568 // cpr should have been removed from mLaunchingProviders 12569 NL = mLaunchingProviders.size(); 12570 i--; 12571 } 12572 } 12573 } 12574 return restart; 12575 } 12576 12577 // ========================================================= 12578 // SERVICES 12579 // ========================================================= 12580 12581 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12582 int flags) { 12583 enforceNotIsolatedCaller("getServices"); 12584 synchronized (this) { 12585 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12586 } 12587 } 12588 12589 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12590 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12591 synchronized (this) { 12592 return mServices.getRunningServiceControlPanelLocked(name); 12593 } 12594 } 12595 12596 public ComponentName startService(IApplicationThread caller, Intent service, 12597 String resolvedType, int userId) { 12598 enforceNotIsolatedCaller("startService"); 12599 // Refuse possible leaked file descriptors 12600 if (service != null && service.hasFileDescriptors() == true) { 12601 throw new IllegalArgumentException("File descriptors passed in Intent"); 12602 } 12603 12604 if (DEBUG_SERVICE) 12605 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12606 synchronized(this) { 12607 final int callingPid = Binder.getCallingPid(); 12608 final int callingUid = Binder.getCallingUid(); 12609 final long origId = Binder.clearCallingIdentity(); 12610 ComponentName res = mServices.startServiceLocked(caller, service, 12611 resolvedType, callingPid, callingUid, userId); 12612 Binder.restoreCallingIdentity(origId); 12613 return res; 12614 } 12615 } 12616 12617 ComponentName startServiceInPackage(int uid, 12618 Intent service, String resolvedType, int userId) { 12619 synchronized(this) { 12620 if (DEBUG_SERVICE) 12621 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12622 final long origId = Binder.clearCallingIdentity(); 12623 ComponentName res = mServices.startServiceLocked(null, service, 12624 resolvedType, -1, uid, userId); 12625 Binder.restoreCallingIdentity(origId); 12626 return res; 12627 } 12628 } 12629 12630 public int stopService(IApplicationThread caller, Intent service, 12631 String resolvedType, int userId) { 12632 enforceNotIsolatedCaller("stopService"); 12633 // Refuse possible leaked file descriptors 12634 if (service != null && service.hasFileDescriptors() == true) { 12635 throw new IllegalArgumentException("File descriptors passed in Intent"); 12636 } 12637 12638 synchronized(this) { 12639 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12640 } 12641 } 12642 12643 public IBinder peekService(Intent service, String resolvedType) { 12644 enforceNotIsolatedCaller("peekService"); 12645 // Refuse possible leaked file descriptors 12646 if (service != null && service.hasFileDescriptors() == true) { 12647 throw new IllegalArgumentException("File descriptors passed in Intent"); 12648 } 12649 synchronized(this) { 12650 return mServices.peekServiceLocked(service, resolvedType); 12651 } 12652 } 12653 12654 public boolean stopServiceToken(ComponentName className, IBinder token, 12655 int startId) { 12656 synchronized(this) { 12657 return mServices.stopServiceTokenLocked(className, token, startId); 12658 } 12659 } 12660 12661 public void setServiceForeground(ComponentName className, IBinder token, 12662 int id, Notification notification, boolean removeNotification) { 12663 synchronized(this) { 12664 mServices.setServiceForegroundLocked(className, token, id, notification, 12665 removeNotification); 12666 } 12667 } 12668 12669 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12670 boolean requireFull, String name, String callerPackage) { 12671 final int callingUserId = UserHandle.getUserId(callingUid); 12672 if (callingUserId != userId) { 12673 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12674 if ((requireFull || checkComponentPermission( 12675 android.Manifest.permission.INTERACT_ACROSS_USERS, 12676 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12677 && checkComponentPermission( 12678 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12679 callingPid, callingUid, -1, true) 12680 != PackageManager.PERMISSION_GRANTED) { 12681 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12682 // In this case, they would like to just execute as their 12683 // owner user instead of failing. 12684 userId = callingUserId; 12685 } else { 12686 StringBuilder builder = new StringBuilder(128); 12687 builder.append("Permission Denial: "); 12688 builder.append(name); 12689 if (callerPackage != null) { 12690 builder.append(" from "); 12691 builder.append(callerPackage); 12692 } 12693 builder.append(" asks to run as user "); 12694 builder.append(userId); 12695 builder.append(" but is calling from user "); 12696 builder.append(UserHandle.getUserId(callingUid)); 12697 builder.append("; this requires "); 12698 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12699 if (!requireFull) { 12700 builder.append(" or "); 12701 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12702 } 12703 String msg = builder.toString(); 12704 Slog.w(TAG, msg); 12705 throw new SecurityException(msg); 12706 } 12707 } 12708 } 12709 if (userId == UserHandle.USER_CURRENT 12710 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12711 // Note that we may be accessing this outside of a lock... 12712 // shouldn't be a big deal, if this is being called outside 12713 // of a locked context there is intrinsically a race with 12714 // the value the caller will receive and someone else changing it. 12715 userId = mCurrentUserId; 12716 } 12717 if (!allowAll && userId < 0) { 12718 throw new IllegalArgumentException( 12719 "Call does not support special user #" + userId); 12720 } 12721 } 12722 return userId; 12723 } 12724 12725 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12726 String className, int flags) { 12727 boolean result = false; 12728 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12729 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12730 if (ActivityManager.checkUidPermission( 12731 android.Manifest.permission.INTERACT_ACROSS_USERS, 12732 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12733 ComponentName comp = new ComponentName(aInfo.packageName, className); 12734 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12735 + " requests FLAG_SINGLE_USER, but app does not hold " 12736 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12737 Slog.w(TAG, msg); 12738 throw new SecurityException(msg); 12739 } 12740 result = true; 12741 } 12742 } else if (componentProcessName == aInfo.packageName) { 12743 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12744 } else if ("system".equals(componentProcessName)) { 12745 result = true; 12746 } 12747 if (DEBUG_MU) { 12748 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12749 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12750 } 12751 return result; 12752 } 12753 12754 public int bindService(IApplicationThread caller, IBinder token, 12755 Intent service, String resolvedType, 12756 IServiceConnection connection, int flags, int userId) { 12757 enforceNotIsolatedCaller("bindService"); 12758 // Refuse possible leaked file descriptors 12759 if (service != null && service.hasFileDescriptors() == true) { 12760 throw new IllegalArgumentException("File descriptors passed in Intent"); 12761 } 12762 12763 synchronized(this) { 12764 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12765 connection, flags, userId); 12766 } 12767 } 12768 12769 public boolean unbindService(IServiceConnection connection) { 12770 synchronized (this) { 12771 return mServices.unbindServiceLocked(connection); 12772 } 12773 } 12774 12775 public void publishService(IBinder token, Intent intent, IBinder service) { 12776 // Refuse possible leaked file descriptors 12777 if (intent != null && intent.hasFileDescriptors() == true) { 12778 throw new IllegalArgumentException("File descriptors passed in Intent"); 12779 } 12780 12781 synchronized(this) { 12782 if (!(token instanceof ServiceRecord)) { 12783 throw new IllegalArgumentException("Invalid service token"); 12784 } 12785 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12786 } 12787 } 12788 12789 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12790 // Refuse possible leaked file descriptors 12791 if (intent != null && intent.hasFileDescriptors() == true) { 12792 throw new IllegalArgumentException("File descriptors passed in Intent"); 12793 } 12794 12795 synchronized(this) { 12796 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12797 } 12798 } 12799 12800 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12801 synchronized(this) { 12802 if (!(token instanceof ServiceRecord)) { 12803 throw new IllegalArgumentException("Invalid service token"); 12804 } 12805 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12806 } 12807 } 12808 12809 // ========================================================= 12810 // BACKUP AND RESTORE 12811 // ========================================================= 12812 12813 // Cause the target app to be launched if necessary and its backup agent 12814 // instantiated. The backup agent will invoke backupAgentCreated() on the 12815 // activity manager to announce its creation. 12816 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12817 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12818 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12819 12820 synchronized(this) { 12821 // !!! TODO: currently no check here that we're already bound 12822 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12823 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12824 synchronized (stats) { 12825 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12826 } 12827 12828 // Backup agent is now in use, its package can't be stopped. 12829 try { 12830 AppGlobals.getPackageManager().setPackageStoppedState( 12831 app.packageName, false, UserHandle.getUserId(app.uid)); 12832 } catch (RemoteException e) { 12833 } catch (IllegalArgumentException e) { 12834 Slog.w(TAG, "Failed trying to unstop package " 12835 + app.packageName + ": " + e); 12836 } 12837 12838 BackupRecord r = new BackupRecord(ss, app, backupMode); 12839 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12840 ? new ComponentName(app.packageName, app.backupAgentName) 12841 : new ComponentName("android", "FullBackupAgent"); 12842 // startProcessLocked() returns existing proc's record if it's already running 12843 ProcessRecord proc = startProcessLocked(app.processName, app, 12844 false, 0, "backup", hostingName, false, false, false); 12845 if (proc == null) { 12846 Slog.e(TAG, "Unable to start backup agent process " + r); 12847 return false; 12848 } 12849 12850 r.app = proc; 12851 mBackupTarget = r; 12852 mBackupAppName = app.packageName; 12853 12854 // Try not to kill the process during backup 12855 updateOomAdjLocked(proc); 12856 12857 // If the process is already attached, schedule the creation of the backup agent now. 12858 // If it is not yet live, this will be done when it attaches to the framework. 12859 if (proc.thread != null) { 12860 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12861 try { 12862 proc.thread.scheduleCreateBackupAgent(app, 12863 compatibilityInfoForPackageLocked(app), backupMode); 12864 } catch (RemoteException e) { 12865 // Will time out on the backup manager side 12866 } 12867 } else { 12868 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12869 } 12870 // Invariants: at this point, the target app process exists and the application 12871 // is either already running or in the process of coming up. mBackupTarget and 12872 // mBackupAppName describe the app, so that when it binds back to the AM we 12873 // know that it's scheduled for a backup-agent operation. 12874 } 12875 12876 return true; 12877 } 12878 12879 @Override 12880 public void clearPendingBackup() { 12881 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 12882 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 12883 12884 synchronized (this) { 12885 mBackupTarget = null; 12886 mBackupAppName = null; 12887 } 12888 } 12889 12890 // A backup agent has just come up 12891 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12892 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12893 + " = " + agent); 12894 12895 synchronized(this) { 12896 if (!agentPackageName.equals(mBackupAppName)) { 12897 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12898 return; 12899 } 12900 } 12901 12902 long oldIdent = Binder.clearCallingIdentity(); 12903 try { 12904 IBackupManager bm = IBackupManager.Stub.asInterface( 12905 ServiceManager.getService(Context.BACKUP_SERVICE)); 12906 bm.agentConnected(agentPackageName, agent); 12907 } catch (RemoteException e) { 12908 // can't happen; the backup manager service is local 12909 } catch (Exception e) { 12910 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12911 e.printStackTrace(); 12912 } finally { 12913 Binder.restoreCallingIdentity(oldIdent); 12914 } 12915 } 12916 12917 // done with this agent 12918 public void unbindBackupAgent(ApplicationInfo appInfo) { 12919 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12920 if (appInfo == null) { 12921 Slog.w(TAG, "unbind backup agent for null app"); 12922 return; 12923 } 12924 12925 synchronized(this) { 12926 try { 12927 if (mBackupAppName == null) { 12928 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12929 return; 12930 } 12931 12932 if (!mBackupAppName.equals(appInfo.packageName)) { 12933 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12934 return; 12935 } 12936 12937 // Not backing this app up any more; reset its OOM adjustment 12938 final ProcessRecord proc = mBackupTarget.app; 12939 updateOomAdjLocked(proc); 12940 12941 // If the app crashed during backup, 'thread' will be null here 12942 if (proc.thread != null) { 12943 try { 12944 proc.thread.scheduleDestroyBackupAgent(appInfo, 12945 compatibilityInfoForPackageLocked(appInfo)); 12946 } catch (Exception e) { 12947 Slog.e(TAG, "Exception when unbinding backup agent:"); 12948 e.printStackTrace(); 12949 } 12950 } 12951 } finally { 12952 mBackupTarget = null; 12953 mBackupAppName = null; 12954 } 12955 } 12956 } 12957 // ========================================================= 12958 // BROADCASTS 12959 // ========================================================= 12960 12961 private final List getStickiesLocked(String action, IntentFilter filter, 12962 List cur, int userId) { 12963 final ContentResolver resolver = mContext.getContentResolver(); 12964 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12965 if (stickies == null) { 12966 return cur; 12967 } 12968 final ArrayList<Intent> list = stickies.get(action); 12969 if (list == null) { 12970 return cur; 12971 } 12972 int N = list.size(); 12973 for (int i=0; i<N; i++) { 12974 Intent intent = list.get(i); 12975 if (filter.match(resolver, intent, true, TAG) >= 0) { 12976 if (cur == null) { 12977 cur = new ArrayList<Intent>(); 12978 } 12979 cur.add(intent); 12980 } 12981 } 12982 return cur; 12983 } 12984 12985 boolean isPendingBroadcastProcessLocked(int pid) { 12986 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12987 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12988 } 12989 12990 void skipPendingBroadcastLocked(int pid) { 12991 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 12992 for (BroadcastQueue queue : mBroadcastQueues) { 12993 queue.skipPendingBroadcastLocked(pid); 12994 } 12995 } 12996 12997 // The app just attached; send any pending broadcasts that it should receive 12998 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 12999 boolean didSomething = false; 13000 for (BroadcastQueue queue : mBroadcastQueues) { 13001 didSomething |= queue.sendPendingBroadcastsLocked(app); 13002 } 13003 return didSomething; 13004 } 13005 13006 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13007 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13008 enforceNotIsolatedCaller("registerReceiver"); 13009 int callingUid; 13010 int callingPid; 13011 synchronized(this) { 13012 ProcessRecord callerApp = null; 13013 if (caller != null) { 13014 callerApp = getRecordForAppLocked(caller); 13015 if (callerApp == null) { 13016 throw new SecurityException( 13017 "Unable to find app for caller " + caller 13018 + " (pid=" + Binder.getCallingPid() 13019 + ") when registering receiver " + receiver); 13020 } 13021 if (callerApp.info.uid != Process.SYSTEM_UID && 13022 !callerApp.pkgList.containsKey(callerPackage) && 13023 !"android".equals(callerPackage)) { 13024 throw new SecurityException("Given caller package " + callerPackage 13025 + " is not running in process " + callerApp); 13026 } 13027 callingUid = callerApp.info.uid; 13028 callingPid = callerApp.pid; 13029 } else { 13030 callerPackage = null; 13031 callingUid = Binder.getCallingUid(); 13032 callingPid = Binder.getCallingPid(); 13033 } 13034 13035 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13036 true, true, "registerReceiver", callerPackage); 13037 13038 List allSticky = null; 13039 13040 // Look for any matching sticky broadcasts... 13041 Iterator actions = filter.actionsIterator(); 13042 if (actions != null) { 13043 while (actions.hasNext()) { 13044 String action = (String)actions.next(); 13045 allSticky = getStickiesLocked(action, filter, allSticky, 13046 UserHandle.USER_ALL); 13047 allSticky = getStickiesLocked(action, filter, allSticky, 13048 UserHandle.getUserId(callingUid)); 13049 } 13050 } else { 13051 allSticky = getStickiesLocked(null, filter, allSticky, 13052 UserHandle.USER_ALL); 13053 allSticky = getStickiesLocked(null, filter, allSticky, 13054 UserHandle.getUserId(callingUid)); 13055 } 13056 13057 // The first sticky in the list is returned directly back to 13058 // the client. 13059 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13060 13061 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13062 + ": " + sticky); 13063 13064 if (receiver == null) { 13065 return sticky; 13066 } 13067 13068 ReceiverList rl 13069 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13070 if (rl == null) { 13071 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13072 userId, receiver); 13073 if (rl.app != null) { 13074 rl.app.receivers.add(rl); 13075 } else { 13076 try { 13077 receiver.asBinder().linkToDeath(rl, 0); 13078 } catch (RemoteException e) { 13079 return sticky; 13080 } 13081 rl.linkedToDeath = true; 13082 } 13083 mRegisteredReceivers.put(receiver.asBinder(), rl); 13084 } else if (rl.uid != callingUid) { 13085 throw new IllegalArgumentException( 13086 "Receiver requested to register for uid " + callingUid 13087 + " was previously registered for uid " + rl.uid); 13088 } else if (rl.pid != callingPid) { 13089 throw new IllegalArgumentException( 13090 "Receiver requested to register for pid " + callingPid 13091 + " was previously registered for pid " + rl.pid); 13092 } else if (rl.userId != userId) { 13093 throw new IllegalArgumentException( 13094 "Receiver requested to register for user " + userId 13095 + " was previously registered for user " + rl.userId); 13096 } 13097 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13098 permission, callingUid, userId); 13099 rl.add(bf); 13100 if (!bf.debugCheck()) { 13101 Slog.w(TAG, "==> For Dynamic broadast"); 13102 } 13103 mReceiverResolver.addFilter(bf); 13104 13105 // Enqueue broadcasts for all existing stickies that match 13106 // this filter. 13107 if (allSticky != null) { 13108 ArrayList receivers = new ArrayList(); 13109 receivers.add(bf); 13110 13111 int N = allSticky.size(); 13112 for (int i=0; i<N; i++) { 13113 Intent intent = (Intent)allSticky.get(i); 13114 BroadcastQueue queue = broadcastQueueForIntent(intent); 13115 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13116 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13117 null, null, false, true, true, -1); 13118 queue.enqueueParallelBroadcastLocked(r); 13119 queue.scheduleBroadcastsLocked(); 13120 } 13121 } 13122 13123 return sticky; 13124 } 13125 } 13126 13127 public void unregisterReceiver(IIntentReceiver receiver) { 13128 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13129 13130 final long origId = Binder.clearCallingIdentity(); 13131 try { 13132 boolean doTrim = false; 13133 13134 synchronized(this) { 13135 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13136 if (rl != null) { 13137 if (rl.curBroadcast != null) { 13138 BroadcastRecord r = rl.curBroadcast; 13139 final boolean doNext = finishReceiverLocked( 13140 receiver.asBinder(), r.resultCode, r.resultData, 13141 r.resultExtras, r.resultAbort); 13142 if (doNext) { 13143 doTrim = true; 13144 r.queue.processNextBroadcast(false); 13145 } 13146 } 13147 13148 if (rl.app != null) { 13149 rl.app.receivers.remove(rl); 13150 } 13151 removeReceiverLocked(rl); 13152 if (rl.linkedToDeath) { 13153 rl.linkedToDeath = false; 13154 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13155 } 13156 } 13157 } 13158 13159 // If we actually concluded any broadcasts, we might now be able 13160 // to trim the recipients' apps from our working set 13161 if (doTrim) { 13162 trimApplications(); 13163 return; 13164 } 13165 13166 } finally { 13167 Binder.restoreCallingIdentity(origId); 13168 } 13169 } 13170 13171 void removeReceiverLocked(ReceiverList rl) { 13172 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13173 int N = rl.size(); 13174 for (int i=0; i<N; i++) { 13175 mReceiverResolver.removeFilter(rl.get(i)); 13176 } 13177 } 13178 13179 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13180 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13181 ProcessRecord r = mLruProcesses.get(i); 13182 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13183 try { 13184 r.thread.dispatchPackageBroadcast(cmd, packages); 13185 } catch (RemoteException ex) { 13186 } 13187 } 13188 } 13189 } 13190 13191 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13192 int[] users) { 13193 List<ResolveInfo> receivers = null; 13194 try { 13195 HashSet<ComponentName> singleUserReceivers = null; 13196 boolean scannedFirstReceivers = false; 13197 for (int user : users) { 13198 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13199 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13200 if (user != 0 && newReceivers != null) { 13201 // If this is not the primary user, we need to check for 13202 // any receivers that should be filtered out. 13203 for (int i=0; i<newReceivers.size(); i++) { 13204 ResolveInfo ri = newReceivers.get(i); 13205 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13206 newReceivers.remove(i); 13207 i--; 13208 } 13209 } 13210 } 13211 if (newReceivers != null && newReceivers.size() == 0) { 13212 newReceivers = null; 13213 } 13214 if (receivers == null) { 13215 receivers = newReceivers; 13216 } else if (newReceivers != null) { 13217 // We need to concatenate the additional receivers 13218 // found with what we have do far. This would be easy, 13219 // but we also need to de-dup any receivers that are 13220 // singleUser. 13221 if (!scannedFirstReceivers) { 13222 // Collect any single user receivers we had already retrieved. 13223 scannedFirstReceivers = true; 13224 for (int i=0; i<receivers.size(); i++) { 13225 ResolveInfo ri = receivers.get(i); 13226 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13227 ComponentName cn = new ComponentName( 13228 ri.activityInfo.packageName, ri.activityInfo.name); 13229 if (singleUserReceivers == null) { 13230 singleUserReceivers = new HashSet<ComponentName>(); 13231 } 13232 singleUserReceivers.add(cn); 13233 } 13234 } 13235 } 13236 // Add the new results to the existing results, tracking 13237 // and de-dupping single user receivers. 13238 for (int i=0; i<newReceivers.size(); i++) { 13239 ResolveInfo ri = newReceivers.get(i); 13240 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13241 ComponentName cn = new ComponentName( 13242 ri.activityInfo.packageName, ri.activityInfo.name); 13243 if (singleUserReceivers == null) { 13244 singleUserReceivers = new HashSet<ComponentName>(); 13245 } 13246 if (!singleUserReceivers.contains(cn)) { 13247 singleUserReceivers.add(cn); 13248 receivers.add(ri); 13249 } 13250 } else { 13251 receivers.add(ri); 13252 } 13253 } 13254 } 13255 } 13256 } catch (RemoteException ex) { 13257 // pm is in same process, this will never happen. 13258 } 13259 return receivers; 13260 } 13261 13262 private final int broadcastIntentLocked(ProcessRecord callerApp, 13263 String callerPackage, Intent intent, String resolvedType, 13264 IIntentReceiver resultTo, int resultCode, String resultData, 13265 Bundle map, String requiredPermission, int appOp, 13266 boolean ordered, boolean sticky, int callingPid, int callingUid, 13267 int userId) { 13268 intent = new Intent(intent); 13269 13270 // By default broadcasts do not go to stopped apps. 13271 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13272 13273 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13274 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13275 + " ordered=" + ordered + " userid=" + userId); 13276 if ((resultTo != null) && !ordered) { 13277 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13278 } 13279 13280 userId = handleIncomingUser(callingPid, callingUid, userId, 13281 true, false, "broadcast", callerPackage); 13282 13283 // Make sure that the user who is receiving this broadcast is started. 13284 // If not, we will just skip it. 13285 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13286 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13287 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13288 Slog.w(TAG, "Skipping broadcast of " + intent 13289 + ": user " + userId + " is stopped"); 13290 return ActivityManager.BROADCAST_SUCCESS; 13291 } 13292 } 13293 13294 /* 13295 * Prevent non-system code (defined here to be non-persistent 13296 * processes) from sending protected broadcasts. 13297 */ 13298 int callingAppId = UserHandle.getAppId(callingUid); 13299 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13300 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13301 callingUid == 0) { 13302 // Always okay. 13303 } else if (callerApp == null || !callerApp.persistent) { 13304 try { 13305 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13306 intent.getAction())) { 13307 String msg = "Permission Denial: not allowed to send broadcast " 13308 + intent.getAction() + " from pid=" 13309 + callingPid + ", uid=" + callingUid; 13310 Slog.w(TAG, msg); 13311 throw new SecurityException(msg); 13312 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13313 // Special case for compatibility: we don't want apps to send this, 13314 // but historically it has not been protected and apps may be using it 13315 // to poke their own app widget. So, instead of making it protected, 13316 // just limit it to the caller. 13317 if (callerApp == null) { 13318 String msg = "Permission Denial: not allowed to send broadcast " 13319 + intent.getAction() + " from unknown caller."; 13320 Slog.w(TAG, msg); 13321 throw new SecurityException(msg); 13322 } else if (intent.getComponent() != null) { 13323 // They are good enough to send to an explicit component... verify 13324 // it is being sent to the calling app. 13325 if (!intent.getComponent().getPackageName().equals( 13326 callerApp.info.packageName)) { 13327 String msg = "Permission Denial: not allowed to send broadcast " 13328 + intent.getAction() + " to " 13329 + intent.getComponent().getPackageName() + " from " 13330 + callerApp.info.packageName; 13331 Slog.w(TAG, msg); 13332 throw new SecurityException(msg); 13333 } 13334 } else { 13335 // Limit broadcast to their own package. 13336 intent.setPackage(callerApp.info.packageName); 13337 } 13338 } 13339 } catch (RemoteException e) { 13340 Slog.w(TAG, "Remote exception", e); 13341 return ActivityManager.BROADCAST_SUCCESS; 13342 } 13343 } 13344 13345 // Handle special intents: if this broadcast is from the package 13346 // manager about a package being removed, we need to remove all of 13347 // its activities from the history stack. 13348 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13349 intent.getAction()); 13350 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13351 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13352 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13353 || uidRemoved) { 13354 if (checkComponentPermission( 13355 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13356 callingPid, callingUid, -1, true) 13357 == PackageManager.PERMISSION_GRANTED) { 13358 if (uidRemoved) { 13359 final Bundle intentExtras = intent.getExtras(); 13360 final int uid = intentExtras != null 13361 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13362 if (uid >= 0) { 13363 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13364 synchronized (bs) { 13365 bs.removeUidStatsLocked(uid); 13366 } 13367 mAppOpsService.uidRemoved(uid); 13368 } 13369 } else { 13370 // If resources are unavailable just force stop all 13371 // those packages and flush the attribute cache as well. 13372 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13373 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13374 if (list != null && (list.length > 0)) { 13375 for (String pkg : list) { 13376 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13377 "storage unmount"); 13378 } 13379 sendPackageBroadcastLocked( 13380 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13381 } 13382 } else { 13383 Uri data = intent.getData(); 13384 String ssp; 13385 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13386 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13387 intent.getAction()); 13388 boolean fullUninstall = removed && 13389 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13390 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13391 forceStopPackageLocked(ssp, UserHandle.getAppId( 13392 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13393 false, fullUninstall, userId, 13394 removed ? "pkg removed" : "pkg changed"); 13395 } 13396 if (removed) { 13397 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13398 new String[] {ssp}, userId); 13399 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13400 mAppOpsService.packageRemoved( 13401 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13402 13403 // Remove all permissions granted from/to this package 13404 removeUriPermissionsForPackageLocked(ssp, userId, true); 13405 } 13406 } 13407 } 13408 } 13409 } 13410 } else { 13411 String msg = "Permission Denial: " + intent.getAction() 13412 + " broadcast from " + callerPackage + " (pid=" + callingPid 13413 + ", uid=" + callingUid + ")" 13414 + " requires " 13415 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13416 Slog.w(TAG, msg); 13417 throw new SecurityException(msg); 13418 } 13419 13420 // Special case for adding a package: by default turn on compatibility 13421 // mode. 13422 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13423 Uri data = intent.getData(); 13424 String ssp; 13425 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13426 mCompatModePackages.handlePackageAddedLocked(ssp, 13427 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13428 } 13429 } 13430 13431 /* 13432 * If this is the time zone changed action, queue up a message that will reset the timezone 13433 * of all currently running processes. This message will get queued up before the broadcast 13434 * happens. 13435 */ 13436 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13437 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13438 } 13439 13440 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13441 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13442 } 13443 13444 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13445 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13446 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13447 } 13448 13449 // Add to the sticky list if requested. 13450 if (sticky) { 13451 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13452 callingPid, callingUid) 13453 != PackageManager.PERMISSION_GRANTED) { 13454 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13455 + callingPid + ", uid=" + callingUid 13456 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13457 Slog.w(TAG, msg); 13458 throw new SecurityException(msg); 13459 } 13460 if (requiredPermission != null) { 13461 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13462 + " and enforce permission " + requiredPermission); 13463 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13464 } 13465 if (intent.getComponent() != null) { 13466 throw new SecurityException( 13467 "Sticky broadcasts can't target a specific component"); 13468 } 13469 // We use userId directly here, since the "all" target is maintained 13470 // as a separate set of sticky broadcasts. 13471 if (userId != UserHandle.USER_ALL) { 13472 // But first, if this is not a broadcast to all users, then 13473 // make sure it doesn't conflict with an existing broadcast to 13474 // all users. 13475 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13476 UserHandle.USER_ALL); 13477 if (stickies != null) { 13478 ArrayList<Intent> list = stickies.get(intent.getAction()); 13479 if (list != null) { 13480 int N = list.size(); 13481 int i; 13482 for (i=0; i<N; i++) { 13483 if (intent.filterEquals(list.get(i))) { 13484 throw new IllegalArgumentException( 13485 "Sticky broadcast " + intent + " for user " 13486 + userId + " conflicts with existing global broadcast"); 13487 } 13488 } 13489 } 13490 } 13491 } 13492 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13493 if (stickies == null) { 13494 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13495 mStickyBroadcasts.put(userId, stickies); 13496 } 13497 ArrayList<Intent> list = stickies.get(intent.getAction()); 13498 if (list == null) { 13499 list = new ArrayList<Intent>(); 13500 stickies.put(intent.getAction(), list); 13501 } 13502 int N = list.size(); 13503 int i; 13504 for (i=0; i<N; i++) { 13505 if (intent.filterEquals(list.get(i))) { 13506 // This sticky already exists, replace it. 13507 list.set(i, new Intent(intent)); 13508 break; 13509 } 13510 } 13511 if (i >= N) { 13512 list.add(new Intent(intent)); 13513 } 13514 } 13515 13516 int[] users; 13517 if (userId == UserHandle.USER_ALL) { 13518 // Caller wants broadcast to go to all started users. 13519 users = mStartedUserArray; 13520 } else { 13521 // Caller wants broadcast to go to one specific user. 13522 users = new int[] {userId}; 13523 } 13524 13525 // Figure out who all will receive this broadcast. 13526 List receivers = null; 13527 List<BroadcastFilter> registeredReceivers = null; 13528 // Need to resolve the intent to interested receivers... 13529 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13530 == 0) { 13531 receivers = collectReceiverComponents(intent, resolvedType, users); 13532 } 13533 if (intent.getComponent() == null) { 13534 registeredReceivers = mReceiverResolver.queryIntent(intent, 13535 resolvedType, false, userId); 13536 } 13537 13538 final boolean replacePending = 13539 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13540 13541 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13542 + " replacePending=" + replacePending); 13543 13544 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13545 if (!ordered && NR > 0) { 13546 // If we are not serializing this broadcast, then send the 13547 // registered receivers separately so they don't wait for the 13548 // components to be launched. 13549 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13550 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13551 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13552 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13553 ordered, sticky, false, userId); 13554 if (DEBUG_BROADCAST) Slog.v( 13555 TAG, "Enqueueing parallel broadcast " + r); 13556 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13557 if (!replaced) { 13558 queue.enqueueParallelBroadcastLocked(r); 13559 queue.scheduleBroadcastsLocked(); 13560 } 13561 registeredReceivers = null; 13562 NR = 0; 13563 } 13564 13565 // Merge into one list. 13566 int ir = 0; 13567 if (receivers != null) { 13568 // A special case for PACKAGE_ADDED: do not allow the package 13569 // being added to see this broadcast. This prevents them from 13570 // using this as a back door to get run as soon as they are 13571 // installed. Maybe in the future we want to have a special install 13572 // broadcast or such for apps, but we'd like to deliberately make 13573 // this decision. 13574 String skipPackages[] = null; 13575 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13576 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13577 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13578 Uri data = intent.getData(); 13579 if (data != null) { 13580 String pkgName = data.getSchemeSpecificPart(); 13581 if (pkgName != null) { 13582 skipPackages = new String[] { pkgName }; 13583 } 13584 } 13585 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13586 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13587 } 13588 if (skipPackages != null && (skipPackages.length > 0)) { 13589 for (String skipPackage : skipPackages) { 13590 if (skipPackage != null) { 13591 int NT = receivers.size(); 13592 for (int it=0; it<NT; it++) { 13593 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13594 if (curt.activityInfo.packageName.equals(skipPackage)) { 13595 receivers.remove(it); 13596 it--; 13597 NT--; 13598 } 13599 } 13600 } 13601 } 13602 } 13603 13604 int NT = receivers != null ? receivers.size() : 0; 13605 int it = 0; 13606 ResolveInfo curt = null; 13607 BroadcastFilter curr = null; 13608 while (it < NT && ir < NR) { 13609 if (curt == null) { 13610 curt = (ResolveInfo)receivers.get(it); 13611 } 13612 if (curr == null) { 13613 curr = registeredReceivers.get(ir); 13614 } 13615 if (curr.getPriority() >= curt.priority) { 13616 // Insert this broadcast record into the final list. 13617 receivers.add(it, curr); 13618 ir++; 13619 curr = null; 13620 it++; 13621 NT++; 13622 } else { 13623 // Skip to the next ResolveInfo in the final list. 13624 it++; 13625 curt = null; 13626 } 13627 } 13628 } 13629 while (ir < NR) { 13630 if (receivers == null) { 13631 receivers = new ArrayList(); 13632 } 13633 receivers.add(registeredReceivers.get(ir)); 13634 ir++; 13635 } 13636 13637 if ((receivers != null && receivers.size() > 0) 13638 || resultTo != null) { 13639 BroadcastQueue queue = broadcastQueueForIntent(intent); 13640 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13641 callerPackage, callingPid, callingUid, resolvedType, 13642 requiredPermission, appOp, receivers, resultTo, resultCode, 13643 resultData, map, ordered, sticky, false, userId); 13644 if (DEBUG_BROADCAST) Slog.v( 13645 TAG, "Enqueueing ordered broadcast " + r 13646 + ": prev had " + queue.mOrderedBroadcasts.size()); 13647 if (DEBUG_BROADCAST) { 13648 int seq = r.intent.getIntExtra("seq", -1); 13649 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13650 } 13651 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13652 if (!replaced) { 13653 queue.enqueueOrderedBroadcastLocked(r); 13654 queue.scheduleBroadcastsLocked(); 13655 } 13656 } 13657 13658 return ActivityManager.BROADCAST_SUCCESS; 13659 } 13660 13661 final Intent verifyBroadcastLocked(Intent intent) { 13662 // Refuse possible leaked file descriptors 13663 if (intent != null && intent.hasFileDescriptors() == true) { 13664 throw new IllegalArgumentException("File descriptors passed in Intent"); 13665 } 13666 13667 int flags = intent.getFlags(); 13668 13669 if (!mProcessesReady) { 13670 // if the caller really truly claims to know what they're doing, go 13671 // ahead and allow the broadcast without launching any receivers 13672 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13673 intent = new Intent(intent); 13674 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13675 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13676 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13677 + " before boot completion"); 13678 throw new IllegalStateException("Cannot broadcast before boot completed"); 13679 } 13680 } 13681 13682 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13683 throw new IllegalArgumentException( 13684 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13685 } 13686 13687 return intent; 13688 } 13689 13690 public final int broadcastIntent(IApplicationThread caller, 13691 Intent intent, String resolvedType, IIntentReceiver resultTo, 13692 int resultCode, String resultData, Bundle map, 13693 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13694 enforceNotIsolatedCaller("broadcastIntent"); 13695 synchronized(this) { 13696 intent = verifyBroadcastLocked(intent); 13697 13698 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13699 final int callingPid = Binder.getCallingPid(); 13700 final int callingUid = Binder.getCallingUid(); 13701 final long origId = Binder.clearCallingIdentity(); 13702 int res = broadcastIntentLocked(callerApp, 13703 callerApp != null ? callerApp.info.packageName : null, 13704 intent, resolvedType, resultTo, 13705 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13706 callingPid, callingUid, userId); 13707 Binder.restoreCallingIdentity(origId); 13708 return res; 13709 } 13710 } 13711 13712 int broadcastIntentInPackage(String packageName, int uid, 13713 Intent intent, String resolvedType, IIntentReceiver resultTo, 13714 int resultCode, String resultData, Bundle map, 13715 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13716 synchronized(this) { 13717 intent = verifyBroadcastLocked(intent); 13718 13719 final long origId = Binder.clearCallingIdentity(); 13720 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13721 resultTo, resultCode, resultData, map, requiredPermission, 13722 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13723 Binder.restoreCallingIdentity(origId); 13724 return res; 13725 } 13726 } 13727 13728 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13729 // Refuse possible leaked file descriptors 13730 if (intent != null && intent.hasFileDescriptors() == true) { 13731 throw new IllegalArgumentException("File descriptors passed in Intent"); 13732 } 13733 13734 userId = handleIncomingUser(Binder.getCallingPid(), 13735 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13736 13737 synchronized(this) { 13738 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13739 != PackageManager.PERMISSION_GRANTED) { 13740 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13741 + Binder.getCallingPid() 13742 + ", uid=" + Binder.getCallingUid() 13743 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13744 Slog.w(TAG, msg); 13745 throw new SecurityException(msg); 13746 } 13747 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13748 if (stickies != null) { 13749 ArrayList<Intent> list = stickies.get(intent.getAction()); 13750 if (list != null) { 13751 int N = list.size(); 13752 int i; 13753 for (i=0; i<N; i++) { 13754 if (intent.filterEquals(list.get(i))) { 13755 list.remove(i); 13756 break; 13757 } 13758 } 13759 if (list.size() <= 0) { 13760 stickies.remove(intent.getAction()); 13761 } 13762 } 13763 if (stickies.size() <= 0) { 13764 mStickyBroadcasts.remove(userId); 13765 } 13766 } 13767 } 13768 } 13769 13770 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13771 String resultData, Bundle resultExtras, boolean resultAbort) { 13772 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13773 if (r == null) { 13774 Slog.w(TAG, "finishReceiver called but not found on queue"); 13775 return false; 13776 } 13777 13778 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13779 } 13780 13781 void backgroundServicesFinishedLocked(int userId) { 13782 for (BroadcastQueue queue : mBroadcastQueues) { 13783 queue.backgroundServicesFinishedLocked(userId); 13784 } 13785 } 13786 13787 public void finishReceiver(IBinder who, int resultCode, String resultData, 13788 Bundle resultExtras, boolean resultAbort) { 13789 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13790 13791 // Refuse possible leaked file descriptors 13792 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13793 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13794 } 13795 13796 final long origId = Binder.clearCallingIdentity(); 13797 try { 13798 boolean doNext = false; 13799 BroadcastRecord r; 13800 13801 synchronized(this) { 13802 r = broadcastRecordForReceiverLocked(who); 13803 if (r != null) { 13804 doNext = r.queue.finishReceiverLocked(r, resultCode, 13805 resultData, resultExtras, resultAbort, true); 13806 } 13807 } 13808 13809 if (doNext) { 13810 r.queue.processNextBroadcast(false); 13811 } 13812 trimApplications(); 13813 } finally { 13814 Binder.restoreCallingIdentity(origId); 13815 } 13816 } 13817 13818 // ========================================================= 13819 // INSTRUMENTATION 13820 // ========================================================= 13821 13822 public boolean startInstrumentation(ComponentName className, 13823 String profileFile, int flags, Bundle arguments, 13824 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13825 int userId) { 13826 enforceNotIsolatedCaller("startInstrumentation"); 13827 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13828 userId, false, true, "startInstrumentation", null); 13829 // Refuse possible leaked file descriptors 13830 if (arguments != null && arguments.hasFileDescriptors()) { 13831 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13832 } 13833 13834 synchronized(this) { 13835 InstrumentationInfo ii = null; 13836 ApplicationInfo ai = null; 13837 try { 13838 ii = mContext.getPackageManager().getInstrumentationInfo( 13839 className, STOCK_PM_FLAGS); 13840 ai = AppGlobals.getPackageManager().getApplicationInfo( 13841 ii.targetPackage, STOCK_PM_FLAGS, userId); 13842 } catch (PackageManager.NameNotFoundException e) { 13843 } catch (RemoteException e) { 13844 } 13845 if (ii == null) { 13846 reportStartInstrumentationFailure(watcher, className, 13847 "Unable to find instrumentation info for: " + className); 13848 return false; 13849 } 13850 if (ai == null) { 13851 reportStartInstrumentationFailure(watcher, className, 13852 "Unable to find instrumentation target package: " + ii.targetPackage); 13853 return false; 13854 } 13855 13856 int match = mContext.getPackageManager().checkSignatures( 13857 ii.targetPackage, ii.packageName); 13858 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13859 String msg = "Permission Denial: starting instrumentation " 13860 + className + " from pid=" 13861 + Binder.getCallingPid() 13862 + ", uid=" + Binder.getCallingPid() 13863 + " not allowed because package " + ii.packageName 13864 + " does not have a signature matching the target " 13865 + ii.targetPackage; 13866 reportStartInstrumentationFailure(watcher, className, msg); 13867 throw new SecurityException(msg); 13868 } 13869 13870 final long origId = Binder.clearCallingIdentity(); 13871 // Instrumentation can kill and relaunch even persistent processes 13872 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 13873 "start instr"); 13874 ProcessRecord app = addAppLocked(ai, false); 13875 app.instrumentationClass = className; 13876 app.instrumentationInfo = ai; 13877 app.instrumentationProfileFile = profileFile; 13878 app.instrumentationArguments = arguments; 13879 app.instrumentationWatcher = watcher; 13880 app.instrumentationUiAutomationConnection = uiAutomationConnection; 13881 app.instrumentationResultClass = className; 13882 Binder.restoreCallingIdentity(origId); 13883 } 13884 13885 return true; 13886 } 13887 13888 /** 13889 * Report errors that occur while attempting to start Instrumentation. Always writes the 13890 * error to the logs, but if somebody is watching, send the report there too. This enables 13891 * the "am" command to report errors with more information. 13892 * 13893 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13894 * @param cn The component name of the instrumentation. 13895 * @param report The error report. 13896 */ 13897 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13898 ComponentName cn, String report) { 13899 Slog.w(TAG, report); 13900 try { 13901 if (watcher != null) { 13902 Bundle results = new Bundle(); 13903 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13904 results.putString("Error", report); 13905 watcher.instrumentationStatus(cn, -1, results); 13906 } 13907 } catch (RemoteException e) { 13908 Slog.w(TAG, e); 13909 } 13910 } 13911 13912 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13913 if (app.instrumentationWatcher != null) { 13914 try { 13915 // NOTE: IInstrumentationWatcher *must* be oneway here 13916 app.instrumentationWatcher.instrumentationFinished( 13917 app.instrumentationClass, 13918 resultCode, 13919 results); 13920 } catch (RemoteException e) { 13921 } 13922 } 13923 if (app.instrumentationUiAutomationConnection != null) { 13924 try { 13925 app.instrumentationUiAutomationConnection.shutdown(); 13926 } catch (RemoteException re) { 13927 /* ignore */ 13928 } 13929 // Only a UiAutomation can set this flag and now that 13930 // it is finished we make sure it is reset to its default. 13931 mUserIsMonkey = false; 13932 } 13933 app.instrumentationWatcher = null; 13934 app.instrumentationUiAutomationConnection = null; 13935 app.instrumentationClass = null; 13936 app.instrumentationInfo = null; 13937 app.instrumentationProfileFile = null; 13938 app.instrumentationArguments = null; 13939 13940 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 13941 "finished inst"); 13942 } 13943 13944 public void finishInstrumentation(IApplicationThread target, 13945 int resultCode, Bundle results) { 13946 int userId = UserHandle.getCallingUserId(); 13947 // Refuse possible leaked file descriptors 13948 if (results != null && results.hasFileDescriptors()) { 13949 throw new IllegalArgumentException("File descriptors passed in Intent"); 13950 } 13951 13952 synchronized(this) { 13953 ProcessRecord app = getRecordForAppLocked(target); 13954 if (app == null) { 13955 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13956 return; 13957 } 13958 final long origId = Binder.clearCallingIdentity(); 13959 finishInstrumentationLocked(app, resultCode, results); 13960 Binder.restoreCallingIdentity(origId); 13961 } 13962 } 13963 13964 // ========================================================= 13965 // CONFIGURATION 13966 // ========================================================= 13967 13968 public ConfigurationInfo getDeviceConfigurationInfo() { 13969 ConfigurationInfo config = new ConfigurationInfo(); 13970 synchronized (this) { 13971 config.reqTouchScreen = mConfiguration.touchscreen; 13972 config.reqKeyboardType = mConfiguration.keyboard; 13973 config.reqNavigation = mConfiguration.navigation; 13974 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13975 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13976 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13977 } 13978 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13979 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13980 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13981 } 13982 config.reqGlEsVersion = GL_ES_VERSION; 13983 } 13984 return config; 13985 } 13986 13987 ActivityStack getFocusedStack() { 13988 return mStackSupervisor.getFocusedStack(); 13989 } 13990 13991 public Configuration getConfiguration() { 13992 Configuration ci; 13993 synchronized(this) { 13994 ci = new Configuration(mConfiguration); 13995 } 13996 return ci; 13997 } 13998 13999 public void updatePersistentConfiguration(Configuration values) { 14000 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14001 "updateConfiguration()"); 14002 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14003 "updateConfiguration()"); 14004 if (values == null) { 14005 throw new NullPointerException("Configuration must not be null"); 14006 } 14007 14008 synchronized(this) { 14009 final long origId = Binder.clearCallingIdentity(); 14010 updateConfigurationLocked(values, null, true, false); 14011 Binder.restoreCallingIdentity(origId); 14012 } 14013 } 14014 14015 public void updateConfiguration(Configuration values) { 14016 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14017 "updateConfiguration()"); 14018 14019 synchronized(this) { 14020 if (values == null && mWindowManager != null) { 14021 // sentinel: fetch the current configuration from the window manager 14022 values = mWindowManager.computeNewConfiguration(); 14023 } 14024 14025 if (mWindowManager != null) { 14026 mProcessList.applyDisplaySize(mWindowManager); 14027 } 14028 14029 final long origId = Binder.clearCallingIdentity(); 14030 if (values != null) { 14031 Settings.System.clearConfiguration(values); 14032 } 14033 updateConfigurationLocked(values, null, false, false); 14034 Binder.restoreCallingIdentity(origId); 14035 } 14036 } 14037 14038 /** 14039 * Do either or both things: (1) change the current configuration, and (2) 14040 * make sure the given activity is running with the (now) current 14041 * configuration. Returns true if the activity has been left running, or 14042 * false if <var>starting</var> is being destroyed to match the new 14043 * configuration. 14044 * @param persistent TODO 14045 */ 14046 boolean updateConfigurationLocked(Configuration values, 14047 ActivityRecord starting, boolean persistent, boolean initLocale) { 14048 int changes = 0; 14049 14050 if (values != null) { 14051 Configuration newConfig = new Configuration(mConfiguration); 14052 changes = newConfig.updateFrom(values); 14053 if (changes != 0) { 14054 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14055 Slog.i(TAG, "Updating configuration to: " + values); 14056 } 14057 14058 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14059 14060 if (values.locale != null && !initLocale) { 14061 saveLocaleLocked(values.locale, 14062 !values.locale.equals(mConfiguration.locale), 14063 values.userSetLocale); 14064 } 14065 14066 mConfigurationSeq++; 14067 if (mConfigurationSeq <= 0) { 14068 mConfigurationSeq = 1; 14069 } 14070 newConfig.seq = mConfigurationSeq; 14071 mConfiguration = newConfig; 14072 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14073 14074 final Configuration configCopy = new Configuration(mConfiguration); 14075 14076 // TODO: If our config changes, should we auto dismiss any currently 14077 // showing dialogs? 14078 mShowDialogs = shouldShowDialogs(newConfig); 14079 14080 AttributeCache ac = AttributeCache.instance(); 14081 if (ac != null) { 14082 ac.updateConfiguration(configCopy); 14083 } 14084 14085 // Make sure all resources in our process are updated 14086 // right now, so that anyone who is going to retrieve 14087 // resource values after we return will be sure to get 14088 // the new ones. This is especially important during 14089 // boot, where the first config change needs to guarantee 14090 // all resources have that config before following boot 14091 // code is executed. 14092 mSystemThread.applyConfigurationToResources(configCopy); 14093 14094 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14095 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14096 msg.obj = new Configuration(configCopy); 14097 mHandler.sendMessage(msg); 14098 } 14099 14100 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14101 ProcessRecord app = mLruProcesses.get(i); 14102 try { 14103 if (app.thread != null) { 14104 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14105 + app.processName + " new config " + mConfiguration); 14106 app.thread.scheduleConfigurationChanged(configCopy); 14107 } 14108 } catch (Exception e) { 14109 } 14110 } 14111 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14112 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14113 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14114 | Intent.FLAG_RECEIVER_FOREGROUND); 14115 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14116 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14117 Process.SYSTEM_UID, UserHandle.USER_ALL); 14118 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14119 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14120 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14121 broadcastIntentLocked(null, null, intent, 14122 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14123 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14124 } 14125 } 14126 } 14127 14128 boolean kept = true; 14129 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14130 // mainStack is null during startup. 14131 if (mainStack != null) { 14132 if (changes != 0 && starting == null) { 14133 // If the configuration changed, and the caller is not already 14134 // in the process of starting an activity, then find the top 14135 // activity to check if its configuration needs to change. 14136 starting = mainStack.topRunningActivityLocked(null); 14137 } 14138 14139 if (starting != null) { 14140 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14141 // And we need to make sure at this point that all other activities 14142 // are made visible with the correct configuration. 14143 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14144 } 14145 } 14146 14147 if (values != null && mWindowManager != null) { 14148 mWindowManager.setNewConfiguration(mConfiguration); 14149 } 14150 14151 return kept; 14152 } 14153 14154 /** 14155 * Decide based on the configuration whether we should shouw the ANR, 14156 * crash, etc dialogs. The idea is that if there is no affordnace to 14157 * press the on-screen buttons, we shouldn't show the dialog. 14158 * 14159 * A thought: SystemUI might also want to get told about this, the Power 14160 * dialog / global actions also might want different behaviors. 14161 */ 14162 private static final boolean shouldShowDialogs(Configuration config) { 14163 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14164 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14165 } 14166 14167 /** 14168 * Save the locale. You must be inside a synchronized (this) block. 14169 */ 14170 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14171 if(isDiff) { 14172 SystemProperties.set("user.language", l.getLanguage()); 14173 SystemProperties.set("user.region", l.getCountry()); 14174 } 14175 14176 if(isPersist) { 14177 SystemProperties.set("persist.sys.language", l.getLanguage()); 14178 SystemProperties.set("persist.sys.country", l.getCountry()); 14179 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14180 } 14181 } 14182 14183 @Override 14184 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14185 ActivityRecord srec = ActivityRecord.forToken(token); 14186 return srec != null && srec.task.affinity != null && 14187 srec.task.affinity.equals(destAffinity); 14188 } 14189 14190 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14191 Intent resultData) { 14192 14193 synchronized (this) { 14194 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14195 if (stack != null) { 14196 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14197 } 14198 return false; 14199 } 14200 } 14201 14202 public int getLaunchedFromUid(IBinder activityToken) { 14203 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14204 if (srec == null) { 14205 return -1; 14206 } 14207 return srec.launchedFromUid; 14208 } 14209 14210 public String getLaunchedFromPackage(IBinder activityToken) { 14211 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14212 if (srec == null) { 14213 return null; 14214 } 14215 return srec.launchedFromPackage; 14216 } 14217 14218 // ========================================================= 14219 // LIFETIME MANAGEMENT 14220 // ========================================================= 14221 14222 // Returns which broadcast queue the app is the current [or imminent] receiver 14223 // on, or 'null' if the app is not an active broadcast recipient. 14224 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14225 BroadcastRecord r = app.curReceiver; 14226 if (r != null) { 14227 return r.queue; 14228 } 14229 14230 // It's not the current receiver, but it might be starting up to become one 14231 synchronized (this) { 14232 for (BroadcastQueue queue : mBroadcastQueues) { 14233 r = queue.mPendingBroadcast; 14234 if (r != null && r.curApp == app) { 14235 // found it; report which queue it's in 14236 return queue; 14237 } 14238 } 14239 } 14240 14241 return null; 14242 } 14243 14244 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14245 boolean doingAll, long now) { 14246 if (mAdjSeq == app.adjSeq) { 14247 // This adjustment has already been computed. 14248 return app.curRawAdj; 14249 } 14250 14251 if (app.thread == null) { 14252 app.adjSeq = mAdjSeq; 14253 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14254 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14255 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14256 } 14257 14258 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14259 app.adjSource = null; 14260 app.adjTarget = null; 14261 app.empty = false; 14262 app.cached = false; 14263 14264 final int activitiesSize = app.activities.size(); 14265 14266 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14267 // The max adjustment doesn't allow this app to be anything 14268 // below foreground, so it is not worth doing work for it. 14269 app.adjType = "fixed"; 14270 app.adjSeq = mAdjSeq; 14271 app.curRawAdj = app.maxAdj; 14272 app.foregroundActivities = false; 14273 app.keeping = true; 14274 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14275 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14276 // System process can do UI, and when they do we want to have 14277 // them trim their memory after the user leaves the UI. To 14278 // facilitate this, here we need to determine whether or not it 14279 // is currently showing UI. 14280 app.systemNoUi = true; 14281 if (app == TOP_APP) { 14282 app.systemNoUi = false; 14283 } else if (activitiesSize > 0) { 14284 for (int j = 0; j < activitiesSize; j++) { 14285 final ActivityRecord r = app.activities.get(j); 14286 if (r.visible) { 14287 app.systemNoUi = false; 14288 } 14289 } 14290 } 14291 if (!app.systemNoUi) { 14292 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14293 } 14294 return (app.curAdj=app.maxAdj); 14295 } 14296 14297 app.keeping = false; 14298 app.systemNoUi = false; 14299 14300 // Determine the importance of the process, starting with most 14301 // important to least, and assign an appropriate OOM adjustment. 14302 int adj; 14303 int schedGroup; 14304 int procState; 14305 boolean foregroundActivities = false; 14306 boolean interesting = false; 14307 BroadcastQueue queue; 14308 if (app == TOP_APP) { 14309 // The last app on the list is the foreground app. 14310 adj = ProcessList.FOREGROUND_APP_ADJ; 14311 schedGroup = Process.THREAD_GROUP_DEFAULT; 14312 app.adjType = "top-activity"; 14313 foregroundActivities = true; 14314 interesting = true; 14315 procState = ActivityManager.PROCESS_STATE_TOP; 14316 } else if (app.instrumentationClass != null) { 14317 // Don't want to kill running instrumentation. 14318 adj = ProcessList.FOREGROUND_APP_ADJ; 14319 schedGroup = Process.THREAD_GROUP_DEFAULT; 14320 app.adjType = "instrumentation"; 14321 interesting = true; 14322 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14323 } else if ((queue = isReceivingBroadcast(app)) != null) { 14324 // An app that is currently receiving a broadcast also 14325 // counts as being in the foreground for OOM killer purposes. 14326 // It's placed in a sched group based on the nature of the 14327 // broadcast as reflected by which queue it's active in. 14328 adj = ProcessList.FOREGROUND_APP_ADJ; 14329 schedGroup = (queue == mFgBroadcastQueue) 14330 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14331 app.adjType = "broadcast"; 14332 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14333 } else if (app.executingServices.size() > 0) { 14334 // An app that is currently executing a service callback also 14335 // counts as being in the foreground. 14336 adj = ProcessList.FOREGROUND_APP_ADJ; 14337 schedGroup = app.execServicesFg ? 14338 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14339 app.adjType = "exec-service"; 14340 procState = ActivityManager.PROCESS_STATE_SERVICE; 14341 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14342 } else { 14343 // As far as we know the process is empty. We may change our mind later. 14344 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14345 // At this point we don't actually know the adjustment. Use the cached adj 14346 // value that the caller wants us to. 14347 adj = cachedAdj; 14348 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14349 app.cached = true; 14350 app.empty = true; 14351 app.adjType = "cch-empty"; 14352 } 14353 14354 // Examine all activities if not already foreground. 14355 if (!foregroundActivities && activitiesSize > 0) { 14356 for (int j = 0; j < activitiesSize; j++) { 14357 final ActivityRecord r = app.activities.get(j); 14358 if (r.app != app) { 14359 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14360 + app + "?!?"); 14361 continue; 14362 } 14363 if (r.visible) { 14364 // App has a visible activity; only upgrade adjustment. 14365 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14366 adj = ProcessList.VISIBLE_APP_ADJ; 14367 app.adjType = "visible"; 14368 } 14369 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14370 procState = ActivityManager.PROCESS_STATE_TOP; 14371 } 14372 schedGroup = Process.THREAD_GROUP_DEFAULT; 14373 app.cached = false; 14374 app.empty = false; 14375 foregroundActivities = true; 14376 break; 14377 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14378 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14379 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14380 app.adjType = "pausing"; 14381 } 14382 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14383 procState = ActivityManager.PROCESS_STATE_TOP; 14384 } 14385 schedGroup = Process.THREAD_GROUP_DEFAULT; 14386 app.cached = false; 14387 app.empty = false; 14388 foregroundActivities = true; 14389 } else if (r.state == ActivityState.STOPPING) { 14390 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14391 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14392 app.adjType = "stopping"; 14393 } 14394 // For the process state, we will at this point consider the 14395 // process to be cached. It will be cached either as an activity 14396 // or empty depending on whether the activity is finishing. We do 14397 // this so that we can treat the process as cached for purposes of 14398 // memory trimming (determing current memory level, trim command to 14399 // send to process) since there can be an arbitrary number of stopping 14400 // processes and they should soon all go into the cached state. 14401 if (!r.finishing) { 14402 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14403 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14404 } 14405 } 14406 app.cached = false; 14407 app.empty = false; 14408 foregroundActivities = true; 14409 } else { 14410 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14411 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14412 app.adjType = "cch-act"; 14413 } 14414 } 14415 } 14416 } 14417 14418 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14419 if (app.foregroundServices) { 14420 // The user is aware of this app, so make it visible. 14421 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14422 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14423 app.cached = false; 14424 app.adjType = "fg-service"; 14425 schedGroup = Process.THREAD_GROUP_DEFAULT; 14426 } else if (app.forcingToForeground != null) { 14427 // The user is aware of this app, so make it visible. 14428 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14429 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14430 app.cached = false; 14431 app.adjType = "force-fg"; 14432 app.adjSource = app.forcingToForeground; 14433 schedGroup = Process.THREAD_GROUP_DEFAULT; 14434 } 14435 } 14436 14437 if (app.foregroundServices) { 14438 interesting = true; 14439 } 14440 14441 if (app == mHeavyWeightProcess) { 14442 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14443 // We don't want to kill the current heavy-weight process. 14444 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14445 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14446 app.cached = false; 14447 app.adjType = "heavy"; 14448 } 14449 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14450 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14451 } 14452 } 14453 14454 if (app == mHomeProcess) { 14455 if (adj > ProcessList.HOME_APP_ADJ) { 14456 // This process is hosting what we currently consider to be the 14457 // home app, so we don't want to let it go into the background. 14458 adj = ProcessList.HOME_APP_ADJ; 14459 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14460 app.cached = false; 14461 app.adjType = "home"; 14462 } 14463 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14464 procState = ActivityManager.PROCESS_STATE_HOME; 14465 } 14466 } 14467 14468 if (app == mPreviousProcess && app.activities.size() > 0) { 14469 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14470 // This was the previous process that showed UI to the user. 14471 // We want to try to keep it around more aggressively, to give 14472 // a good experience around switching between two apps. 14473 adj = ProcessList.PREVIOUS_APP_ADJ; 14474 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14475 app.cached = false; 14476 app.adjType = "previous"; 14477 } 14478 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14479 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14480 } 14481 } 14482 14483 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14484 + " reason=" + app.adjType); 14485 14486 // By default, we use the computed adjustment. It may be changed if 14487 // there are applications dependent on our services or providers, but 14488 // this gives us a baseline and makes sure we don't get into an 14489 // infinite recursion. 14490 app.adjSeq = mAdjSeq; 14491 app.curRawAdj = adj; 14492 app.hasStartedServices = false; 14493 14494 if (mBackupTarget != null && app == mBackupTarget.app) { 14495 // If possible we want to avoid killing apps while they're being backed up 14496 if (adj > ProcessList.BACKUP_APP_ADJ) { 14497 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14498 adj = ProcessList.BACKUP_APP_ADJ; 14499 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14500 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14501 } 14502 app.adjType = "backup"; 14503 app.cached = false; 14504 } 14505 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14506 procState = ActivityManager.PROCESS_STATE_BACKUP; 14507 } 14508 } 14509 14510 boolean mayBeTop = false; 14511 14512 for (int is = app.services.size()-1; 14513 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14514 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14515 || procState > ActivityManager.PROCESS_STATE_TOP); 14516 is--) { 14517 ServiceRecord s = app.services.valueAt(is); 14518 if (s.startRequested) { 14519 app.hasStartedServices = true; 14520 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14521 procState = ActivityManager.PROCESS_STATE_SERVICE; 14522 } 14523 if (app.hasShownUi && app != mHomeProcess) { 14524 // If this process has shown some UI, let it immediately 14525 // go to the LRU list because it may be pretty heavy with 14526 // UI stuff. We'll tag it with a label just to help 14527 // debug and understand what is going on. 14528 if (adj > ProcessList.SERVICE_ADJ) { 14529 app.adjType = "cch-started-ui-services"; 14530 } 14531 } else { 14532 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14533 // This service has seen some activity within 14534 // recent memory, so we will keep its process ahead 14535 // of the background processes. 14536 if (adj > ProcessList.SERVICE_ADJ) { 14537 adj = ProcessList.SERVICE_ADJ; 14538 app.adjType = "started-services"; 14539 app.cached = false; 14540 } 14541 } 14542 // If we have let the service slide into the background 14543 // state, still have some text describing what it is doing 14544 // even though the service no longer has an impact. 14545 if (adj > ProcessList.SERVICE_ADJ) { 14546 app.adjType = "cch-started-services"; 14547 } 14548 } 14549 // Don't kill this process because it is doing work; it 14550 // has said it is doing work. 14551 app.keeping = true; 14552 } 14553 for (int conni = s.connections.size()-1; 14554 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14555 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14556 || procState > ActivityManager.PROCESS_STATE_TOP); 14557 conni--) { 14558 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14559 for (int i = 0; 14560 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14561 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14562 || procState > ActivityManager.PROCESS_STATE_TOP); 14563 i++) { 14564 // XXX should compute this based on the max of 14565 // all connected clients. 14566 ConnectionRecord cr = clist.get(i); 14567 if (cr.binding.client == app) { 14568 // Binding to ourself is not interesting. 14569 continue; 14570 } 14571 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14572 ProcessRecord client = cr.binding.client; 14573 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14574 TOP_APP, doingAll, now); 14575 int clientProcState = client.curProcState; 14576 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14577 // If the other app is cached for any reason, for purposes here 14578 // we are going to consider it empty. The specific cached state 14579 // doesn't propagate except under certain conditions. 14580 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14581 } 14582 String adjType = null; 14583 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14584 // Not doing bind OOM management, so treat 14585 // this guy more like a started service. 14586 if (app.hasShownUi && app != mHomeProcess) { 14587 // If this process has shown some UI, let it immediately 14588 // go to the LRU list because it may be pretty heavy with 14589 // UI stuff. We'll tag it with a label just to help 14590 // debug and understand what is going on. 14591 if (adj > clientAdj) { 14592 adjType = "cch-bound-ui-services"; 14593 } 14594 app.cached = false; 14595 clientAdj = adj; 14596 clientProcState = procState; 14597 } else { 14598 if (now >= (s.lastActivity 14599 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14600 // This service has not seen activity within 14601 // recent memory, so allow it to drop to the 14602 // LRU list if there is no other reason to keep 14603 // it around. We'll also tag it with a label just 14604 // to help debug and undertand what is going on. 14605 if (adj > clientAdj) { 14606 adjType = "cch-bound-services"; 14607 } 14608 clientAdj = adj; 14609 } 14610 } 14611 } 14612 if (adj > clientAdj) { 14613 // If this process has recently shown UI, and 14614 // the process that is binding to it is less 14615 // important than being visible, then we don't 14616 // care about the binding as much as we care 14617 // about letting this process get into the LRU 14618 // list to be killed and restarted if needed for 14619 // memory. 14620 if (app.hasShownUi && app != mHomeProcess 14621 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14622 adjType = "cch-bound-ui-services"; 14623 } else { 14624 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14625 |Context.BIND_IMPORTANT)) != 0) { 14626 adj = clientAdj; 14627 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14628 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14629 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14630 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14631 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14632 adj = clientAdj; 14633 } else { 14634 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14635 adj = ProcessList.VISIBLE_APP_ADJ; 14636 } 14637 } 14638 if (!client.cached) { 14639 app.cached = false; 14640 } 14641 if (client.keeping) { 14642 app.keeping = true; 14643 } 14644 adjType = "service"; 14645 } 14646 } 14647 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14648 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14649 schedGroup = Process.THREAD_GROUP_DEFAULT; 14650 } 14651 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14652 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14653 // Special handling of clients who are in the top state. 14654 // We *may* want to consider this process to be in the 14655 // top state as well, but only if there is not another 14656 // reason for it to be running. Being on the top is a 14657 // special state, meaning you are specifically running 14658 // for the current top app. If the process is already 14659 // running in the background for some other reason, it 14660 // is more important to continue considering it to be 14661 // in the background state. 14662 mayBeTop = true; 14663 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14664 } else { 14665 // Special handling for above-top states (persistent 14666 // processes). These should not bring the current process 14667 // into the top state, since they are not on top. Instead 14668 // give them the best state after that. 14669 clientProcState = 14670 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14671 } 14672 } 14673 } else { 14674 if (clientProcState < 14675 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14676 clientProcState = 14677 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14678 } 14679 } 14680 if (procState > clientProcState) { 14681 procState = clientProcState; 14682 } 14683 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14684 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14685 app.pendingUiClean = true; 14686 } 14687 if (adjType != null) { 14688 app.adjType = adjType; 14689 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14690 .REASON_SERVICE_IN_USE; 14691 app.adjSource = cr.binding.client; 14692 app.adjSourceOom = clientAdj; 14693 app.adjTarget = s.name; 14694 } 14695 } 14696 final ActivityRecord a = cr.activity; 14697 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14698 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14699 (a.visible || a.state == ActivityState.RESUMED 14700 || a.state == ActivityState.PAUSING)) { 14701 adj = ProcessList.FOREGROUND_APP_ADJ; 14702 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14703 schedGroup = Process.THREAD_GROUP_DEFAULT; 14704 } 14705 app.cached = false; 14706 app.adjType = "service"; 14707 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14708 .REASON_SERVICE_IN_USE; 14709 app.adjSource = a; 14710 app.adjSourceOom = adj; 14711 app.adjTarget = s.name; 14712 } 14713 } 14714 } 14715 } 14716 } 14717 14718 for (int provi = app.pubProviders.size()-1; 14719 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14720 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14721 || procState > ActivityManager.PROCESS_STATE_TOP); 14722 provi--) { 14723 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14724 for (int i = cpr.connections.size()-1; 14725 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14726 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14727 || procState > ActivityManager.PROCESS_STATE_TOP); 14728 i--) { 14729 ContentProviderConnection conn = cpr.connections.get(i); 14730 ProcessRecord client = conn.client; 14731 if (client == app) { 14732 // Being our own client is not interesting. 14733 continue; 14734 } 14735 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14736 int clientProcState = client.curProcState; 14737 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14738 // If the other app is cached for any reason, for purposes here 14739 // we are going to consider it empty. 14740 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14741 } 14742 if (adj > clientAdj) { 14743 if (app.hasShownUi && app != mHomeProcess 14744 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14745 app.adjType = "cch-ui-provider"; 14746 } else { 14747 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14748 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14749 app.adjType = "provider"; 14750 } 14751 app.cached &= client.cached; 14752 app.keeping |= client.keeping; 14753 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14754 .REASON_PROVIDER_IN_USE; 14755 app.adjSource = client; 14756 app.adjSourceOom = clientAdj; 14757 app.adjTarget = cpr.name; 14758 } 14759 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14760 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14761 // Special handling of clients who are in the top state. 14762 // We *may* want to consider this process to be in the 14763 // top state as well, but only if there is not another 14764 // reason for it to be running. Being on the top is a 14765 // special state, meaning you are specifically running 14766 // for the current top app. If the process is already 14767 // running in the background for some other reason, it 14768 // is more important to continue considering it to be 14769 // in the background state. 14770 mayBeTop = true; 14771 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14772 } else { 14773 // Special handling for above-top states (persistent 14774 // processes). These should not bring the current process 14775 // into the top state, since they are not on top. Instead 14776 // give them the best state after that. 14777 clientProcState = 14778 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14779 } 14780 } 14781 if (procState > clientProcState) { 14782 procState = clientProcState; 14783 } 14784 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14785 schedGroup = Process.THREAD_GROUP_DEFAULT; 14786 } 14787 } 14788 // If the provider has external (non-framework) process 14789 // dependencies, ensure that its adjustment is at least 14790 // FOREGROUND_APP_ADJ. 14791 if (cpr.hasExternalProcessHandles()) { 14792 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14793 adj = ProcessList.FOREGROUND_APP_ADJ; 14794 schedGroup = Process.THREAD_GROUP_DEFAULT; 14795 app.cached = false; 14796 app.keeping = true; 14797 app.adjType = "provider"; 14798 app.adjTarget = cpr.name; 14799 } 14800 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14801 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14802 } 14803 } 14804 } 14805 14806 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14807 // A client of one of our services or providers is in the top state. We 14808 // *may* want to be in the top state, but not if we are already running in 14809 // the background for some other reason. For the decision here, we are going 14810 // to pick out a few specific states that we want to remain in when a client 14811 // is top (states that tend to be longer-term) and otherwise allow it to go 14812 // to the top state. 14813 switch (procState) { 14814 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14815 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14816 case ActivityManager.PROCESS_STATE_SERVICE: 14817 // These all are longer-term states, so pull them up to the top 14818 // of the background states, but not all the way to the top state. 14819 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14820 break; 14821 default: 14822 // Otherwise, top is a better choice, so take it. 14823 procState = ActivityManager.PROCESS_STATE_TOP; 14824 break; 14825 } 14826 } 14827 14828 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14829 // This is a cached process, but with client activities. Mark it so. 14830 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14831 app.adjType = "cch-client-act"; 14832 } 14833 14834 if (adj == ProcessList.SERVICE_ADJ) { 14835 if (doingAll) { 14836 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14837 mNewNumServiceProcs++; 14838 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14839 if (!app.serviceb) { 14840 // This service isn't far enough down on the LRU list to 14841 // normally be a B service, but if we are low on RAM and it 14842 // is large we want to force it down since we would prefer to 14843 // keep launcher over it. 14844 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 14845 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 14846 app.serviceHighRam = true; 14847 app.serviceb = true; 14848 //Slog.i(TAG, "ADJ " + app + " high ram!"); 14849 } else { 14850 mNewNumAServiceProcs++; 14851 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 14852 } 14853 } else { 14854 app.serviceHighRam = false; 14855 } 14856 } 14857 if (app.serviceb) { 14858 adj = ProcessList.SERVICE_B_ADJ; 14859 } 14860 } 14861 14862 app.curRawAdj = adj; 14863 14864 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14865 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14866 if (adj > app.maxAdj) { 14867 adj = app.maxAdj; 14868 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14869 schedGroup = Process.THREAD_GROUP_DEFAULT; 14870 } 14871 } 14872 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 14873 app.keeping = true; 14874 } 14875 14876 // Do final modification to adj. Everything we do between here and applying 14877 // the final setAdj must be done in this function, because we will also use 14878 // it when computing the final cached adj later. Note that we don't need to 14879 // worry about this for max adj above, since max adj will always be used to 14880 // keep it out of the cached vaues. 14881 adj = app.modifyRawOomAdj(adj); 14882 14883 app.curProcState = procState; 14884 14885 int importance = app.memImportance; 14886 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14887 app.curAdj = adj; 14888 app.curSchedGroup = schedGroup; 14889 if (!interesting) { 14890 // For this reporting, if there is not something explicitly 14891 // interesting in this process then we will push it to the 14892 // background importance. 14893 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14894 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 14895 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14896 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14897 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14898 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14899 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14900 } else if (adj >= ProcessList.SERVICE_ADJ) { 14901 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14902 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14903 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14904 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14905 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14906 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14907 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14908 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14909 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14910 } else { 14911 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14912 } 14913 } 14914 14915 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14916 if (foregroundActivities != app.foregroundActivities) { 14917 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14918 } 14919 if (changes != 0) { 14920 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14921 app.memImportance = importance; 14922 app.foregroundActivities = foregroundActivities; 14923 int i = mPendingProcessChanges.size()-1; 14924 ProcessChangeItem item = null; 14925 while (i >= 0) { 14926 item = mPendingProcessChanges.get(i); 14927 if (item.pid == app.pid) { 14928 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14929 break; 14930 } 14931 i--; 14932 } 14933 if (i < 0) { 14934 // No existing item in pending changes; need a new one. 14935 final int NA = mAvailProcessChanges.size(); 14936 if (NA > 0) { 14937 item = mAvailProcessChanges.remove(NA-1); 14938 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14939 } else { 14940 item = new ProcessChangeItem(); 14941 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14942 } 14943 item.changes = 0; 14944 item.pid = app.pid; 14945 item.uid = app.info.uid; 14946 if (mPendingProcessChanges.size() == 0) { 14947 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14948 "*** Enqueueing dispatch processes changed!"); 14949 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14950 } 14951 mPendingProcessChanges.add(item); 14952 } 14953 item.changes |= changes; 14954 item.importance = importance; 14955 item.foregroundActivities = foregroundActivities; 14956 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14957 + Integer.toHexString(System.identityHashCode(item)) 14958 + " " + app.toShortString() + ": changes=" + item.changes 14959 + " importance=" + item.importance 14960 + " foreground=" + item.foregroundActivities 14961 + " type=" + app.adjType + " source=" + app.adjSource 14962 + " target=" + app.adjTarget); 14963 } 14964 14965 return app.curRawAdj; 14966 } 14967 14968 /** 14969 * Schedule PSS collection of a process. 14970 */ 14971 void requestPssLocked(ProcessRecord proc, int procState) { 14972 if (mPendingPssProcesses.contains(proc)) { 14973 return; 14974 } 14975 if (mPendingPssProcesses.size() == 0) { 14976 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14977 } 14978 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 14979 proc.pssProcState = procState; 14980 mPendingPssProcesses.add(proc); 14981 } 14982 14983 /** 14984 * Schedule PSS collection of all processes. 14985 */ 14986 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 14987 if (!always) { 14988 if (now < (mLastFullPssTime + 14989 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 14990 return; 14991 } 14992 } 14993 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 14994 mLastFullPssTime = now; 14995 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 14996 mPendingPssProcesses.clear(); 14997 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14998 ProcessRecord app = mLruProcesses.get(i); 14999 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15000 app.pssProcState = app.setProcState; 15001 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15002 mSleeping, now); 15003 mPendingPssProcesses.add(app); 15004 } 15005 } 15006 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15007 } 15008 15009 /** 15010 * Ask a given process to GC right now. 15011 */ 15012 final void performAppGcLocked(ProcessRecord app) { 15013 try { 15014 app.lastRequestedGc = SystemClock.uptimeMillis(); 15015 if (app.thread != null) { 15016 if (app.reportLowMemory) { 15017 app.reportLowMemory = false; 15018 app.thread.scheduleLowMemory(); 15019 } else { 15020 app.thread.processInBackground(); 15021 } 15022 } 15023 } catch (Exception e) { 15024 // whatever. 15025 } 15026 } 15027 15028 /** 15029 * Returns true if things are idle enough to perform GCs. 15030 */ 15031 private final boolean canGcNowLocked() { 15032 boolean processingBroadcasts = false; 15033 for (BroadcastQueue q : mBroadcastQueues) { 15034 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15035 processingBroadcasts = true; 15036 } 15037 } 15038 return !processingBroadcasts 15039 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 15040 } 15041 15042 /** 15043 * Perform GCs on all processes that are waiting for it, but only 15044 * if things are idle. 15045 */ 15046 final void performAppGcsLocked() { 15047 final int N = mProcessesToGc.size(); 15048 if (N <= 0) { 15049 return; 15050 } 15051 if (canGcNowLocked()) { 15052 while (mProcessesToGc.size() > 0) { 15053 ProcessRecord proc = mProcessesToGc.remove(0); 15054 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15055 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15056 <= SystemClock.uptimeMillis()) { 15057 // To avoid spamming the system, we will GC processes one 15058 // at a time, waiting a few seconds between each. 15059 performAppGcLocked(proc); 15060 scheduleAppGcsLocked(); 15061 return; 15062 } else { 15063 // It hasn't been long enough since we last GCed this 15064 // process... put it in the list to wait for its time. 15065 addProcessToGcListLocked(proc); 15066 break; 15067 } 15068 } 15069 } 15070 15071 scheduleAppGcsLocked(); 15072 } 15073 } 15074 15075 /** 15076 * If all looks good, perform GCs on all processes waiting for them. 15077 */ 15078 final void performAppGcsIfAppropriateLocked() { 15079 if (canGcNowLocked()) { 15080 performAppGcsLocked(); 15081 return; 15082 } 15083 // Still not idle, wait some more. 15084 scheduleAppGcsLocked(); 15085 } 15086 15087 /** 15088 * Schedule the execution of all pending app GCs. 15089 */ 15090 final void scheduleAppGcsLocked() { 15091 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15092 15093 if (mProcessesToGc.size() > 0) { 15094 // Schedule a GC for the time to the next process. 15095 ProcessRecord proc = mProcessesToGc.get(0); 15096 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15097 15098 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15099 long now = SystemClock.uptimeMillis(); 15100 if (when < (now+GC_TIMEOUT)) { 15101 when = now + GC_TIMEOUT; 15102 } 15103 mHandler.sendMessageAtTime(msg, when); 15104 } 15105 } 15106 15107 /** 15108 * Add a process to the array of processes waiting to be GCed. Keeps the 15109 * list in sorted order by the last GC time. The process can't already be 15110 * on the list. 15111 */ 15112 final void addProcessToGcListLocked(ProcessRecord proc) { 15113 boolean added = false; 15114 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15115 if (mProcessesToGc.get(i).lastRequestedGc < 15116 proc.lastRequestedGc) { 15117 added = true; 15118 mProcessesToGc.add(i+1, proc); 15119 break; 15120 } 15121 } 15122 if (!added) { 15123 mProcessesToGc.add(0, proc); 15124 } 15125 } 15126 15127 /** 15128 * Set up to ask a process to GC itself. This will either do it 15129 * immediately, or put it on the list of processes to gc the next 15130 * time things are idle. 15131 */ 15132 final void scheduleAppGcLocked(ProcessRecord app) { 15133 long now = SystemClock.uptimeMillis(); 15134 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15135 return; 15136 } 15137 if (!mProcessesToGc.contains(app)) { 15138 addProcessToGcListLocked(app); 15139 scheduleAppGcsLocked(); 15140 } 15141 } 15142 15143 final void checkExcessivePowerUsageLocked(boolean doKills) { 15144 updateCpuStatsNow(); 15145 15146 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15147 boolean doWakeKills = doKills; 15148 boolean doCpuKills = doKills; 15149 if (mLastPowerCheckRealtime == 0) { 15150 doWakeKills = false; 15151 } 15152 if (mLastPowerCheckUptime == 0) { 15153 doCpuKills = false; 15154 } 15155 if (stats.isScreenOn()) { 15156 doWakeKills = false; 15157 } 15158 final long curRealtime = SystemClock.elapsedRealtime(); 15159 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15160 final long curUptime = SystemClock.uptimeMillis(); 15161 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15162 mLastPowerCheckRealtime = curRealtime; 15163 mLastPowerCheckUptime = curUptime; 15164 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15165 doWakeKills = false; 15166 } 15167 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15168 doCpuKills = false; 15169 } 15170 int i = mLruProcesses.size(); 15171 while (i > 0) { 15172 i--; 15173 ProcessRecord app = mLruProcesses.get(i); 15174 if (!app.keeping) { 15175 long wtime; 15176 synchronized (stats) { 15177 wtime = stats.getProcessWakeTime(app.info.uid, 15178 app.pid, curRealtime); 15179 } 15180 long wtimeUsed = wtime - app.lastWakeTime; 15181 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15182 if (DEBUG_POWER) { 15183 StringBuilder sb = new StringBuilder(128); 15184 sb.append("Wake for "); 15185 app.toShortString(sb); 15186 sb.append(": over "); 15187 TimeUtils.formatDuration(realtimeSince, sb); 15188 sb.append(" used "); 15189 TimeUtils.formatDuration(wtimeUsed, sb); 15190 sb.append(" ("); 15191 sb.append((wtimeUsed*100)/realtimeSince); 15192 sb.append("%)"); 15193 Slog.i(TAG, sb.toString()); 15194 sb.setLength(0); 15195 sb.append("CPU for "); 15196 app.toShortString(sb); 15197 sb.append(": over "); 15198 TimeUtils.formatDuration(uptimeSince, sb); 15199 sb.append(" used "); 15200 TimeUtils.formatDuration(cputimeUsed, sb); 15201 sb.append(" ("); 15202 sb.append((cputimeUsed*100)/uptimeSince); 15203 sb.append("%)"); 15204 Slog.i(TAG, sb.toString()); 15205 } 15206 // If a process has held a wake lock for more 15207 // than 50% of the time during this period, 15208 // that sounds bad. Kill! 15209 if (doWakeKills && realtimeSince > 0 15210 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15211 synchronized (stats) { 15212 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15213 realtimeSince, wtimeUsed); 15214 } 15215 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15216 + " during " + realtimeSince); 15217 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15218 } else if (doCpuKills && uptimeSince > 0 15219 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15220 synchronized (stats) { 15221 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15222 uptimeSince, cputimeUsed); 15223 } 15224 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15225 + " during " + uptimeSince); 15226 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15227 } else { 15228 app.lastWakeTime = wtime; 15229 app.lastCpuTime = app.curCpuTime; 15230 } 15231 } 15232 } 15233 } 15234 15235 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15236 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15237 boolean success = true; 15238 15239 if (app.curRawAdj != app.setRawAdj) { 15240 if (wasKeeping && !app.keeping) { 15241 // This app is no longer something we want to keep. Note 15242 // its current wake lock time to later know to kill it if 15243 // it is not behaving well. 15244 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15245 synchronized (stats) { 15246 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15247 app.pid, SystemClock.elapsedRealtime()); 15248 } 15249 app.lastCpuTime = app.curCpuTime; 15250 } 15251 15252 app.setRawAdj = app.curRawAdj; 15253 } 15254 15255 if (app.curAdj != app.setAdj) { 15256 ProcessList.setOomAdj(app.pid, app.curAdj); 15257 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15258 TAG, "Set " + app.pid + " " + app.processName + 15259 " adj " + app.curAdj + ": " + app.adjType); 15260 app.setAdj = app.curAdj; 15261 } 15262 15263 if (app.setSchedGroup != app.curSchedGroup) { 15264 app.setSchedGroup = app.curSchedGroup; 15265 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15266 "Setting process group of " + app.processName 15267 + " to " + app.curSchedGroup); 15268 if (app.waitingToKill != null && 15269 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15270 killUnneededProcessLocked(app, app.waitingToKill); 15271 success = false; 15272 } else { 15273 if (true) { 15274 long oldId = Binder.clearCallingIdentity(); 15275 try { 15276 Process.setProcessGroup(app.pid, app.curSchedGroup); 15277 } catch (Exception e) { 15278 Slog.w(TAG, "Failed setting process group of " + app.pid 15279 + " to " + app.curSchedGroup); 15280 e.printStackTrace(); 15281 } finally { 15282 Binder.restoreCallingIdentity(oldId); 15283 } 15284 } else { 15285 if (app.thread != null) { 15286 try { 15287 app.thread.setSchedulingGroup(app.curSchedGroup); 15288 } catch (RemoteException e) { 15289 } 15290 } 15291 } 15292 Process.setSwappiness(app.pid, 15293 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15294 } 15295 } 15296 if (app.repProcState != app.curProcState) { 15297 app.repProcState = app.curProcState; 15298 if (!reportingProcessState && app.thread != null) { 15299 try { 15300 if (false) { 15301 //RuntimeException h = new RuntimeException("here"); 15302 Slog.i(TAG, "Sending new process state " + app.repProcState 15303 + " to " + app /*, h*/); 15304 } 15305 app.thread.setProcessState(app.repProcState); 15306 } catch (RemoteException e) { 15307 } 15308 } 15309 } 15310 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15311 app.setProcState)) { 15312 app.lastStateTime = now; 15313 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15314 mSleeping, now); 15315 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15316 + ProcessList.makeProcStateString(app.setProcState) + " to " 15317 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15318 + (app.nextPssTime-now) + ": " + app); 15319 } else { 15320 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15321 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15322 requestPssLocked(app, app.setProcState); 15323 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15324 mSleeping, now); 15325 } else if (false && DEBUG_PSS) { 15326 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15327 } 15328 } 15329 if (app.setProcState != app.curProcState) { 15330 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15331 "Proc state change of " + app.processName 15332 + " to " + app.curProcState); 15333 app.setProcState = app.curProcState; 15334 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15335 app.notCachedSinceIdle = false; 15336 } 15337 if (!doingAll) { 15338 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15339 } else { 15340 app.procStateChanged = true; 15341 } 15342 } 15343 return success; 15344 } 15345 15346 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15347 if (proc.thread != null && proc.baseProcessTracker != null) { 15348 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15349 } 15350 } 15351 15352 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15353 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15354 if (app.thread == null) { 15355 return false; 15356 } 15357 15358 final boolean wasKeeping = app.keeping; 15359 15360 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15361 15362 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15363 reportingProcessState, now); 15364 } 15365 15366 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15367 boolean oomAdj) { 15368 if (isForeground != proc.foregroundServices) { 15369 proc.foregroundServices = isForeground; 15370 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15371 proc.info.uid); 15372 if (isForeground) { 15373 if (curProcs == null) { 15374 curProcs = new ArrayList<ProcessRecord>(); 15375 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15376 } 15377 if (!curProcs.contains(proc)) { 15378 curProcs.add(proc); 15379 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15380 proc.info.packageName, proc.info.uid); 15381 } 15382 } else { 15383 if (curProcs != null) { 15384 if (curProcs.remove(proc)) { 15385 mBatteryStatsService.noteEvent( 15386 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15387 proc.info.packageName, proc.info.uid); 15388 if (curProcs.size() <= 0) { 15389 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15390 } 15391 } 15392 } 15393 } 15394 if (oomAdj) { 15395 updateOomAdjLocked(); 15396 } 15397 } 15398 } 15399 15400 private final ActivityRecord resumedAppLocked() { 15401 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15402 String pkg; 15403 int uid; 15404 if (act != null) { 15405 pkg = act.packageName; 15406 uid = act.info.applicationInfo.uid; 15407 } else { 15408 pkg = null; 15409 uid = -1; 15410 } 15411 // Has the UID or resumed package name changed? 15412 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15413 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15414 if (mCurResumedPackage != null) { 15415 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15416 mCurResumedPackage, mCurResumedUid); 15417 } 15418 mCurResumedPackage = pkg; 15419 mCurResumedUid = uid; 15420 if (mCurResumedPackage != null) { 15421 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15422 mCurResumedPackage, mCurResumedUid); 15423 } 15424 } 15425 return act; 15426 } 15427 15428 final boolean updateOomAdjLocked(ProcessRecord app) { 15429 return updateOomAdjLocked(app, false); 15430 } 15431 15432 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15433 final ActivityRecord TOP_ACT = resumedAppLocked(); 15434 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15435 final boolean wasCached = app.cached; 15436 15437 mAdjSeq++; 15438 15439 // This is the desired cached adjusment we want to tell it to use. 15440 // If our app is currently cached, we know it, and that is it. Otherwise, 15441 // we don't know it yet, and it needs to now be cached we will then 15442 // need to do a complete oom adj. 15443 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15444 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15445 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15446 SystemClock.uptimeMillis()); 15447 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15448 // Changed to/from cached state, so apps after it in the LRU 15449 // list may also be changed. 15450 updateOomAdjLocked(); 15451 } 15452 return success; 15453 } 15454 15455 final void updateOomAdjLocked() { 15456 final ActivityRecord TOP_ACT = resumedAppLocked(); 15457 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15458 final long now = SystemClock.uptimeMillis(); 15459 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15460 final int N = mLruProcesses.size(); 15461 15462 if (false) { 15463 RuntimeException e = new RuntimeException(); 15464 e.fillInStackTrace(); 15465 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15466 } 15467 15468 mAdjSeq++; 15469 mNewNumServiceProcs = 0; 15470 mNewNumAServiceProcs = 0; 15471 15472 final int emptyProcessLimit; 15473 final int cachedProcessLimit; 15474 if (mProcessLimit <= 0) { 15475 emptyProcessLimit = cachedProcessLimit = 0; 15476 } else if (mProcessLimit == 1) { 15477 emptyProcessLimit = 1; 15478 cachedProcessLimit = 0; 15479 } else { 15480 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15481 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15482 } 15483 15484 // Let's determine how many processes we have running vs. 15485 // how many slots we have for background processes; we may want 15486 // to put multiple processes in a slot of there are enough of 15487 // them. 15488 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15489 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15490 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15491 if (numEmptyProcs > cachedProcessLimit) { 15492 // If there are more empty processes than our limit on cached 15493 // processes, then use the cached process limit for the factor. 15494 // This ensures that the really old empty processes get pushed 15495 // down to the bottom, so if we are running low on memory we will 15496 // have a better chance at keeping around more cached processes 15497 // instead of a gazillion empty processes. 15498 numEmptyProcs = cachedProcessLimit; 15499 } 15500 int emptyFactor = numEmptyProcs/numSlots; 15501 if (emptyFactor < 1) emptyFactor = 1; 15502 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15503 if (cachedFactor < 1) cachedFactor = 1; 15504 int stepCached = 0; 15505 int stepEmpty = 0; 15506 int numCached = 0; 15507 int numEmpty = 0; 15508 int numTrimming = 0; 15509 15510 mNumNonCachedProcs = 0; 15511 mNumCachedHiddenProcs = 0; 15512 15513 // First update the OOM adjustment for each of the 15514 // application processes based on their current state. 15515 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15516 int nextCachedAdj = curCachedAdj+1; 15517 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15518 int nextEmptyAdj = curEmptyAdj+2; 15519 for (int i=N-1; i>=0; i--) { 15520 ProcessRecord app = mLruProcesses.get(i); 15521 if (!app.killedByAm && app.thread != null) { 15522 app.procStateChanged = false; 15523 final boolean wasKeeping = app.keeping; 15524 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15525 15526 // If we haven't yet assigned the final cached adj 15527 // to the process, do that now. 15528 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15529 switch (app.curProcState) { 15530 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15531 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15532 // This process is a cached process holding activities... 15533 // assign it the next cached value for that type, and then 15534 // step that cached level. 15535 app.curRawAdj = curCachedAdj; 15536 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15537 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15538 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15539 + ")"); 15540 if (curCachedAdj != nextCachedAdj) { 15541 stepCached++; 15542 if (stepCached >= cachedFactor) { 15543 stepCached = 0; 15544 curCachedAdj = nextCachedAdj; 15545 nextCachedAdj += 2; 15546 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15547 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15548 } 15549 } 15550 } 15551 break; 15552 default: 15553 // For everything else, assign next empty cached process 15554 // level and bump that up. Note that this means that 15555 // long-running services that have dropped down to the 15556 // cached level will be treated as empty (since their process 15557 // state is still as a service), which is what we want. 15558 app.curRawAdj = curEmptyAdj; 15559 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15560 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15561 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15562 + ")"); 15563 if (curEmptyAdj != nextEmptyAdj) { 15564 stepEmpty++; 15565 if (stepEmpty >= emptyFactor) { 15566 stepEmpty = 0; 15567 curEmptyAdj = nextEmptyAdj; 15568 nextEmptyAdj += 2; 15569 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15570 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15571 } 15572 } 15573 } 15574 break; 15575 } 15576 } 15577 15578 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15579 15580 // Count the number of process types. 15581 switch (app.curProcState) { 15582 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15583 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15584 mNumCachedHiddenProcs++; 15585 numCached++; 15586 if (numCached > cachedProcessLimit) { 15587 killUnneededProcessLocked(app, "cached #" + numCached); 15588 } 15589 break; 15590 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15591 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15592 && app.lastActivityTime < oldTime) { 15593 killUnneededProcessLocked(app, "empty for " 15594 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15595 / 1000) + "s"); 15596 } else { 15597 numEmpty++; 15598 if (numEmpty > emptyProcessLimit) { 15599 killUnneededProcessLocked(app, "empty #" + numEmpty); 15600 } 15601 } 15602 break; 15603 default: 15604 mNumNonCachedProcs++; 15605 break; 15606 } 15607 15608 if (app.isolated && app.services.size() <= 0) { 15609 // If this is an isolated process, and there are no 15610 // services running in it, then the process is no longer 15611 // needed. We agressively kill these because we can by 15612 // definition not re-use the same process again, and it is 15613 // good to avoid having whatever code was running in them 15614 // left sitting around after no longer needed. 15615 killUnneededProcessLocked(app, "isolated not needed"); 15616 } 15617 15618 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15619 && !app.killedByAm) { 15620 numTrimming++; 15621 } 15622 } 15623 } 15624 15625 mNumServiceProcs = mNewNumServiceProcs; 15626 15627 // Now determine the memory trimming level of background processes. 15628 // Unfortunately we need to start at the back of the list to do this 15629 // properly. We only do this if the number of background apps we 15630 // are managing to keep around is less than half the maximum we desire; 15631 // if we are keeping a good number around, we'll let them use whatever 15632 // memory they want. 15633 final int numCachedAndEmpty = numCached + numEmpty; 15634 int memFactor; 15635 if (numCached <= ProcessList.TRIM_CACHED_APPS 15636 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15637 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15638 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15639 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15640 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15641 } else { 15642 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15643 } 15644 } else { 15645 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15646 } 15647 // We always allow the memory level to go up (better). We only allow it to go 15648 // down if we are in a state where that is allowed, *and* the total number of processes 15649 // has gone down since last time. 15650 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15651 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15652 + " last=" + mLastNumProcesses); 15653 if (memFactor > mLastMemoryLevel) { 15654 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15655 memFactor = mLastMemoryLevel; 15656 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15657 } 15658 } 15659 mLastMemoryLevel = memFactor; 15660 mLastNumProcesses = mLruProcesses.size(); 15661 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15662 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15663 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15664 if (mLowRamStartTime == 0) { 15665 mLowRamStartTime = now; 15666 } 15667 int step = 0; 15668 int fgTrimLevel; 15669 switch (memFactor) { 15670 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15671 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15672 break; 15673 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15674 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15675 break; 15676 default: 15677 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15678 break; 15679 } 15680 int factor = numTrimming/3; 15681 int minFactor = 2; 15682 if (mHomeProcess != null) minFactor++; 15683 if (mPreviousProcess != null) minFactor++; 15684 if (factor < minFactor) factor = minFactor; 15685 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15686 for (int i=N-1; i>=0; i--) { 15687 ProcessRecord app = mLruProcesses.get(i); 15688 if (allChanged || app.procStateChanged) { 15689 setProcessTrackerState(app, trackerMemFactor, now); 15690 app.procStateChanged = false; 15691 } 15692 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15693 && !app.killedByAm) { 15694 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15695 try { 15696 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15697 "Trimming memory of " + app.processName 15698 + " to " + curLevel); 15699 app.thread.scheduleTrimMemory(curLevel); 15700 } catch (RemoteException e) { 15701 } 15702 if (false) { 15703 // For now we won't do this; our memory trimming seems 15704 // to be good enough at this point that destroying 15705 // activities causes more harm than good. 15706 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15707 && app != mHomeProcess && app != mPreviousProcess) { 15708 // Need to do this on its own message because the stack may not 15709 // be in a consistent state at this point. 15710 // For these apps we will also finish their activities 15711 // to help them free memory. 15712 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15713 } 15714 } 15715 } 15716 app.trimMemoryLevel = curLevel; 15717 step++; 15718 if (step >= factor) { 15719 step = 0; 15720 switch (curLevel) { 15721 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15722 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15723 break; 15724 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15725 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15726 break; 15727 } 15728 } 15729 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15730 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15731 && app.thread != null) { 15732 try { 15733 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15734 "Trimming memory of heavy-weight " + app.processName 15735 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15736 app.thread.scheduleTrimMemory( 15737 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15738 } catch (RemoteException e) { 15739 } 15740 } 15741 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15742 } else { 15743 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15744 || app.systemNoUi) && app.pendingUiClean) { 15745 // If this application is now in the background and it 15746 // had done UI, then give it the special trim level to 15747 // have it free UI resources. 15748 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15749 if (app.trimMemoryLevel < level && app.thread != null) { 15750 try { 15751 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15752 "Trimming memory of bg-ui " + app.processName 15753 + " to " + level); 15754 app.thread.scheduleTrimMemory(level); 15755 } catch (RemoteException e) { 15756 } 15757 } 15758 app.pendingUiClean = false; 15759 } 15760 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15761 try { 15762 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15763 "Trimming memory of fg " + app.processName 15764 + " to " + fgTrimLevel); 15765 app.thread.scheduleTrimMemory(fgTrimLevel); 15766 } catch (RemoteException e) { 15767 } 15768 } 15769 app.trimMemoryLevel = fgTrimLevel; 15770 } 15771 } 15772 } else { 15773 if (mLowRamStartTime != 0) { 15774 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15775 mLowRamStartTime = 0; 15776 } 15777 for (int i=N-1; i>=0; i--) { 15778 ProcessRecord app = mLruProcesses.get(i); 15779 if (allChanged || app.procStateChanged) { 15780 setProcessTrackerState(app, trackerMemFactor, now); 15781 app.procStateChanged = false; 15782 } 15783 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15784 || app.systemNoUi) && app.pendingUiClean) { 15785 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15786 && app.thread != null) { 15787 try { 15788 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15789 "Trimming memory of ui hidden " + app.processName 15790 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15791 app.thread.scheduleTrimMemory( 15792 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15793 } catch (RemoteException e) { 15794 } 15795 } 15796 app.pendingUiClean = false; 15797 } 15798 app.trimMemoryLevel = 0; 15799 } 15800 } 15801 15802 if (mAlwaysFinishActivities) { 15803 // Need to do this on its own message because the stack may not 15804 // be in a consistent state at this point. 15805 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15806 } 15807 15808 if (allChanged) { 15809 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15810 } 15811 15812 if (mProcessStats.shouldWriteNowLocked(now)) { 15813 mHandler.post(new Runnable() { 15814 @Override public void run() { 15815 synchronized (ActivityManagerService.this) { 15816 mProcessStats.writeStateAsyncLocked(); 15817 } 15818 } 15819 }); 15820 } 15821 15822 if (DEBUG_OOM_ADJ) { 15823 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15824 } 15825 } 15826 15827 final void trimApplications() { 15828 synchronized (this) { 15829 int i; 15830 15831 // First remove any unused application processes whose package 15832 // has been removed. 15833 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15834 final ProcessRecord app = mRemovedProcesses.get(i); 15835 if (app.activities.size() == 0 15836 && app.curReceiver == null && app.services.size() == 0) { 15837 Slog.i( 15838 TAG, "Exiting empty application process " 15839 + app.processName + " (" 15840 + (app.thread != null ? app.thread.asBinder() : null) 15841 + ")\n"); 15842 if (app.pid > 0 && app.pid != MY_PID) { 15843 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 15844 app.processName, app.setAdj, "empty"); 15845 app.killedByAm = true; 15846 Process.killProcessQuiet(app.pid); 15847 } else { 15848 try { 15849 app.thread.scheduleExit(); 15850 } catch (Exception e) { 15851 // Ignore exceptions. 15852 } 15853 } 15854 cleanUpApplicationRecordLocked(app, false, true, -1); 15855 mRemovedProcesses.remove(i); 15856 15857 if (app.persistent) { 15858 if (app.persistent) { 15859 addAppLocked(app.info, false); 15860 } 15861 } 15862 } 15863 } 15864 15865 // Now update the oom adj for all processes. 15866 updateOomAdjLocked(); 15867 } 15868 } 15869 15870 /** This method sends the specified signal to each of the persistent apps */ 15871 public void signalPersistentProcesses(int sig) throws RemoteException { 15872 if (sig != Process.SIGNAL_USR1) { 15873 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 15874 } 15875 15876 synchronized (this) { 15877 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 15878 != PackageManager.PERMISSION_GRANTED) { 15879 throw new SecurityException("Requires permission " 15880 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 15881 } 15882 15883 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15884 ProcessRecord r = mLruProcesses.get(i); 15885 if (r.thread != null && r.persistent) { 15886 Process.sendSignal(r.pid, sig); 15887 } 15888 } 15889 } 15890 } 15891 15892 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 15893 if (proc == null || proc == mProfileProc) { 15894 proc = mProfileProc; 15895 path = mProfileFile; 15896 profileType = mProfileType; 15897 clearProfilerLocked(); 15898 } 15899 if (proc == null) { 15900 return; 15901 } 15902 try { 15903 proc.thread.profilerControl(false, path, null, profileType); 15904 } catch (RemoteException e) { 15905 throw new IllegalStateException("Process disappeared"); 15906 } 15907 } 15908 15909 private void clearProfilerLocked() { 15910 if (mProfileFd != null) { 15911 try { 15912 mProfileFd.close(); 15913 } catch (IOException e) { 15914 } 15915 } 15916 mProfileApp = null; 15917 mProfileProc = null; 15918 mProfileFile = null; 15919 mProfileType = 0; 15920 mAutoStopProfiler = false; 15921 } 15922 15923 public boolean profileControl(String process, int userId, boolean start, 15924 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 15925 15926 try { 15927 synchronized (this) { 15928 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15929 // its own permission. 15930 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15931 != PackageManager.PERMISSION_GRANTED) { 15932 throw new SecurityException("Requires permission " 15933 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15934 } 15935 15936 if (start && fd == null) { 15937 throw new IllegalArgumentException("null fd"); 15938 } 15939 15940 ProcessRecord proc = null; 15941 if (process != null) { 15942 proc = findProcessLocked(process, userId, "profileControl"); 15943 } 15944 15945 if (start && (proc == null || proc.thread == null)) { 15946 throw new IllegalArgumentException("Unknown process: " + process); 15947 } 15948 15949 if (start) { 15950 stopProfilerLocked(null, null, 0); 15951 setProfileApp(proc.info, proc.processName, path, fd, false); 15952 mProfileProc = proc; 15953 mProfileType = profileType; 15954 try { 15955 fd = fd.dup(); 15956 } catch (IOException e) { 15957 fd = null; 15958 } 15959 proc.thread.profilerControl(start, path, fd, profileType); 15960 fd = null; 15961 mProfileFd = null; 15962 } else { 15963 stopProfilerLocked(proc, path, profileType); 15964 if (fd != null) { 15965 try { 15966 fd.close(); 15967 } catch (IOException e) { 15968 } 15969 } 15970 } 15971 15972 return true; 15973 } 15974 } catch (RemoteException e) { 15975 throw new IllegalStateException("Process disappeared"); 15976 } finally { 15977 if (fd != null) { 15978 try { 15979 fd.close(); 15980 } catch (IOException e) { 15981 } 15982 } 15983 } 15984 } 15985 15986 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 15987 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15988 userId, true, true, callName, null); 15989 ProcessRecord proc = null; 15990 try { 15991 int pid = Integer.parseInt(process); 15992 synchronized (mPidsSelfLocked) { 15993 proc = mPidsSelfLocked.get(pid); 15994 } 15995 } catch (NumberFormatException e) { 15996 } 15997 15998 if (proc == null) { 15999 ArrayMap<String, SparseArray<ProcessRecord>> all 16000 = mProcessNames.getMap(); 16001 SparseArray<ProcessRecord> procs = all.get(process); 16002 if (procs != null && procs.size() > 0) { 16003 proc = procs.valueAt(0); 16004 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16005 for (int i=1; i<procs.size(); i++) { 16006 ProcessRecord thisProc = procs.valueAt(i); 16007 if (thisProc.userId == userId) { 16008 proc = thisProc; 16009 break; 16010 } 16011 } 16012 } 16013 } 16014 } 16015 16016 return proc; 16017 } 16018 16019 public boolean dumpHeap(String process, int userId, boolean managed, 16020 String path, ParcelFileDescriptor fd) throws RemoteException { 16021 16022 try { 16023 synchronized (this) { 16024 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16025 // its own permission (same as profileControl). 16026 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16027 != PackageManager.PERMISSION_GRANTED) { 16028 throw new SecurityException("Requires permission " 16029 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16030 } 16031 16032 if (fd == null) { 16033 throw new IllegalArgumentException("null fd"); 16034 } 16035 16036 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16037 if (proc == null || proc.thread == null) { 16038 throw new IllegalArgumentException("Unknown process: " + process); 16039 } 16040 16041 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16042 if (!isDebuggable) { 16043 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16044 throw new SecurityException("Process not debuggable: " + proc); 16045 } 16046 } 16047 16048 proc.thread.dumpHeap(managed, path, fd); 16049 fd = null; 16050 return true; 16051 } 16052 } catch (RemoteException e) { 16053 throw new IllegalStateException("Process disappeared"); 16054 } finally { 16055 if (fd != null) { 16056 try { 16057 fd.close(); 16058 } catch (IOException e) { 16059 } 16060 } 16061 } 16062 } 16063 16064 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16065 public void monitor() { 16066 synchronized (this) { } 16067 } 16068 16069 void onCoreSettingsChange(Bundle settings) { 16070 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16071 ProcessRecord processRecord = mLruProcesses.get(i); 16072 try { 16073 if (processRecord.thread != null) { 16074 processRecord.thread.setCoreSettings(settings); 16075 } 16076 } catch (RemoteException re) { 16077 /* ignore */ 16078 } 16079 } 16080 } 16081 16082 // Multi-user methods 16083 16084 /** 16085 * Start user, if its not already running, but don't bring it to foreground. 16086 */ 16087 @Override 16088 public boolean startUserInBackground(final int userId) { 16089 return startUser(userId, /* foreground */ false); 16090 } 16091 16092 @Override 16093 public boolean switchUser(final int userId) { 16094 return startUser(userId, /* foregound */ true); 16095 } 16096 16097 private boolean startUser(final int userId, boolean foreground) { 16098 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16099 != PackageManager.PERMISSION_GRANTED) { 16100 String msg = "Permission Denial: switchUser() from pid=" 16101 + Binder.getCallingPid() 16102 + ", uid=" + Binder.getCallingUid() 16103 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16104 Slog.w(TAG, msg); 16105 throw new SecurityException(msg); 16106 } 16107 16108 final long ident = Binder.clearCallingIdentity(); 16109 try { 16110 synchronized (this) { 16111 final int oldUserId = mCurrentUserId; 16112 if (oldUserId == userId) { 16113 return true; 16114 } 16115 16116 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16117 if (userInfo == null) { 16118 Slog.w(TAG, "No user info for user #" + userId); 16119 return false; 16120 } 16121 16122 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16123 R.anim.screen_user_enter); 16124 16125 boolean needStart = false; 16126 16127 // If the user we are switching to is not currently started, then 16128 // we need to start it now. 16129 if (mStartedUsers.get(userId) == null) { 16130 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16131 updateStartedUserArrayLocked(); 16132 needStart = true; 16133 } 16134 16135 final Integer userIdInt = Integer.valueOf(userId); 16136 mUserLru.remove(userIdInt); 16137 mUserLru.add(userIdInt); 16138 16139 if (foreground) { 16140 mCurrentUserId = userId; 16141 mWindowManager.setCurrentUser(userId); 16142 } else { 16143 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16144 mUserLru.remove(currentUserIdInt); 16145 mUserLru.add(currentUserIdInt); 16146 } 16147 16148 // Once the internal notion of the active user has switched, we lock the device 16149 // with the option to show the user switcher on the keyguard. 16150 mWindowManager.lockNow(null); 16151 16152 final UserStartedState uss = mStartedUsers.get(userId); 16153 16154 // Make sure user is in the started state. If it is currently 16155 // stopping, we need to knock that off. 16156 if (uss.mState == UserStartedState.STATE_STOPPING) { 16157 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16158 // so we can just fairly silently bring the user back from 16159 // the almost-dead. 16160 uss.mState = UserStartedState.STATE_RUNNING; 16161 updateStartedUserArrayLocked(); 16162 needStart = true; 16163 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16164 // This means ACTION_SHUTDOWN has been sent, so we will 16165 // need to treat this as a new boot of the user. 16166 uss.mState = UserStartedState.STATE_BOOTING; 16167 updateStartedUserArrayLocked(); 16168 needStart = true; 16169 } 16170 16171 if (foreground) { 16172 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16173 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16174 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16175 oldUserId, userId, uss)); 16176 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16177 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16178 } 16179 16180 if (needStart) { 16181 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16182 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16183 | Intent.FLAG_RECEIVER_FOREGROUND); 16184 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16185 broadcastIntentLocked(null, null, intent, 16186 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16187 false, false, MY_PID, Process.SYSTEM_UID, userId); 16188 } 16189 16190 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16191 if (userId != 0) { 16192 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16193 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16194 broadcastIntentLocked(null, null, intent, null, 16195 new IIntentReceiver.Stub() { 16196 public void performReceive(Intent intent, int resultCode, 16197 String data, Bundle extras, boolean ordered, 16198 boolean sticky, int sendingUser) { 16199 userInitialized(uss, userId); 16200 } 16201 }, 0, null, null, null, AppOpsManager.OP_NONE, 16202 true, false, MY_PID, Process.SYSTEM_UID, 16203 userId); 16204 uss.initializing = true; 16205 } else { 16206 getUserManagerLocked().makeInitialized(userInfo.id); 16207 } 16208 } 16209 16210 if (foreground) { 16211 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16212 if (homeInFront) { 16213 startHomeActivityLocked(userId); 16214 } else { 16215 mStackSupervisor.resumeTopActivitiesLocked(); 16216 } 16217 EventLogTags.writeAmSwitchUser(userId); 16218 getUserManagerLocked().userForeground(userId); 16219 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16220 } 16221 16222 if (needStart) { 16223 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16224 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16225 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16226 broadcastIntentLocked(null, null, intent, 16227 null, new IIntentReceiver.Stub() { 16228 @Override 16229 public void performReceive(Intent intent, int resultCode, String data, 16230 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16231 throws RemoteException { 16232 } 16233 }, 0, null, null, 16234 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16235 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16236 } 16237 } 16238 } finally { 16239 Binder.restoreCallingIdentity(ident); 16240 } 16241 16242 return true; 16243 } 16244 16245 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16246 long ident = Binder.clearCallingIdentity(); 16247 try { 16248 Intent intent; 16249 if (oldUserId >= 0) { 16250 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16251 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16252 | Intent.FLAG_RECEIVER_FOREGROUND); 16253 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16254 broadcastIntentLocked(null, null, intent, 16255 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16256 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16257 } 16258 if (newUserId >= 0) { 16259 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16260 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16261 | Intent.FLAG_RECEIVER_FOREGROUND); 16262 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16263 broadcastIntentLocked(null, null, intent, 16264 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16265 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16266 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16267 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16268 | Intent.FLAG_RECEIVER_FOREGROUND); 16269 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16270 broadcastIntentLocked(null, null, intent, 16271 null, null, 0, null, null, 16272 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16273 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16274 } 16275 } finally { 16276 Binder.restoreCallingIdentity(ident); 16277 } 16278 } 16279 16280 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16281 final int newUserId) { 16282 final int N = mUserSwitchObservers.beginBroadcast(); 16283 if (N > 0) { 16284 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16285 int mCount = 0; 16286 @Override 16287 public void sendResult(Bundle data) throws RemoteException { 16288 synchronized (ActivityManagerService.this) { 16289 if (mCurUserSwitchCallback == this) { 16290 mCount++; 16291 if (mCount == N) { 16292 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16293 } 16294 } 16295 } 16296 } 16297 }; 16298 synchronized (this) { 16299 uss.switching = true; 16300 mCurUserSwitchCallback = callback; 16301 } 16302 for (int i=0; i<N; i++) { 16303 try { 16304 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16305 newUserId, callback); 16306 } catch (RemoteException e) { 16307 } 16308 } 16309 } else { 16310 synchronized (this) { 16311 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16312 } 16313 } 16314 mUserSwitchObservers.finishBroadcast(); 16315 } 16316 16317 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16318 synchronized (this) { 16319 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16320 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16321 } 16322 } 16323 16324 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16325 mCurUserSwitchCallback = null; 16326 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16327 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16328 oldUserId, newUserId, uss)); 16329 } 16330 16331 void userInitialized(UserStartedState uss, int newUserId) { 16332 completeSwitchAndInitalize(uss, newUserId, true, false); 16333 } 16334 16335 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16336 completeSwitchAndInitalize(uss, newUserId, false, true); 16337 } 16338 16339 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16340 boolean clearInitializing, boolean clearSwitching) { 16341 boolean unfrozen = false; 16342 synchronized (this) { 16343 if (clearInitializing) { 16344 uss.initializing = false; 16345 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16346 } 16347 if (clearSwitching) { 16348 uss.switching = false; 16349 } 16350 if (!uss.switching && !uss.initializing) { 16351 mWindowManager.stopFreezingScreen(); 16352 unfrozen = true; 16353 } 16354 } 16355 if (unfrozen) { 16356 final int N = mUserSwitchObservers.beginBroadcast(); 16357 for (int i=0; i<N; i++) { 16358 try { 16359 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16360 } catch (RemoteException e) { 16361 } 16362 } 16363 mUserSwitchObservers.finishBroadcast(); 16364 } 16365 } 16366 16367 void finishUserSwitch(UserStartedState uss) { 16368 synchronized (this) { 16369 if (uss.mState == UserStartedState.STATE_BOOTING 16370 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16371 uss.mState = UserStartedState.STATE_RUNNING; 16372 final int userId = uss.mHandle.getIdentifier(); 16373 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16374 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16375 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16376 broadcastIntentLocked(null, null, intent, 16377 null, null, 0, null, null, 16378 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16379 true, false, MY_PID, Process.SYSTEM_UID, userId); 16380 } 16381 int num = mUserLru.size(); 16382 int i = 0; 16383 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16384 Integer oldUserId = mUserLru.get(i); 16385 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16386 if (oldUss == null) { 16387 // Shouldn't happen, but be sane if it does. 16388 mUserLru.remove(i); 16389 num--; 16390 continue; 16391 } 16392 if (oldUss.mState == UserStartedState.STATE_STOPPING 16393 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16394 // This user is already stopping, doesn't count. 16395 num--; 16396 i++; 16397 continue; 16398 } 16399 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16400 // Owner and current can't be stopped, but count as running. 16401 i++; 16402 continue; 16403 } 16404 // This is a user to be stopped. 16405 stopUserLocked(oldUserId, null); 16406 num--; 16407 i++; 16408 } 16409 } 16410 } 16411 16412 @Override 16413 public int stopUser(final int userId, final IStopUserCallback callback) { 16414 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16415 != PackageManager.PERMISSION_GRANTED) { 16416 String msg = "Permission Denial: switchUser() from pid=" 16417 + Binder.getCallingPid() 16418 + ", uid=" + Binder.getCallingUid() 16419 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16420 Slog.w(TAG, msg); 16421 throw new SecurityException(msg); 16422 } 16423 if (userId <= 0) { 16424 throw new IllegalArgumentException("Can't stop primary user " + userId); 16425 } 16426 synchronized (this) { 16427 return stopUserLocked(userId, callback); 16428 } 16429 } 16430 16431 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16432 if (mCurrentUserId == userId) { 16433 return ActivityManager.USER_OP_IS_CURRENT; 16434 } 16435 16436 final UserStartedState uss = mStartedUsers.get(userId); 16437 if (uss == null) { 16438 // User is not started, nothing to do... but we do need to 16439 // callback if requested. 16440 if (callback != null) { 16441 mHandler.post(new Runnable() { 16442 @Override 16443 public void run() { 16444 try { 16445 callback.userStopped(userId); 16446 } catch (RemoteException e) { 16447 } 16448 } 16449 }); 16450 } 16451 return ActivityManager.USER_OP_SUCCESS; 16452 } 16453 16454 if (callback != null) { 16455 uss.mStopCallbacks.add(callback); 16456 } 16457 16458 if (uss.mState != UserStartedState.STATE_STOPPING 16459 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16460 uss.mState = UserStartedState.STATE_STOPPING; 16461 updateStartedUserArrayLocked(); 16462 16463 long ident = Binder.clearCallingIdentity(); 16464 try { 16465 // We are going to broadcast ACTION_USER_STOPPING and then 16466 // once that is done send a final ACTION_SHUTDOWN and then 16467 // stop the user. 16468 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16469 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16470 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16471 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16472 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16473 // This is the result receiver for the final shutdown broadcast. 16474 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16475 @Override 16476 public void performReceive(Intent intent, int resultCode, String data, 16477 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16478 finishUserStop(uss); 16479 } 16480 }; 16481 // This is the result receiver for the initial stopping broadcast. 16482 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16483 @Override 16484 public void performReceive(Intent intent, int resultCode, String data, 16485 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16486 // On to the next. 16487 synchronized (ActivityManagerService.this) { 16488 if (uss.mState != UserStartedState.STATE_STOPPING) { 16489 // Whoops, we are being started back up. Abort, abort! 16490 return; 16491 } 16492 uss.mState = UserStartedState.STATE_SHUTDOWN; 16493 } 16494 broadcastIntentLocked(null, null, shutdownIntent, 16495 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16496 true, false, MY_PID, Process.SYSTEM_UID, userId); 16497 } 16498 }; 16499 // Kick things off. 16500 broadcastIntentLocked(null, null, stoppingIntent, 16501 null, stoppingReceiver, 0, null, null, 16502 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16503 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16504 } finally { 16505 Binder.restoreCallingIdentity(ident); 16506 } 16507 } 16508 16509 return ActivityManager.USER_OP_SUCCESS; 16510 } 16511 16512 void finishUserStop(UserStartedState uss) { 16513 final int userId = uss.mHandle.getIdentifier(); 16514 boolean stopped; 16515 ArrayList<IStopUserCallback> callbacks; 16516 synchronized (this) { 16517 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16518 if (mStartedUsers.get(userId) != uss) { 16519 stopped = false; 16520 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16521 stopped = false; 16522 } else { 16523 stopped = true; 16524 // User can no longer run. 16525 mStartedUsers.remove(userId); 16526 mUserLru.remove(Integer.valueOf(userId)); 16527 updateStartedUserArrayLocked(); 16528 16529 // Clean up all state and processes associated with the user. 16530 // Kill all the processes for the user. 16531 forceStopUserLocked(userId, "finish user"); 16532 } 16533 } 16534 16535 for (int i=0; i<callbacks.size(); i++) { 16536 try { 16537 if (stopped) callbacks.get(i).userStopped(userId); 16538 else callbacks.get(i).userStopAborted(userId); 16539 } catch (RemoteException e) { 16540 } 16541 } 16542 16543 mStackSupervisor.removeUserLocked(userId); 16544 } 16545 16546 @Override 16547 public UserInfo getCurrentUser() { 16548 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16549 != PackageManager.PERMISSION_GRANTED) && ( 16550 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16551 != PackageManager.PERMISSION_GRANTED)) { 16552 String msg = "Permission Denial: getCurrentUser() from pid=" 16553 + Binder.getCallingPid() 16554 + ", uid=" + Binder.getCallingUid() 16555 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16556 Slog.w(TAG, msg); 16557 throw new SecurityException(msg); 16558 } 16559 synchronized (this) { 16560 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16561 } 16562 } 16563 16564 int getCurrentUserIdLocked() { 16565 return mCurrentUserId; 16566 } 16567 16568 @Override 16569 public boolean isUserRunning(int userId, boolean orStopped) { 16570 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16571 != PackageManager.PERMISSION_GRANTED) { 16572 String msg = "Permission Denial: isUserRunning() from pid=" 16573 + Binder.getCallingPid() 16574 + ", uid=" + Binder.getCallingUid() 16575 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16576 Slog.w(TAG, msg); 16577 throw new SecurityException(msg); 16578 } 16579 synchronized (this) { 16580 return isUserRunningLocked(userId, orStopped); 16581 } 16582 } 16583 16584 boolean isUserRunningLocked(int userId, boolean orStopped) { 16585 UserStartedState state = mStartedUsers.get(userId); 16586 if (state == null) { 16587 return false; 16588 } 16589 if (orStopped) { 16590 return true; 16591 } 16592 return state.mState != UserStartedState.STATE_STOPPING 16593 && state.mState != UserStartedState.STATE_SHUTDOWN; 16594 } 16595 16596 @Override 16597 public int[] getRunningUserIds() { 16598 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16599 != PackageManager.PERMISSION_GRANTED) { 16600 String msg = "Permission Denial: isUserRunning() from pid=" 16601 + Binder.getCallingPid() 16602 + ", uid=" + Binder.getCallingUid() 16603 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16604 Slog.w(TAG, msg); 16605 throw new SecurityException(msg); 16606 } 16607 synchronized (this) { 16608 return mStartedUserArray; 16609 } 16610 } 16611 16612 private void updateStartedUserArrayLocked() { 16613 int num = 0; 16614 for (int i=0; i<mStartedUsers.size(); i++) { 16615 UserStartedState uss = mStartedUsers.valueAt(i); 16616 // This list does not include stopping users. 16617 if (uss.mState != UserStartedState.STATE_STOPPING 16618 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16619 num++; 16620 } 16621 } 16622 mStartedUserArray = new int[num]; 16623 num = 0; 16624 for (int i=0; i<mStartedUsers.size(); i++) { 16625 UserStartedState uss = mStartedUsers.valueAt(i); 16626 if (uss.mState != UserStartedState.STATE_STOPPING 16627 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16628 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16629 num++; 16630 } 16631 } 16632 } 16633 16634 @Override 16635 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16636 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16637 != PackageManager.PERMISSION_GRANTED) { 16638 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16639 + Binder.getCallingPid() 16640 + ", uid=" + Binder.getCallingUid() 16641 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16642 Slog.w(TAG, msg); 16643 throw new SecurityException(msg); 16644 } 16645 16646 mUserSwitchObservers.register(observer); 16647 } 16648 16649 @Override 16650 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16651 mUserSwitchObservers.unregister(observer); 16652 } 16653 16654 private boolean userExists(int userId) { 16655 if (userId == 0) { 16656 return true; 16657 } 16658 UserManagerService ums = getUserManagerLocked(); 16659 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16660 } 16661 16662 int[] getUsersLocked() { 16663 UserManagerService ums = getUserManagerLocked(); 16664 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16665 } 16666 16667 UserManagerService getUserManagerLocked() { 16668 if (mUserManager == null) { 16669 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16670 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16671 } 16672 return mUserManager; 16673 } 16674 16675 private int applyUserId(int uid, int userId) { 16676 return UserHandle.getUid(userId, uid); 16677 } 16678 16679 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16680 if (info == null) return null; 16681 ApplicationInfo newInfo = new ApplicationInfo(info); 16682 newInfo.uid = applyUserId(info.uid, userId); 16683 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16684 + info.packageName; 16685 return newInfo; 16686 } 16687 16688 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16689 if (aInfo == null 16690 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16691 return aInfo; 16692 } 16693 16694 ActivityInfo info = new ActivityInfo(aInfo); 16695 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16696 return info; 16697 } 16698} 16699