ActivityManagerService.java revision 303e1ff1fec8b240b587bb18b981247a99833aa8
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 int[] mRelatedUserIds = new int[0]; // Accessed by ActivityStack 1019 private UserManagerService mUserManager; 1020 1021 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1022 final ProcessRecord mApp; 1023 final int mPid; 1024 final IApplicationThread mAppThread; 1025 1026 AppDeathRecipient(ProcessRecord app, int pid, 1027 IApplicationThread thread) { 1028 if (localLOGV) Slog.v( 1029 TAG, "New death recipient " + this 1030 + " for thread " + thread.asBinder()); 1031 mApp = app; 1032 mPid = pid; 1033 mAppThread = thread; 1034 } 1035 1036 @Override 1037 public void binderDied() { 1038 if (localLOGV) Slog.v( 1039 TAG, "Death received in " + this 1040 + " for thread " + mAppThread.asBinder()); 1041 synchronized(ActivityManagerService.this) { 1042 appDiedLocked(mApp, mPid, mAppThread); 1043 } 1044 } 1045 } 1046 1047 static final int SHOW_ERROR_MSG = 1; 1048 static final int SHOW_NOT_RESPONDING_MSG = 2; 1049 static final int SHOW_FACTORY_ERROR_MSG = 3; 1050 static final int UPDATE_CONFIGURATION_MSG = 4; 1051 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1052 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1053 static final int SERVICE_TIMEOUT_MSG = 12; 1054 static final int UPDATE_TIME_ZONE = 13; 1055 static final int SHOW_UID_ERROR_MSG = 14; 1056 static final int IM_FEELING_LUCKY_MSG = 15; 1057 static final int PROC_START_TIMEOUT_MSG = 20; 1058 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1059 static final int KILL_APPLICATION_MSG = 22; 1060 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1061 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1062 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1063 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1064 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1065 static final int CLEAR_DNS_CACHE_MSG = 28; 1066 static final int UPDATE_HTTP_PROXY_MSG = 29; 1067 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1068 static final int DISPATCH_PROCESSES_CHANGED = 31; 1069 static final int DISPATCH_PROCESS_DIED = 32; 1070 static final int REPORT_MEM_USAGE_MSG = 33; 1071 static final int REPORT_USER_SWITCH_MSG = 34; 1072 static final int CONTINUE_USER_SWITCH_MSG = 35; 1073 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1074 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1075 static final int PERSIST_URI_GRANTS_MSG = 38; 1076 static final int REQUEST_ALL_PSS_MSG = 39; 1077 static final int START_RELATED_USERS_MSG = 40; 1078 static final int UPDATE_TIME = 41; 1079 1080 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1081 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1082 static final int FIRST_COMPAT_MODE_MSG = 300; 1083 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1084 1085 AlertDialog mUidAlert; 1086 CompatModeDialog mCompatModeDialog; 1087 long mLastMemUsageReportTime = 0; 1088 1089 /** 1090 * Flag whether the current user is a "monkey", i.e. whether 1091 * the UI is driven by a UI automation tool. 1092 */ 1093 private boolean mUserIsMonkey; 1094 1095 final ServiceThread mHandlerThread; 1096 final MainHandler mHandler; 1097 1098 final class MainHandler extends Handler { 1099 public MainHandler(Looper looper) { 1100 super(looper, null, true); 1101 } 1102 1103 @Override 1104 public void handleMessage(Message msg) { 1105 switch (msg.what) { 1106 case SHOW_ERROR_MSG: { 1107 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1108 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1109 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1110 synchronized (ActivityManagerService.this) { 1111 ProcessRecord proc = (ProcessRecord)data.get("app"); 1112 AppErrorResult res = (AppErrorResult) data.get("result"); 1113 if (proc != null && proc.crashDialog != null) { 1114 Slog.e(TAG, "App already has crash dialog: " + proc); 1115 if (res != null) { 1116 res.set(0); 1117 } 1118 return; 1119 } 1120 if (!showBackground && UserHandle.getAppId(proc.uid) 1121 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1122 && proc.pid != MY_PID) { 1123 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1124 if (res != null) { 1125 res.set(0); 1126 } 1127 return; 1128 } 1129 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1130 Dialog d = new AppErrorDialog(mContext, 1131 ActivityManagerService.this, res, proc); 1132 d.show(); 1133 proc.crashDialog = d; 1134 } else { 1135 // The device is asleep, so just pretend that the user 1136 // saw a crash dialog and hit "force quit". 1137 if (res != null) { 1138 res.set(0); 1139 } 1140 } 1141 } 1142 1143 ensureBootCompleted(); 1144 } break; 1145 case SHOW_NOT_RESPONDING_MSG: { 1146 synchronized (ActivityManagerService.this) { 1147 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1148 ProcessRecord proc = (ProcessRecord)data.get("app"); 1149 if (proc != null && proc.anrDialog != null) { 1150 Slog.e(TAG, "App already has anr dialog: " + proc); 1151 return; 1152 } 1153 1154 Intent intent = new Intent("android.intent.action.ANR"); 1155 if (!mProcessesReady) { 1156 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1157 | Intent.FLAG_RECEIVER_FOREGROUND); 1158 } 1159 broadcastIntentLocked(null, null, intent, 1160 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1161 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1162 1163 if (mShowDialogs) { 1164 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1165 mContext, proc, (ActivityRecord)data.get("activity"), 1166 msg.arg1 != 0); 1167 d.show(); 1168 proc.anrDialog = d; 1169 } else { 1170 // Just kill the app if there is no dialog to be shown. 1171 killAppAtUsersRequest(proc, null); 1172 } 1173 } 1174 1175 ensureBootCompleted(); 1176 } break; 1177 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1178 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1179 synchronized (ActivityManagerService.this) { 1180 ProcessRecord proc = (ProcessRecord) data.get("app"); 1181 if (proc == null) { 1182 Slog.e(TAG, "App not found when showing strict mode dialog."); 1183 break; 1184 } 1185 if (proc.crashDialog != null) { 1186 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1187 return; 1188 } 1189 AppErrorResult res = (AppErrorResult) data.get("result"); 1190 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1191 Dialog d = new StrictModeViolationDialog(mContext, 1192 ActivityManagerService.this, res, proc); 1193 d.show(); 1194 proc.crashDialog = d; 1195 } else { 1196 // The device is asleep, so just pretend that the user 1197 // saw a crash dialog and hit "force quit". 1198 res.set(0); 1199 } 1200 } 1201 ensureBootCompleted(); 1202 } break; 1203 case SHOW_FACTORY_ERROR_MSG: { 1204 Dialog d = new FactoryErrorDialog( 1205 mContext, msg.getData().getCharSequence("msg")); 1206 d.show(); 1207 ensureBootCompleted(); 1208 } break; 1209 case UPDATE_CONFIGURATION_MSG: { 1210 final ContentResolver resolver = mContext.getContentResolver(); 1211 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1212 } break; 1213 case GC_BACKGROUND_PROCESSES_MSG: { 1214 synchronized (ActivityManagerService.this) { 1215 performAppGcsIfAppropriateLocked(); 1216 } 1217 } break; 1218 case WAIT_FOR_DEBUGGER_MSG: { 1219 synchronized (ActivityManagerService.this) { 1220 ProcessRecord app = (ProcessRecord)msg.obj; 1221 if (msg.arg1 != 0) { 1222 if (!app.waitedForDebugger) { 1223 Dialog d = new AppWaitingForDebuggerDialog( 1224 ActivityManagerService.this, 1225 mContext, app); 1226 app.waitDialog = d; 1227 app.waitedForDebugger = true; 1228 d.show(); 1229 } 1230 } else { 1231 if (app.waitDialog != null) { 1232 app.waitDialog.dismiss(); 1233 app.waitDialog = null; 1234 } 1235 } 1236 } 1237 } break; 1238 case SERVICE_TIMEOUT_MSG: { 1239 if (mDidDexOpt) { 1240 mDidDexOpt = false; 1241 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1242 nmsg.obj = msg.obj; 1243 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1244 return; 1245 } 1246 mServices.serviceTimeout((ProcessRecord)msg.obj); 1247 } break; 1248 case UPDATE_TIME_ZONE: { 1249 synchronized (ActivityManagerService.this) { 1250 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1251 ProcessRecord r = mLruProcesses.get(i); 1252 if (r.thread != null) { 1253 try { 1254 r.thread.updateTimeZone(); 1255 } catch (RemoteException ex) { 1256 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1257 } 1258 } 1259 } 1260 } 1261 } break; 1262 case CLEAR_DNS_CACHE_MSG: { 1263 synchronized (ActivityManagerService.this) { 1264 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1265 ProcessRecord r = mLruProcesses.get(i); 1266 if (r.thread != null) { 1267 try { 1268 r.thread.clearDnsCache(); 1269 } catch (RemoteException ex) { 1270 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1271 } 1272 } 1273 } 1274 } 1275 } break; 1276 case UPDATE_HTTP_PROXY_MSG: { 1277 ProxyProperties proxy = (ProxyProperties)msg.obj; 1278 String host = ""; 1279 String port = ""; 1280 String exclList = ""; 1281 String pacFileUrl = null; 1282 if (proxy != null) { 1283 host = proxy.getHost(); 1284 port = Integer.toString(proxy.getPort()); 1285 exclList = proxy.getExclusionList(); 1286 pacFileUrl = proxy.getPacFileUrl(); 1287 } 1288 synchronized (ActivityManagerService.this) { 1289 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1290 ProcessRecord r = mLruProcesses.get(i); 1291 if (r.thread != null) { 1292 try { 1293 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1294 } catch (RemoteException ex) { 1295 Slog.w(TAG, "Failed to update http proxy for: " + 1296 r.info.processName); 1297 } 1298 } 1299 } 1300 } 1301 } break; 1302 case SHOW_UID_ERROR_MSG: { 1303 String title = "System UIDs Inconsistent"; 1304 String text = "UIDs on the system are inconsistent, you need to wipe your" 1305 + " data partition or your device will be unstable."; 1306 Log.e(TAG, title + ": " + text); 1307 if (mShowDialogs) { 1308 // XXX This is a temporary dialog, no need to localize. 1309 AlertDialog d = new BaseErrorDialog(mContext); 1310 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1311 d.setCancelable(false); 1312 d.setTitle(title); 1313 d.setMessage(text); 1314 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1315 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1316 mUidAlert = d; 1317 d.show(); 1318 } 1319 } break; 1320 case IM_FEELING_LUCKY_MSG: { 1321 if (mUidAlert != null) { 1322 mUidAlert.dismiss(); 1323 mUidAlert = null; 1324 } 1325 } break; 1326 case PROC_START_TIMEOUT_MSG: { 1327 if (mDidDexOpt) { 1328 mDidDexOpt = false; 1329 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1330 nmsg.obj = msg.obj; 1331 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1332 return; 1333 } 1334 ProcessRecord app = (ProcessRecord)msg.obj; 1335 synchronized (ActivityManagerService.this) { 1336 processStartTimedOutLocked(app); 1337 } 1338 } break; 1339 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1340 synchronized (ActivityManagerService.this) { 1341 doPendingActivityLaunchesLocked(true); 1342 } 1343 } break; 1344 case KILL_APPLICATION_MSG: { 1345 synchronized (ActivityManagerService.this) { 1346 int appid = msg.arg1; 1347 boolean restart = (msg.arg2 == 1); 1348 Bundle bundle = (Bundle)msg.obj; 1349 String pkg = bundle.getString("pkg"); 1350 String reason = bundle.getString("reason"); 1351 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1352 false, UserHandle.USER_ALL, reason); 1353 } 1354 } break; 1355 case FINALIZE_PENDING_INTENT_MSG: { 1356 ((PendingIntentRecord)msg.obj).completeFinalize(); 1357 } break; 1358 case POST_HEAVY_NOTIFICATION_MSG: { 1359 INotificationManager inm = NotificationManager.getService(); 1360 if (inm == null) { 1361 return; 1362 } 1363 1364 ActivityRecord root = (ActivityRecord)msg.obj; 1365 ProcessRecord process = root.app; 1366 if (process == null) { 1367 return; 1368 } 1369 1370 try { 1371 Context context = mContext.createPackageContext(process.info.packageName, 0); 1372 String text = mContext.getString(R.string.heavy_weight_notification, 1373 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1374 Notification notification = new Notification(); 1375 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1376 notification.when = 0; 1377 notification.flags = Notification.FLAG_ONGOING_EVENT; 1378 notification.tickerText = text; 1379 notification.defaults = 0; // please be quiet 1380 notification.sound = null; 1381 notification.vibrate = null; 1382 notification.setLatestEventInfo(context, text, 1383 mContext.getText(R.string.heavy_weight_notification_detail), 1384 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1385 PendingIntent.FLAG_CANCEL_CURRENT, null, 1386 new UserHandle(root.userId))); 1387 1388 try { 1389 int[] outId = new int[1]; 1390 inm.enqueueNotificationWithTag("android", "android", null, 1391 R.string.heavy_weight_notification, 1392 notification, outId, root.userId); 1393 } catch (RuntimeException e) { 1394 Slog.w(ActivityManagerService.TAG, 1395 "Error showing notification for heavy-weight app", e); 1396 } catch (RemoteException e) { 1397 } 1398 } catch (NameNotFoundException e) { 1399 Slog.w(TAG, "Unable to create context for heavy notification", e); 1400 } 1401 } break; 1402 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1403 INotificationManager inm = NotificationManager.getService(); 1404 if (inm == null) { 1405 return; 1406 } 1407 try { 1408 inm.cancelNotificationWithTag("android", null, 1409 R.string.heavy_weight_notification, msg.arg1); 1410 } catch (RuntimeException e) { 1411 Slog.w(ActivityManagerService.TAG, 1412 "Error canceling notification for service", e); 1413 } catch (RemoteException e) { 1414 } 1415 } break; 1416 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1417 synchronized (ActivityManagerService.this) { 1418 checkExcessivePowerUsageLocked(true); 1419 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1420 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1421 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1422 } 1423 } break; 1424 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1425 synchronized (ActivityManagerService.this) { 1426 ActivityRecord ar = (ActivityRecord)msg.obj; 1427 if (mCompatModeDialog != null) { 1428 if (mCompatModeDialog.mAppInfo.packageName.equals( 1429 ar.info.applicationInfo.packageName)) { 1430 return; 1431 } 1432 mCompatModeDialog.dismiss(); 1433 mCompatModeDialog = null; 1434 } 1435 if (ar != null && false) { 1436 if (mCompatModePackages.getPackageAskCompatModeLocked( 1437 ar.packageName)) { 1438 int mode = mCompatModePackages.computeCompatModeLocked( 1439 ar.info.applicationInfo); 1440 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1441 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1442 mCompatModeDialog = new CompatModeDialog( 1443 ActivityManagerService.this, mContext, 1444 ar.info.applicationInfo); 1445 mCompatModeDialog.show(); 1446 } 1447 } 1448 } 1449 } 1450 break; 1451 } 1452 case DISPATCH_PROCESSES_CHANGED: { 1453 dispatchProcessesChanged(); 1454 break; 1455 } 1456 case DISPATCH_PROCESS_DIED: { 1457 final int pid = msg.arg1; 1458 final int uid = msg.arg2; 1459 dispatchProcessDied(pid, uid); 1460 break; 1461 } 1462 case REPORT_MEM_USAGE_MSG: { 1463 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1464 Thread thread = new Thread() { 1465 @Override public void run() { 1466 final SparseArray<ProcessMemInfo> infoMap 1467 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1468 for (int i=0, N=memInfos.size(); i<N; i++) { 1469 ProcessMemInfo mi = memInfos.get(i); 1470 infoMap.put(mi.pid, mi); 1471 } 1472 updateCpuStatsNow(); 1473 synchronized (mProcessCpuThread) { 1474 final int N = mProcessCpuTracker.countStats(); 1475 for (int i=0; i<N; i++) { 1476 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1477 if (st.vsize > 0) { 1478 long pss = Debug.getPss(st.pid, null); 1479 if (pss > 0) { 1480 if (infoMap.indexOfKey(st.pid) < 0) { 1481 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1482 ProcessList.NATIVE_ADJ, -1, "native", null); 1483 mi.pss = pss; 1484 memInfos.add(mi); 1485 } 1486 } 1487 } 1488 } 1489 } 1490 1491 long totalPss = 0; 1492 for (int i=0, N=memInfos.size(); i<N; i++) { 1493 ProcessMemInfo mi = memInfos.get(i); 1494 if (mi.pss == 0) { 1495 mi.pss = Debug.getPss(mi.pid, null); 1496 } 1497 totalPss += mi.pss; 1498 } 1499 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1500 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1501 if (lhs.oomAdj != rhs.oomAdj) { 1502 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1503 } 1504 if (lhs.pss != rhs.pss) { 1505 return lhs.pss < rhs.pss ? 1 : -1; 1506 } 1507 return 0; 1508 } 1509 }); 1510 1511 StringBuilder tag = new StringBuilder(128); 1512 StringBuilder stack = new StringBuilder(128); 1513 tag.append("Low on memory -- "); 1514 appendMemBucket(tag, totalPss, "total", false); 1515 appendMemBucket(stack, totalPss, "total", true); 1516 1517 StringBuilder logBuilder = new StringBuilder(1024); 1518 logBuilder.append("Low on memory:\n"); 1519 1520 boolean firstLine = true; 1521 int lastOomAdj = Integer.MIN_VALUE; 1522 for (int i=0, N=memInfos.size(); i<N; i++) { 1523 ProcessMemInfo mi = memInfos.get(i); 1524 1525 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1526 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1527 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1528 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1529 if (lastOomAdj != mi.oomAdj) { 1530 lastOomAdj = mi.oomAdj; 1531 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1532 tag.append(" / "); 1533 } 1534 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1535 if (firstLine) { 1536 stack.append(":"); 1537 firstLine = false; 1538 } 1539 stack.append("\n\t at "); 1540 } else { 1541 stack.append("$"); 1542 } 1543 } else { 1544 tag.append(" "); 1545 stack.append("$"); 1546 } 1547 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1548 appendMemBucket(tag, mi.pss, mi.name, false); 1549 } 1550 appendMemBucket(stack, mi.pss, mi.name, true); 1551 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1552 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1553 stack.append("("); 1554 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1555 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1556 stack.append(DUMP_MEM_OOM_LABEL[k]); 1557 stack.append(":"); 1558 stack.append(DUMP_MEM_OOM_ADJ[k]); 1559 } 1560 } 1561 stack.append(")"); 1562 } 1563 } 1564 1565 logBuilder.append(" "); 1566 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1567 logBuilder.append(' '); 1568 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1569 logBuilder.append(' '); 1570 ProcessList.appendRamKb(logBuilder, mi.pss); 1571 logBuilder.append(" kB: "); 1572 logBuilder.append(mi.name); 1573 logBuilder.append(" ("); 1574 logBuilder.append(mi.pid); 1575 logBuilder.append(") "); 1576 logBuilder.append(mi.adjType); 1577 logBuilder.append('\n'); 1578 if (mi.adjReason != null) { 1579 logBuilder.append(" "); 1580 logBuilder.append(mi.adjReason); 1581 logBuilder.append('\n'); 1582 } 1583 } 1584 1585 logBuilder.append(" "); 1586 ProcessList.appendRamKb(logBuilder, totalPss); 1587 logBuilder.append(" kB: TOTAL\n"); 1588 1589 long[] infos = new long[Debug.MEMINFO_COUNT]; 1590 Debug.getMemInfo(infos); 1591 logBuilder.append(" MemInfo: "); 1592 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1593 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1594 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1595 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1596 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1597 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1598 logBuilder.append(" ZRAM: "); 1599 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1600 logBuilder.append(" kB RAM, "); 1601 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1602 logBuilder.append(" kB swap total, "); 1603 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1604 logBuilder.append(" kB swap free\n"); 1605 } 1606 Slog.i(TAG, logBuilder.toString()); 1607 1608 StringBuilder dropBuilder = new StringBuilder(1024); 1609 /* 1610 StringWriter oomSw = new StringWriter(); 1611 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1612 StringWriter catSw = new StringWriter(); 1613 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1614 String[] emptyArgs = new String[] { }; 1615 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1616 oomPw.flush(); 1617 String oomString = oomSw.toString(); 1618 */ 1619 dropBuilder.append(stack); 1620 dropBuilder.append('\n'); 1621 dropBuilder.append('\n'); 1622 dropBuilder.append(logBuilder); 1623 dropBuilder.append('\n'); 1624 /* 1625 dropBuilder.append(oomString); 1626 dropBuilder.append('\n'); 1627 */ 1628 StringWriter catSw = new StringWriter(); 1629 synchronized (ActivityManagerService.this) { 1630 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1631 String[] emptyArgs = new String[] { }; 1632 catPw.println(); 1633 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1634 catPw.println(); 1635 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1636 false, false, null); 1637 catPw.println(); 1638 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1639 catPw.flush(); 1640 } 1641 dropBuilder.append(catSw.toString()); 1642 addErrorToDropBox("lowmem", null, "system_server", null, 1643 null, tag.toString(), dropBuilder.toString(), null, null); 1644 //Slog.i(TAG, "Sent to dropbox:"); 1645 //Slog.i(TAG, dropBuilder.toString()); 1646 synchronized (ActivityManagerService.this) { 1647 long now = SystemClock.uptimeMillis(); 1648 if (mLastMemUsageReportTime < now) { 1649 mLastMemUsageReportTime = now; 1650 } 1651 } 1652 } 1653 }; 1654 thread.start(); 1655 break; 1656 } 1657 case REPORT_USER_SWITCH_MSG: { 1658 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1659 break; 1660 } 1661 case CONTINUE_USER_SWITCH_MSG: { 1662 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1663 break; 1664 } 1665 case USER_SWITCH_TIMEOUT_MSG: { 1666 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1667 break; 1668 } 1669 case IMMERSIVE_MODE_LOCK_MSG: { 1670 final boolean nextState = (msg.arg1 != 0); 1671 if (mUpdateLock.isHeld() != nextState) { 1672 if (DEBUG_IMMERSIVE) { 1673 final ActivityRecord r = (ActivityRecord) msg.obj; 1674 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1675 } 1676 if (nextState) { 1677 mUpdateLock.acquire(); 1678 } else { 1679 mUpdateLock.release(); 1680 } 1681 } 1682 break; 1683 } 1684 case PERSIST_URI_GRANTS_MSG: { 1685 writeGrantedUriPermissions(); 1686 break; 1687 } 1688 case REQUEST_ALL_PSS_MSG: { 1689 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1690 break; 1691 } 1692 case START_RELATED_USERS_MSG: { 1693 synchronized (ActivityManagerService.this) { 1694 startRelatedUsersLocked(); 1695 } 1696 break; 1697 } 1698 case UPDATE_TIME: { 1699 synchronized (ActivityManagerService.this) { 1700 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1701 ProcessRecord r = mLruProcesses.get(i); 1702 if (r.thread != null) { 1703 try { 1704 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1705 } catch (RemoteException ex) { 1706 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1707 } 1708 } 1709 } 1710 } 1711 break; 1712 } 1713 } 1714 } 1715 }; 1716 1717 static final int COLLECT_PSS_BG_MSG = 1; 1718 1719 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1720 @Override 1721 public void handleMessage(Message msg) { 1722 switch (msg.what) { 1723 case COLLECT_PSS_BG_MSG: { 1724 int i=0, num=0; 1725 long start = SystemClock.uptimeMillis(); 1726 long[] tmp = new long[1]; 1727 do { 1728 ProcessRecord proc; 1729 int procState; 1730 int pid; 1731 synchronized (ActivityManagerService.this) { 1732 if (i >= mPendingPssProcesses.size()) { 1733 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1734 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1735 mPendingPssProcesses.clear(); 1736 return; 1737 } 1738 proc = mPendingPssProcesses.get(i); 1739 procState = proc.pssProcState; 1740 if (proc.thread != null && procState == proc.setProcState) { 1741 pid = proc.pid; 1742 } else { 1743 proc = null; 1744 pid = 0; 1745 } 1746 i++; 1747 } 1748 if (proc != null) { 1749 long pss = Debug.getPss(pid, tmp); 1750 synchronized (ActivityManagerService.this) { 1751 if (proc.thread != null && proc.setProcState == procState 1752 && proc.pid == pid) { 1753 num++; 1754 proc.lastPssTime = SystemClock.uptimeMillis(); 1755 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1756 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1757 + ": " + pss + " lastPss=" + proc.lastPss 1758 + " state=" + ProcessList.makeProcStateString(procState)); 1759 if (proc.initialIdlePss == 0) { 1760 proc.initialIdlePss = pss; 1761 } 1762 proc.lastPss = pss; 1763 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1764 proc.lastCachedPss = pss; 1765 } 1766 } 1767 } 1768 } 1769 } while (true); 1770 } 1771 } 1772 } 1773 }; 1774 1775 public void setSystemProcess() { 1776 try { 1777 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1778 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1779 ServiceManager.addService("meminfo", new MemBinder(this)); 1780 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1781 ServiceManager.addService("dbinfo", new DbBinder(this)); 1782 if (MONITOR_CPU_USAGE) { 1783 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1784 } 1785 ServiceManager.addService("permission", new PermissionController(this)); 1786 1787 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1788 "android", STOCK_PM_FLAGS); 1789 mSystemThread.installSystemApplicationInfo(info); 1790 1791 synchronized (this) { 1792 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1793 app.persistent = true; 1794 app.pid = MY_PID; 1795 app.maxAdj = ProcessList.SYSTEM_ADJ; 1796 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1797 mProcessNames.put(app.processName, app.uid, app); 1798 synchronized (mPidsSelfLocked) { 1799 mPidsSelfLocked.put(app.pid, app); 1800 } 1801 updateLruProcessLocked(app, false, null); 1802 updateOomAdjLocked(); 1803 } 1804 } catch (PackageManager.NameNotFoundException e) { 1805 throw new RuntimeException( 1806 "Unable to find android system package", e); 1807 } 1808 } 1809 1810 public void setWindowManager(WindowManagerService wm) { 1811 mWindowManager = wm; 1812 mStackSupervisor.setWindowManager(wm); 1813 } 1814 1815 public void startObservingNativeCrashes() { 1816 final NativeCrashListener ncl = new NativeCrashListener(this); 1817 ncl.start(); 1818 } 1819 1820 public IAppOpsService getAppOpsService() { 1821 return mAppOpsService; 1822 } 1823 1824 static class MemBinder extends Binder { 1825 ActivityManagerService mActivityManagerService; 1826 MemBinder(ActivityManagerService activityManagerService) { 1827 mActivityManagerService = activityManagerService; 1828 } 1829 1830 @Override 1831 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1832 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1833 != PackageManager.PERMISSION_GRANTED) { 1834 pw.println("Permission Denial: can't dump meminfo from from pid=" 1835 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1836 + " without permission " + android.Manifest.permission.DUMP); 1837 return; 1838 } 1839 1840 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1841 } 1842 } 1843 1844 static class GraphicsBinder extends Binder { 1845 ActivityManagerService mActivityManagerService; 1846 GraphicsBinder(ActivityManagerService activityManagerService) { 1847 mActivityManagerService = activityManagerService; 1848 } 1849 1850 @Override 1851 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1852 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1853 != PackageManager.PERMISSION_GRANTED) { 1854 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1855 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1856 + " without permission " + android.Manifest.permission.DUMP); 1857 return; 1858 } 1859 1860 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1861 } 1862 } 1863 1864 static class DbBinder extends Binder { 1865 ActivityManagerService mActivityManagerService; 1866 DbBinder(ActivityManagerService activityManagerService) { 1867 mActivityManagerService = activityManagerService; 1868 } 1869 1870 @Override 1871 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1872 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1873 != PackageManager.PERMISSION_GRANTED) { 1874 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1875 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1876 + " without permission " + android.Manifest.permission.DUMP); 1877 return; 1878 } 1879 1880 mActivityManagerService.dumpDbInfo(fd, pw, args); 1881 } 1882 } 1883 1884 static class CpuBinder extends Binder { 1885 ActivityManagerService mActivityManagerService; 1886 CpuBinder(ActivityManagerService activityManagerService) { 1887 mActivityManagerService = activityManagerService; 1888 } 1889 1890 @Override 1891 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1892 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1893 != PackageManager.PERMISSION_GRANTED) { 1894 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1895 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1896 + " without permission " + android.Manifest.permission.DUMP); 1897 return; 1898 } 1899 1900 synchronized (mActivityManagerService.mProcessCpuThread) { 1901 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1902 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1903 SystemClock.uptimeMillis())); 1904 } 1905 } 1906 } 1907 1908 public static final class Lifecycle extends SystemService { 1909 private final ActivityManagerService mService; 1910 1911 public Lifecycle(Context context) { 1912 super(context); 1913 mService = new ActivityManagerService(context); 1914 } 1915 1916 @Override 1917 public void onStart() { 1918 mService.start(); 1919 } 1920 1921 public ActivityManagerService getService() { 1922 return mService; 1923 } 1924 } 1925 1926 // Note: This method is invoked on the main thread but may need to attach various 1927 // handlers to other threads. So take care to be explicit about the looper. 1928 public ActivityManagerService(Context systemContext) { 1929 mContext = systemContext; 1930 mFactoryTest = FactoryTest.getMode(); 1931 mSystemThread = ActivityThread.currentActivityThread(); 1932 1933 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1934 1935 mHandlerThread = new ServiceThread(TAG, 1936 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1937 mHandlerThread.start(); 1938 mHandler = new MainHandler(mHandlerThread.getLooper()); 1939 1940 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1941 "foreground", BROADCAST_FG_TIMEOUT, false); 1942 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1943 "background", BROADCAST_BG_TIMEOUT, true); 1944 mBroadcastQueues[0] = mFgBroadcastQueue; 1945 mBroadcastQueues[1] = mBgBroadcastQueue; 1946 1947 mServices = new ActiveServices(this); 1948 mProviderMap = new ProviderMap(this); 1949 1950 // TODO: Move creation of battery stats service outside of activity manager service. 1951 File dataDir = Environment.getDataDirectory(); 1952 File systemDir = new File(dataDir, "system"); 1953 systemDir.mkdirs(); 1954 mBatteryStatsService = new BatteryStatsService(new File( 1955 systemDir, "batterystats.bin").toString(), mHandler); 1956 mBatteryStatsService.getActiveStatistics().readLocked(); 1957 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1958 mOnBattery = DEBUG_POWER ? true 1959 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1960 mBatteryStatsService.getActiveStatistics().setCallback(this); 1961 1962 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1963 1964 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1965 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1966 1967 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1968 1969 // User 0 is the first and only user that runs at boot. 1970 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1971 mUserLru.add(Integer.valueOf(0)); 1972 updateStartedUserArrayLocked(); 1973 1974 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1975 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1976 1977 mConfiguration.setToDefaults(); 1978 mConfiguration.setLocale(Locale.getDefault()); 1979 1980 mConfigurationSeq = mConfiguration.seq = 1; 1981 mProcessCpuTracker.init(); 1982 1983 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1984 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1985 mStackSupervisor = new ActivityStackSupervisor(this); 1986 1987 mProcessCpuThread = new Thread("CpuTracker") { 1988 @Override 1989 public void run() { 1990 while (true) { 1991 try { 1992 try { 1993 synchronized(this) { 1994 final long now = SystemClock.uptimeMillis(); 1995 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1996 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1997 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1998 // + ", write delay=" + nextWriteDelay); 1999 if (nextWriteDelay < nextCpuDelay) { 2000 nextCpuDelay = nextWriteDelay; 2001 } 2002 if (nextCpuDelay > 0) { 2003 mProcessCpuMutexFree.set(true); 2004 this.wait(nextCpuDelay); 2005 } 2006 } 2007 } catch (InterruptedException e) { 2008 } 2009 updateCpuStatsNow(); 2010 } catch (Exception e) { 2011 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2012 } 2013 } 2014 } 2015 }; 2016 2017 Watchdog.getInstance().addMonitor(this); 2018 Watchdog.getInstance().addThread(mHandler); 2019 } 2020 2021 private void start() { 2022 mProcessCpuThread.start(); 2023 2024 mBatteryStatsService.publish(mContext); 2025 mUsageStatsService.publish(mContext); 2026 mAppOpsService.publish(mContext); 2027 startRunning(null, null, null, null); 2028 } 2029 2030 @Override 2031 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2032 throws RemoteException { 2033 if (code == SYSPROPS_TRANSACTION) { 2034 // We need to tell all apps about the system property change. 2035 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2036 synchronized(this) { 2037 final int NP = mProcessNames.getMap().size(); 2038 for (int ip=0; ip<NP; ip++) { 2039 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2040 final int NA = apps.size(); 2041 for (int ia=0; ia<NA; ia++) { 2042 ProcessRecord app = apps.valueAt(ia); 2043 if (app.thread != null) { 2044 procs.add(app.thread.asBinder()); 2045 } 2046 } 2047 } 2048 } 2049 2050 int N = procs.size(); 2051 for (int i=0; i<N; i++) { 2052 Parcel data2 = Parcel.obtain(); 2053 try { 2054 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2055 } catch (RemoteException e) { 2056 } 2057 data2.recycle(); 2058 } 2059 } 2060 try { 2061 return super.onTransact(code, data, reply, flags); 2062 } catch (RuntimeException e) { 2063 // The activity manager only throws security exceptions, so let's 2064 // log all others. 2065 if (!(e instanceof SecurityException)) { 2066 Slog.wtf(TAG, "Activity Manager Crash", e); 2067 } 2068 throw e; 2069 } 2070 } 2071 2072 void updateCpuStats() { 2073 final long now = SystemClock.uptimeMillis(); 2074 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2075 return; 2076 } 2077 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2078 synchronized (mProcessCpuThread) { 2079 mProcessCpuThread.notify(); 2080 } 2081 } 2082 } 2083 2084 void updateCpuStatsNow() { 2085 synchronized (mProcessCpuThread) { 2086 mProcessCpuMutexFree.set(false); 2087 final long now = SystemClock.uptimeMillis(); 2088 boolean haveNewCpuStats = false; 2089 2090 if (MONITOR_CPU_USAGE && 2091 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2092 mLastCpuTime.set(now); 2093 haveNewCpuStats = true; 2094 mProcessCpuTracker.update(); 2095 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2096 //Slog.i(TAG, "Total CPU usage: " 2097 // + mProcessCpu.getTotalCpuPercent() + "%"); 2098 2099 // Slog the cpu usage if the property is set. 2100 if ("true".equals(SystemProperties.get("events.cpu"))) { 2101 int user = mProcessCpuTracker.getLastUserTime(); 2102 int system = mProcessCpuTracker.getLastSystemTime(); 2103 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2104 int irq = mProcessCpuTracker.getLastIrqTime(); 2105 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2106 int idle = mProcessCpuTracker.getLastIdleTime(); 2107 2108 int total = user + system + iowait + irq + softIrq + idle; 2109 if (total == 0) total = 1; 2110 2111 EventLog.writeEvent(EventLogTags.CPU, 2112 ((user+system+iowait+irq+softIrq) * 100) / total, 2113 (user * 100) / total, 2114 (system * 100) / total, 2115 (iowait * 100) / total, 2116 (irq * 100) / total, 2117 (softIrq * 100) / total); 2118 } 2119 } 2120 2121 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2122 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2123 synchronized(bstats) { 2124 synchronized(mPidsSelfLocked) { 2125 if (haveNewCpuStats) { 2126 if (mOnBattery) { 2127 int perc = bstats.startAddingCpuLocked(); 2128 int totalUTime = 0; 2129 int totalSTime = 0; 2130 final int N = mProcessCpuTracker.countStats(); 2131 for (int i=0; i<N; i++) { 2132 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2133 if (!st.working) { 2134 continue; 2135 } 2136 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2137 int otherUTime = (st.rel_utime*perc)/100; 2138 int otherSTime = (st.rel_stime*perc)/100; 2139 totalUTime += otherUTime; 2140 totalSTime += otherSTime; 2141 if (pr != null) { 2142 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2143 if (ps == null || !ps.isActive()) { 2144 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2145 pr.info.uid, pr.processName); 2146 } 2147 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2148 st.rel_stime-otherSTime); 2149 ps.addSpeedStepTimes(cpuSpeedTimes); 2150 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2151 } else { 2152 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2153 if (ps == null || !ps.isActive()) { 2154 st.batteryStats = ps = bstats.getProcessStatsLocked( 2155 bstats.mapUid(st.uid), st.name); 2156 } 2157 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2158 st.rel_stime-otherSTime); 2159 ps.addSpeedStepTimes(cpuSpeedTimes); 2160 } 2161 } 2162 bstats.finishAddingCpuLocked(perc, totalUTime, 2163 totalSTime, cpuSpeedTimes); 2164 } 2165 } 2166 } 2167 2168 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2169 mLastWriteTime = now; 2170 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2171 } 2172 } 2173 } 2174 } 2175 2176 @Override 2177 public void batteryNeedsCpuUpdate() { 2178 updateCpuStatsNow(); 2179 } 2180 2181 @Override 2182 public void batteryPowerChanged(boolean onBattery) { 2183 // When plugging in, update the CPU stats first before changing 2184 // the plug state. 2185 updateCpuStatsNow(); 2186 synchronized (this) { 2187 synchronized(mPidsSelfLocked) { 2188 mOnBattery = DEBUG_POWER ? true : onBattery; 2189 } 2190 } 2191 } 2192 2193 /** 2194 * Initialize the application bind args. These are passed to each 2195 * process when the bindApplication() IPC is sent to the process. They're 2196 * lazily setup to make sure the services are running when they're asked for. 2197 */ 2198 private HashMap<String, IBinder> getCommonServicesLocked() { 2199 if (mAppBindArgs == null) { 2200 mAppBindArgs = new HashMap<String, IBinder>(); 2201 2202 // Setup the application init args 2203 mAppBindArgs.put("package", ServiceManager.getService("package")); 2204 mAppBindArgs.put("window", ServiceManager.getService("window")); 2205 mAppBindArgs.put(Context.ALARM_SERVICE, 2206 ServiceManager.getService(Context.ALARM_SERVICE)); 2207 } 2208 return mAppBindArgs; 2209 } 2210 2211 final void setFocusedActivityLocked(ActivityRecord r) { 2212 if (mFocusedActivity != r) { 2213 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2214 mFocusedActivity = r; 2215 mStackSupervisor.setFocusedStack(r); 2216 if (r != null) { 2217 mWindowManager.setFocusedApp(r.appToken, true); 2218 } 2219 applyUpdateLockStateLocked(r); 2220 } 2221 } 2222 2223 @Override 2224 public void setFocusedStack(int stackId) { 2225 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2226 synchronized (ActivityManagerService.this) { 2227 ActivityStack stack = mStackSupervisor.getStack(stackId); 2228 if (stack != null) { 2229 ActivityRecord r = stack.topRunningActivityLocked(null); 2230 if (r != null) { 2231 setFocusedActivityLocked(r); 2232 } 2233 } 2234 } 2235 } 2236 2237 @Override 2238 public void notifyActivityDrawn(IBinder token) { 2239 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2240 synchronized (this) { 2241 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2242 if (r != null) { 2243 r.task.stack.notifyActivityDrawnLocked(r); 2244 } 2245 } 2246 } 2247 2248 final void applyUpdateLockStateLocked(ActivityRecord r) { 2249 // Modifications to the UpdateLock state are done on our handler, outside 2250 // the activity manager's locks. The new state is determined based on the 2251 // state *now* of the relevant activity record. The object is passed to 2252 // the handler solely for logging detail, not to be consulted/modified. 2253 final boolean nextState = r != null && r.immersive; 2254 mHandler.sendMessage( 2255 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2256 } 2257 2258 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2259 Message msg = Message.obtain(); 2260 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2261 msg.obj = r.task.askedCompatMode ? null : r; 2262 mHandler.sendMessage(msg); 2263 } 2264 2265 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2266 String what, Object obj, ProcessRecord srcApp) { 2267 app.lastActivityTime = now; 2268 2269 if (app.activities.size() > 0) { 2270 // Don't want to touch dependent processes that are hosting activities. 2271 return index; 2272 } 2273 2274 int lrui = mLruProcesses.lastIndexOf(app); 2275 if (lrui < 0) { 2276 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2277 + what + " " + obj + " from " + srcApp); 2278 return index; 2279 } 2280 2281 if (lrui >= index) { 2282 // Don't want to cause this to move dependent processes *back* in the 2283 // list as if they were less frequently used. 2284 return index; 2285 } 2286 2287 if (lrui >= mLruProcessActivityStart) { 2288 // Don't want to touch dependent processes that are hosting activities. 2289 return index; 2290 } 2291 2292 mLruProcesses.remove(lrui); 2293 if (index > 0) { 2294 index--; 2295 } 2296 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2297 + " in LRU list: " + app); 2298 mLruProcesses.add(index, app); 2299 return index; 2300 } 2301 2302 final void removeLruProcessLocked(ProcessRecord app) { 2303 int lrui = mLruProcesses.lastIndexOf(app); 2304 if (lrui >= 0) { 2305 if (lrui <= mLruProcessActivityStart) { 2306 mLruProcessActivityStart--; 2307 } 2308 if (lrui <= mLruProcessServiceStart) { 2309 mLruProcessServiceStart--; 2310 } 2311 mLruProcesses.remove(lrui); 2312 } 2313 } 2314 2315 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2316 ProcessRecord client) { 2317 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities; 2318 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2319 if (!activityChange && hasActivity) { 2320 // The process has activties, so we are only going to allow activity-based 2321 // adjustments move it. It should be kept in the front of the list with other 2322 // processes that have activities, and we don't want those to change their 2323 // order except due to activity operations. 2324 return; 2325 } 2326 2327 mLruSeq++; 2328 final long now = SystemClock.uptimeMillis(); 2329 app.lastActivityTime = now; 2330 2331 // First a quick reject: if the app is already at the position we will 2332 // put it, then there is nothing to do. 2333 if (hasActivity) { 2334 final int N = mLruProcesses.size(); 2335 if (N > 0 && mLruProcesses.get(N-1) == app) { 2336 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2337 return; 2338 } 2339 } else { 2340 if (mLruProcessServiceStart > 0 2341 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2342 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2343 return; 2344 } 2345 } 2346 2347 int lrui = mLruProcesses.lastIndexOf(app); 2348 2349 if (app.persistent && lrui >= 0) { 2350 // We don't care about the position of persistent processes, as long as 2351 // they are in the list. 2352 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2353 return; 2354 } 2355 2356 /* In progress: compute new position first, so we can avoid doing work 2357 if the process is not actually going to move. Not yet working. 2358 int addIndex; 2359 int nextIndex; 2360 boolean inActivity = false, inService = false; 2361 if (hasActivity) { 2362 // Process has activities, put it at the very tipsy-top. 2363 addIndex = mLruProcesses.size(); 2364 nextIndex = mLruProcessServiceStart; 2365 inActivity = true; 2366 } else if (hasService) { 2367 // Process has services, put it at the top of the service list. 2368 addIndex = mLruProcessActivityStart; 2369 nextIndex = mLruProcessServiceStart; 2370 inActivity = true; 2371 inService = true; 2372 } else { 2373 // Process not otherwise of interest, it goes to the top of the non-service area. 2374 addIndex = mLruProcessServiceStart; 2375 if (client != null) { 2376 int clientIndex = mLruProcesses.lastIndexOf(client); 2377 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2378 + app); 2379 if (clientIndex >= 0 && addIndex > clientIndex) { 2380 addIndex = clientIndex; 2381 } 2382 } 2383 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2384 } 2385 2386 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2387 + mLruProcessActivityStart + "): " + app); 2388 */ 2389 2390 if (lrui >= 0) { 2391 if (lrui < mLruProcessActivityStart) { 2392 mLruProcessActivityStart--; 2393 } 2394 if (lrui < mLruProcessServiceStart) { 2395 mLruProcessServiceStart--; 2396 } 2397 /* 2398 if (addIndex > lrui) { 2399 addIndex--; 2400 } 2401 if (nextIndex > lrui) { 2402 nextIndex--; 2403 } 2404 */ 2405 mLruProcesses.remove(lrui); 2406 } 2407 2408 /* 2409 mLruProcesses.add(addIndex, app); 2410 if (inActivity) { 2411 mLruProcessActivityStart++; 2412 } 2413 if (inService) { 2414 mLruProcessActivityStart++; 2415 } 2416 */ 2417 2418 int nextIndex; 2419 if (hasActivity) { 2420 final int N = mLruProcesses.size(); 2421 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2422 // Process doesn't have activities, but has clients with 2423 // activities... move it up, but one below the top (the top 2424 // should always have a real activity). 2425 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2426 mLruProcesses.add(N-1, app); 2427 // To keep it from spamming the LRU list (by making a bunch of clients), 2428 // we will push down any other entries owned by the app. 2429 final int uid = app.info.uid; 2430 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2431 ProcessRecord subProc = mLruProcesses.get(i); 2432 if (subProc.info.uid == uid) { 2433 // We want to push this one down the list. If the process after 2434 // it is for the same uid, however, don't do so, because we don't 2435 // want them internally to be re-ordered. 2436 if (mLruProcesses.get(i-1).info.uid != uid) { 2437 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2438 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2439 ProcessRecord tmp = mLruProcesses.get(i); 2440 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2441 mLruProcesses.set(i-1, tmp); 2442 i--; 2443 } 2444 } else { 2445 // A gap, we can stop here. 2446 break; 2447 } 2448 } 2449 } else { 2450 // Process has activities, put it at the very tipsy-top. 2451 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2452 mLruProcesses.add(app); 2453 } 2454 nextIndex = mLruProcessServiceStart; 2455 } else if (hasService) { 2456 // Process has services, put it at the top of the service list. 2457 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2458 mLruProcesses.add(mLruProcessActivityStart, app); 2459 nextIndex = mLruProcessServiceStart; 2460 mLruProcessActivityStart++; 2461 } else { 2462 // Process not otherwise of interest, it goes to the top of the non-service area. 2463 int index = mLruProcessServiceStart; 2464 if (client != null) { 2465 // If there is a client, don't allow the process to be moved up higher 2466 // in the list than that client. 2467 int clientIndex = mLruProcesses.lastIndexOf(client); 2468 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2469 + " when updating " + app); 2470 if (clientIndex <= lrui) { 2471 // Don't allow the client index restriction to push it down farther in the 2472 // list than it already is. 2473 clientIndex = lrui; 2474 } 2475 if (clientIndex >= 0 && index > clientIndex) { 2476 index = clientIndex; 2477 } 2478 } 2479 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2480 mLruProcesses.add(index, app); 2481 nextIndex = index-1; 2482 mLruProcessActivityStart++; 2483 mLruProcessServiceStart++; 2484 } 2485 2486 // If the app is currently using a content provider or service, 2487 // bump those processes as well. 2488 for (int j=app.connections.size()-1; j>=0; j--) { 2489 ConnectionRecord cr = app.connections.valueAt(j); 2490 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2491 && cr.binding.service.app != null 2492 && cr.binding.service.app.lruSeq != mLruSeq 2493 && !cr.binding.service.app.persistent) { 2494 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2495 "service connection", cr, app); 2496 } 2497 } 2498 for (int j=app.conProviders.size()-1; j>=0; j--) { 2499 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2500 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2501 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2502 "provider reference", cpr, app); 2503 } 2504 } 2505 } 2506 2507 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2508 if (uid == Process.SYSTEM_UID) { 2509 // The system gets to run in any process. If there are multiple 2510 // processes with the same uid, just pick the first (this 2511 // should never happen). 2512 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2513 if (procs == null) return null; 2514 final int N = procs.size(); 2515 for (int i = 0; i < N; i++) { 2516 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2517 } 2518 } 2519 ProcessRecord proc = mProcessNames.get(processName, uid); 2520 if (false && proc != null && !keepIfLarge 2521 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2522 && proc.lastCachedPss >= 4000) { 2523 // Turn this condition on to cause killing to happen regularly, for testing. 2524 if (proc.baseProcessTracker != null) { 2525 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2526 } 2527 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2528 + "k from cached"); 2529 } else if (proc != null && !keepIfLarge 2530 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2531 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2532 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2533 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2534 if (proc.baseProcessTracker != null) { 2535 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2536 } 2537 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2538 + "k from cached"); 2539 } 2540 } 2541 return proc; 2542 } 2543 2544 void ensurePackageDexOpt(String packageName) { 2545 IPackageManager pm = AppGlobals.getPackageManager(); 2546 try { 2547 if (pm.performDexOpt(packageName)) { 2548 mDidDexOpt = true; 2549 } 2550 } catch (RemoteException e) { 2551 } 2552 } 2553 2554 boolean isNextTransitionForward() { 2555 int transit = mWindowManager.getPendingAppTransition(); 2556 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2557 || transit == AppTransition.TRANSIT_TASK_OPEN 2558 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2559 } 2560 2561 final ProcessRecord startProcessLocked(String processName, 2562 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2563 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2564 boolean isolated, boolean keepIfLarge) { 2565 ProcessRecord app; 2566 if (!isolated) { 2567 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2568 } else { 2569 // If this is an isolated process, it can't re-use an existing process. 2570 app = null; 2571 } 2572 // We don't have to do anything more if: 2573 // (1) There is an existing application record; and 2574 // (2) The caller doesn't think it is dead, OR there is no thread 2575 // object attached to it so we know it couldn't have crashed; and 2576 // (3) There is a pid assigned to it, so it is either starting or 2577 // already running. 2578 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2579 + " app=" + app + " knownToBeDead=" + knownToBeDead 2580 + " thread=" + (app != null ? app.thread : null) 2581 + " pid=" + (app != null ? app.pid : -1)); 2582 if (app != null && app.pid > 0) { 2583 if (!knownToBeDead || app.thread == null) { 2584 // We already have the app running, or are waiting for it to 2585 // come up (we have a pid but not yet its thread), so keep it. 2586 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2587 // If this is a new package in the process, add the package to the list 2588 app.addPackage(info.packageName, mProcessStats); 2589 return app; 2590 } 2591 2592 // An application record is attached to a previous process, 2593 // clean it up now. 2594 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2595 handleAppDiedLocked(app, true, true); 2596 } 2597 2598 String hostingNameStr = hostingName != null 2599 ? hostingName.flattenToShortString() : null; 2600 2601 if (!isolated) { 2602 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2603 // If we are in the background, then check to see if this process 2604 // is bad. If so, we will just silently fail. 2605 if (mBadProcesses.get(info.processName, info.uid) != null) { 2606 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2607 + "/" + info.processName); 2608 return null; 2609 } 2610 } else { 2611 // When the user is explicitly starting a process, then clear its 2612 // crash count so that we won't make it bad until they see at 2613 // least one crash dialog again, and make the process good again 2614 // if it had been bad. 2615 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2616 + "/" + info.processName); 2617 mProcessCrashTimes.remove(info.processName, info.uid); 2618 if (mBadProcesses.get(info.processName, info.uid) != null) { 2619 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2620 UserHandle.getUserId(info.uid), info.uid, 2621 info.processName); 2622 mBadProcesses.remove(info.processName, info.uid); 2623 if (app != null) { 2624 app.bad = false; 2625 } 2626 } 2627 } 2628 } 2629 2630 if (app == null) { 2631 app = newProcessRecordLocked(info, processName, isolated); 2632 if (app == null) { 2633 Slog.w(TAG, "Failed making new process record for " 2634 + processName + "/" + info.uid + " isolated=" + isolated); 2635 return null; 2636 } 2637 mProcessNames.put(processName, app.uid, app); 2638 if (isolated) { 2639 mIsolatedProcesses.put(app.uid, app); 2640 } 2641 } else { 2642 // If this is a new package in the process, add the package to the list 2643 app.addPackage(info.packageName, mProcessStats); 2644 } 2645 2646 // If the system is not ready yet, then hold off on starting this 2647 // process until it is. 2648 if (!mProcessesReady 2649 && !isAllowedWhileBooting(info) 2650 && !allowWhileBooting) { 2651 if (!mProcessesOnHold.contains(app)) { 2652 mProcessesOnHold.add(app); 2653 } 2654 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2655 return app; 2656 } 2657 2658 startProcessLocked(app, hostingType, hostingNameStr); 2659 return (app.pid != 0) ? app : null; 2660 } 2661 2662 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2663 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2664 } 2665 2666 private final void startProcessLocked(ProcessRecord app, 2667 String hostingType, String hostingNameStr) { 2668 if (app.pid > 0 && app.pid != MY_PID) { 2669 synchronized (mPidsSelfLocked) { 2670 mPidsSelfLocked.remove(app.pid); 2671 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2672 } 2673 app.setPid(0); 2674 } 2675 2676 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2677 "startProcessLocked removing on hold: " + app); 2678 mProcessesOnHold.remove(app); 2679 2680 updateCpuStats(); 2681 2682 try { 2683 int uid = app.uid; 2684 2685 int[] gids = null; 2686 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2687 if (!app.isolated) { 2688 int[] permGids = null; 2689 try { 2690 final PackageManager pm = mContext.getPackageManager(); 2691 permGids = pm.getPackageGids(app.info.packageName); 2692 2693 if (Environment.isExternalStorageEmulated()) { 2694 if (pm.checkPermission( 2695 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2696 app.info.packageName) == PERMISSION_GRANTED) { 2697 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2698 } else { 2699 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2700 } 2701 } 2702 } catch (PackageManager.NameNotFoundException e) { 2703 Slog.w(TAG, "Unable to retrieve gids", e); 2704 } 2705 2706 /* 2707 * Add shared application GID so applications can share some 2708 * resources like shared libraries 2709 */ 2710 if (permGids == null) { 2711 gids = new int[1]; 2712 } else { 2713 gids = new int[permGids.length + 1]; 2714 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2715 } 2716 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2717 } 2718 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2719 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2720 && mTopComponent != null 2721 && app.processName.equals(mTopComponent.getPackageName())) { 2722 uid = 0; 2723 } 2724 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2725 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2726 uid = 0; 2727 } 2728 } 2729 int debugFlags = 0; 2730 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2731 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2732 // Also turn on CheckJNI for debuggable apps. It's quite 2733 // awkward to turn on otherwise. 2734 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2735 } 2736 // Run the app in safe mode if its manifest requests so or the 2737 // system is booted in safe mode. 2738 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2739 Zygote.systemInSafeMode == true) { 2740 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2741 } 2742 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2743 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2744 } 2745 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2746 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2747 } 2748 if ("1".equals(SystemProperties.get("debug.assert"))) { 2749 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2750 } 2751 2752 // Start the process. It will either succeed and return a result containing 2753 // the PID of the new process, or else throw a RuntimeException. 2754 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2755 app.processName, uid, uid, gids, debugFlags, mountExternal, 2756 app.info.targetSdkVersion, app.info.seinfo, null); 2757 2758 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2759 synchronized (bs) { 2760 if (bs.isOnBattery()) { 2761 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2762 } 2763 } 2764 2765 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2766 UserHandle.getUserId(uid), startResult.pid, uid, 2767 app.processName, hostingType, 2768 hostingNameStr != null ? hostingNameStr : ""); 2769 2770 if (app.persistent) { 2771 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2772 } 2773 2774 StringBuilder buf = mStringBuilder; 2775 buf.setLength(0); 2776 buf.append("Start proc "); 2777 buf.append(app.processName); 2778 buf.append(" for "); 2779 buf.append(hostingType); 2780 if (hostingNameStr != null) { 2781 buf.append(" "); 2782 buf.append(hostingNameStr); 2783 } 2784 buf.append(": pid="); 2785 buf.append(startResult.pid); 2786 buf.append(" uid="); 2787 buf.append(uid); 2788 buf.append(" gids={"); 2789 if (gids != null) { 2790 for (int gi=0; gi<gids.length; gi++) { 2791 if (gi != 0) buf.append(", "); 2792 buf.append(gids[gi]); 2793 2794 } 2795 } 2796 buf.append("}"); 2797 Slog.i(TAG, buf.toString()); 2798 app.setPid(startResult.pid); 2799 app.usingWrapper = startResult.usingWrapper; 2800 app.removed = false; 2801 synchronized (mPidsSelfLocked) { 2802 this.mPidsSelfLocked.put(startResult.pid, app); 2803 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2804 msg.obj = app; 2805 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2806 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2807 } 2808 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2809 app.processName, app.info.uid); 2810 if (app.isolated) { 2811 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2812 } 2813 } catch (RuntimeException e) { 2814 // XXX do better error recovery. 2815 app.setPid(0); 2816 Slog.e(TAG, "Failure starting process " + app.processName, e); 2817 } 2818 } 2819 2820 void updateUsageStats(ActivityRecord component, boolean resumed) { 2821 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2822 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2823 if (resumed) { 2824 mUsageStatsService.noteResumeComponent(component.realActivity); 2825 synchronized (stats) { 2826 stats.noteActivityResumedLocked(component.app.uid); 2827 } 2828 } else { 2829 mUsageStatsService.notePauseComponent(component.realActivity); 2830 synchronized (stats) { 2831 stats.noteActivityPausedLocked(component.app.uid); 2832 } 2833 } 2834 } 2835 2836 Intent getHomeIntent() { 2837 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2838 intent.setComponent(mTopComponent); 2839 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2840 intent.addCategory(Intent.CATEGORY_HOME); 2841 } 2842 return intent; 2843 } 2844 2845 boolean startHomeActivityLocked(int userId) { 2846 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2847 && mTopAction == null) { 2848 // We are running in factory test mode, but unable to find 2849 // the factory test app, so just sit around displaying the 2850 // error message and don't try to start anything. 2851 return false; 2852 } 2853 Intent intent = getHomeIntent(); 2854 ActivityInfo aInfo = 2855 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2856 if (aInfo != null) { 2857 intent.setComponent(new ComponentName( 2858 aInfo.applicationInfo.packageName, aInfo.name)); 2859 // Don't do this if the home app is currently being 2860 // instrumented. 2861 aInfo = new ActivityInfo(aInfo); 2862 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2863 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2864 aInfo.applicationInfo.uid, true); 2865 if (app == null || app.instrumentationClass == null) { 2866 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2867 mStackSupervisor.startHomeActivity(intent, aInfo); 2868 } 2869 } 2870 2871 return true; 2872 } 2873 2874 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2875 ActivityInfo ai = null; 2876 ComponentName comp = intent.getComponent(); 2877 try { 2878 if (comp != null) { 2879 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2880 } else { 2881 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2882 intent, 2883 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2884 flags, userId); 2885 2886 if (info != null) { 2887 ai = info.activityInfo; 2888 } 2889 } 2890 } catch (RemoteException e) { 2891 // ignore 2892 } 2893 2894 return ai; 2895 } 2896 2897 /** 2898 * Starts the "new version setup screen" if appropriate. 2899 */ 2900 void startSetupActivityLocked() { 2901 // Only do this once per boot. 2902 if (mCheckedForSetup) { 2903 return; 2904 } 2905 2906 // We will show this screen if the current one is a different 2907 // version than the last one shown, and we are not running in 2908 // low-level factory test mode. 2909 final ContentResolver resolver = mContext.getContentResolver(); 2910 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2911 Settings.Global.getInt(resolver, 2912 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2913 mCheckedForSetup = true; 2914 2915 // See if we should be showing the platform update setup UI. 2916 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2917 List<ResolveInfo> ris = mContext.getPackageManager() 2918 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2919 2920 // We don't allow third party apps to replace this. 2921 ResolveInfo ri = null; 2922 for (int i=0; ris != null && i<ris.size(); i++) { 2923 if ((ris.get(i).activityInfo.applicationInfo.flags 2924 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2925 ri = ris.get(i); 2926 break; 2927 } 2928 } 2929 2930 if (ri != null) { 2931 String vers = ri.activityInfo.metaData != null 2932 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2933 : null; 2934 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2935 vers = ri.activityInfo.applicationInfo.metaData.getString( 2936 Intent.METADATA_SETUP_VERSION); 2937 } 2938 String lastVers = Settings.Secure.getString( 2939 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2940 if (vers != null && !vers.equals(lastVers)) { 2941 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2942 intent.setComponent(new ComponentName( 2943 ri.activityInfo.packageName, ri.activityInfo.name)); 2944 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2945 null, null, 0, 0, 0, null, 0, null, false, null, null); 2946 } 2947 } 2948 } 2949 } 2950 2951 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2952 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2953 } 2954 2955 void enforceNotIsolatedCaller(String caller) { 2956 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2957 throw new SecurityException("Isolated process not allowed to call " + caller); 2958 } 2959 } 2960 2961 @Override 2962 public int getFrontActivityScreenCompatMode() { 2963 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2964 synchronized (this) { 2965 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2966 } 2967 } 2968 2969 @Override 2970 public void setFrontActivityScreenCompatMode(int mode) { 2971 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2972 "setFrontActivityScreenCompatMode"); 2973 synchronized (this) { 2974 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2975 } 2976 } 2977 2978 @Override 2979 public int getPackageScreenCompatMode(String packageName) { 2980 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2981 synchronized (this) { 2982 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2983 } 2984 } 2985 2986 @Override 2987 public void setPackageScreenCompatMode(String packageName, int mode) { 2988 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2989 "setPackageScreenCompatMode"); 2990 synchronized (this) { 2991 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2992 } 2993 } 2994 2995 @Override 2996 public boolean getPackageAskScreenCompat(String packageName) { 2997 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2998 synchronized (this) { 2999 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3000 } 3001 } 3002 3003 @Override 3004 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3005 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3006 "setPackageAskScreenCompat"); 3007 synchronized (this) { 3008 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3009 } 3010 } 3011 3012 private void dispatchProcessesChanged() { 3013 int N; 3014 synchronized (this) { 3015 N = mPendingProcessChanges.size(); 3016 if (mActiveProcessChanges.length < N) { 3017 mActiveProcessChanges = new ProcessChangeItem[N]; 3018 } 3019 mPendingProcessChanges.toArray(mActiveProcessChanges); 3020 mAvailProcessChanges.addAll(mPendingProcessChanges); 3021 mPendingProcessChanges.clear(); 3022 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3023 } 3024 3025 int i = mProcessObservers.beginBroadcast(); 3026 while (i > 0) { 3027 i--; 3028 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3029 if (observer != null) { 3030 try { 3031 for (int j=0; j<N; j++) { 3032 ProcessChangeItem item = mActiveProcessChanges[j]; 3033 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3034 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3035 + item.pid + " uid=" + item.uid + ": " 3036 + item.foregroundActivities); 3037 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3038 item.foregroundActivities); 3039 } 3040 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3041 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3042 + item.pid + " uid=" + item.uid + ": " + item.importance); 3043 observer.onImportanceChanged(item.pid, item.uid, 3044 item.importance); 3045 } 3046 } 3047 } catch (RemoteException e) { 3048 } 3049 } 3050 } 3051 mProcessObservers.finishBroadcast(); 3052 } 3053 3054 private void dispatchProcessDied(int pid, int uid) { 3055 int i = mProcessObservers.beginBroadcast(); 3056 while (i > 0) { 3057 i--; 3058 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3059 if (observer != null) { 3060 try { 3061 observer.onProcessDied(pid, uid); 3062 } catch (RemoteException e) { 3063 } 3064 } 3065 } 3066 mProcessObservers.finishBroadcast(); 3067 } 3068 3069 final void doPendingActivityLaunchesLocked(boolean doResume) { 3070 final int N = mPendingActivityLaunches.size(); 3071 if (N <= 0) { 3072 return; 3073 } 3074 for (int i=0; i<N; i++) { 3075 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3076 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3077 doResume && i == (N-1), null); 3078 } 3079 mPendingActivityLaunches.clear(); 3080 } 3081 3082 @Override 3083 public final int startActivity(IApplicationThread caller, String callingPackage, 3084 Intent intent, String resolvedType, IBinder resultTo, 3085 String resultWho, int requestCode, int startFlags, 3086 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3087 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3088 resultWho, requestCode, 3089 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3090 } 3091 3092 @Override 3093 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3094 Intent intent, String resolvedType, IBinder resultTo, 3095 String resultWho, int requestCode, int startFlags, 3096 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3097 enforceNotIsolatedCaller("startActivity"); 3098 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3099 false, true, "startActivity", null); 3100 // TODO: Switch to user app stacks here. 3101 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3102 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3103 null, null, options, userId, null); 3104 } 3105 3106 @Override 3107 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3108 Intent intent, String resolvedType, IBinder resultTo, 3109 String resultWho, int requestCode, int startFlags, String profileFile, 3110 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3111 enforceNotIsolatedCaller("startActivityAndWait"); 3112 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3113 false, true, "startActivityAndWait", null); 3114 WaitResult res = new WaitResult(); 3115 // TODO: Switch to user app stacks here. 3116 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3117 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3118 res, null, options, UserHandle.getCallingUserId(), null); 3119 return res; 3120 } 3121 3122 @Override 3123 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3124 Intent intent, String resolvedType, IBinder resultTo, 3125 String resultWho, int requestCode, int startFlags, Configuration config, 3126 Bundle options, int userId) { 3127 enforceNotIsolatedCaller("startActivityWithConfig"); 3128 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3129 false, true, "startActivityWithConfig", null); 3130 // TODO: Switch to user app stacks here. 3131 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3132 resolvedType, resultTo, resultWho, requestCode, startFlags, 3133 null, null, null, config, options, userId, null); 3134 return ret; 3135 } 3136 3137 @Override 3138 public int startActivityIntentSender(IApplicationThread caller, 3139 IntentSender intent, Intent fillInIntent, String resolvedType, 3140 IBinder resultTo, String resultWho, int requestCode, 3141 int flagsMask, int flagsValues, Bundle options) { 3142 enforceNotIsolatedCaller("startActivityIntentSender"); 3143 // Refuse possible leaked file descriptors 3144 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3145 throw new IllegalArgumentException("File descriptors passed in Intent"); 3146 } 3147 3148 IIntentSender sender = intent.getTarget(); 3149 if (!(sender instanceof PendingIntentRecord)) { 3150 throw new IllegalArgumentException("Bad PendingIntent object"); 3151 } 3152 3153 PendingIntentRecord pir = (PendingIntentRecord)sender; 3154 3155 synchronized (this) { 3156 // If this is coming from the currently resumed activity, it is 3157 // effectively saying that app switches are allowed at this point. 3158 final ActivityStack stack = getFocusedStack(); 3159 if (stack.mResumedActivity != null && 3160 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3161 mAppSwitchesAllowedTime = 0; 3162 } 3163 } 3164 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3165 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3166 return ret; 3167 } 3168 3169 @Override 3170 public boolean startNextMatchingActivity(IBinder callingActivity, 3171 Intent intent, Bundle options) { 3172 // Refuse possible leaked file descriptors 3173 if (intent != null && intent.hasFileDescriptors() == true) { 3174 throw new IllegalArgumentException("File descriptors passed in Intent"); 3175 } 3176 3177 synchronized (this) { 3178 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3179 if (r == null) { 3180 ActivityOptions.abort(options); 3181 return false; 3182 } 3183 if (r.app == null || r.app.thread == null) { 3184 // The caller is not running... d'oh! 3185 ActivityOptions.abort(options); 3186 return false; 3187 } 3188 intent = new Intent(intent); 3189 // The caller is not allowed to change the data. 3190 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3191 // And we are resetting to find the next component... 3192 intent.setComponent(null); 3193 3194 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3195 3196 ActivityInfo aInfo = null; 3197 try { 3198 List<ResolveInfo> resolves = 3199 AppGlobals.getPackageManager().queryIntentActivities( 3200 intent, r.resolvedType, 3201 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3202 UserHandle.getCallingUserId()); 3203 3204 // Look for the original activity in the list... 3205 final int N = resolves != null ? resolves.size() : 0; 3206 for (int i=0; i<N; i++) { 3207 ResolveInfo rInfo = resolves.get(i); 3208 if (rInfo.activityInfo.packageName.equals(r.packageName) 3209 && rInfo.activityInfo.name.equals(r.info.name)) { 3210 // We found the current one... the next matching is 3211 // after it. 3212 i++; 3213 if (i<N) { 3214 aInfo = resolves.get(i).activityInfo; 3215 } 3216 if (debug) { 3217 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3218 + "/" + r.info.name); 3219 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3220 + "/" + aInfo.name); 3221 } 3222 break; 3223 } 3224 } 3225 } catch (RemoteException e) { 3226 } 3227 3228 if (aInfo == null) { 3229 // Nobody who is next! 3230 ActivityOptions.abort(options); 3231 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3232 return false; 3233 } 3234 3235 intent.setComponent(new ComponentName( 3236 aInfo.applicationInfo.packageName, aInfo.name)); 3237 intent.setFlags(intent.getFlags()&~( 3238 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3239 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3240 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3241 Intent.FLAG_ACTIVITY_NEW_TASK)); 3242 3243 // Okay now we need to start the new activity, replacing the 3244 // currently running activity. This is a little tricky because 3245 // we want to start the new one as if the current one is finished, 3246 // but not finish the current one first so that there is no flicker. 3247 // And thus... 3248 final boolean wasFinishing = r.finishing; 3249 r.finishing = true; 3250 3251 // Propagate reply information over to the new activity. 3252 final ActivityRecord resultTo = r.resultTo; 3253 final String resultWho = r.resultWho; 3254 final int requestCode = r.requestCode; 3255 r.resultTo = null; 3256 if (resultTo != null) { 3257 resultTo.removeResultsLocked(r, resultWho, requestCode); 3258 } 3259 3260 final long origId = Binder.clearCallingIdentity(); 3261 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3262 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3263 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3264 options, false, null, null); 3265 Binder.restoreCallingIdentity(origId); 3266 3267 r.finishing = wasFinishing; 3268 if (res != ActivityManager.START_SUCCESS) { 3269 return false; 3270 } 3271 return true; 3272 } 3273 } 3274 3275 final int startActivityInPackage(int uid, String callingPackage, 3276 Intent intent, String resolvedType, IBinder resultTo, 3277 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3278 IActivityContainer container) { 3279 3280 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3281 false, true, "startActivityInPackage", null); 3282 3283 // TODO: Switch to user app stacks here. 3284 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3285 resultTo, resultWho, requestCode, startFlags, 3286 null, null, null, null, options, userId, container); 3287 return ret; 3288 } 3289 3290 @Override 3291 public final int startActivities(IApplicationThread caller, String callingPackage, 3292 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3293 int userId) { 3294 enforceNotIsolatedCaller("startActivities"); 3295 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3296 false, true, "startActivity", null); 3297 // TODO: Switch to user app stacks here. 3298 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3299 resolvedTypes, resultTo, options, userId); 3300 return ret; 3301 } 3302 3303 final int startActivitiesInPackage(int uid, String callingPackage, 3304 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3305 Bundle options, int userId) { 3306 3307 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3308 false, true, "startActivityInPackage", null); 3309 // TODO: Switch to user app stacks here. 3310 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3311 resultTo, options, userId); 3312 return ret; 3313 } 3314 3315 final void addRecentTaskLocked(TaskRecord task) { 3316 int N = mRecentTasks.size(); 3317 // Quick case: check if the top-most recent task is the same. 3318 if (N > 0 && mRecentTasks.get(0) == task) { 3319 return; 3320 } 3321 // Remove any existing entries that are the same kind of task. 3322 for (int i=0; i<N; i++) { 3323 TaskRecord tr = mRecentTasks.get(i); 3324 if (task.userId == tr.userId 3325 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 3326 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 3327 tr.disposeThumbnail(); 3328 mRecentTasks.remove(i); 3329 i--; 3330 N--; 3331 if (task.intent == null) { 3332 // If the new recent task we are adding is not fully 3333 // specified, then replace it with the existing recent task. 3334 task = tr; 3335 } 3336 } 3337 } 3338 if (N >= MAX_RECENT_TASKS) { 3339 mRecentTasks.remove(N-1).disposeThumbnail(); 3340 } 3341 mRecentTasks.add(0, task); 3342 } 3343 3344 @Override 3345 public void reportActivityFullyDrawn(IBinder token) { 3346 synchronized (this) { 3347 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3348 if (r == null) { 3349 return; 3350 } 3351 r.reportFullyDrawnLocked(); 3352 } 3353 } 3354 3355 @Override 3356 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3357 synchronized (this) { 3358 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3359 if (r == null) { 3360 return; 3361 } 3362 final long origId = Binder.clearCallingIdentity(); 3363 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3364 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3365 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3366 if (config != null) { 3367 r.frozenBeforeDestroy = true; 3368 if (!updateConfigurationLocked(config, r, false, false)) { 3369 mStackSupervisor.resumeTopActivitiesLocked(); 3370 } 3371 } 3372 Binder.restoreCallingIdentity(origId); 3373 } 3374 } 3375 3376 @Override 3377 public int getRequestedOrientation(IBinder token) { 3378 synchronized (this) { 3379 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3380 if (r == null) { 3381 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3382 } 3383 return mWindowManager.getAppOrientation(r.appToken); 3384 } 3385 } 3386 3387 /** 3388 * This is the internal entry point for handling Activity.finish(). 3389 * 3390 * @param token The Binder token referencing the Activity we want to finish. 3391 * @param resultCode Result code, if any, from this Activity. 3392 * @param resultData Result data (Intent), if any, from this Activity. 3393 * 3394 * @return Returns true if the activity successfully finished, or false if it is still running. 3395 */ 3396 @Override 3397 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3398 // Refuse possible leaked file descriptors 3399 if (resultData != null && resultData.hasFileDescriptors() == true) { 3400 throw new IllegalArgumentException("File descriptors passed in Intent"); 3401 } 3402 3403 synchronized(this) { 3404 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3405 if (r == null) { 3406 return true; 3407 } 3408 if (mController != null) { 3409 // Find the first activity that is not finishing. 3410 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3411 if (next != null) { 3412 // ask watcher if this is allowed 3413 boolean resumeOK = true; 3414 try { 3415 resumeOK = mController.activityResuming(next.packageName); 3416 } catch (RemoteException e) { 3417 mController = null; 3418 Watchdog.getInstance().setActivityController(null); 3419 } 3420 3421 if (!resumeOK) { 3422 return false; 3423 } 3424 } 3425 } 3426 final long origId = Binder.clearCallingIdentity(); 3427 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3428 resultData, "app-request", true); 3429 Binder.restoreCallingIdentity(origId); 3430 return res; 3431 } 3432 } 3433 3434 @Override 3435 public final void finishHeavyWeightApp() { 3436 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3437 != PackageManager.PERMISSION_GRANTED) { 3438 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3439 + Binder.getCallingPid() 3440 + ", uid=" + Binder.getCallingUid() 3441 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3442 Slog.w(TAG, msg); 3443 throw new SecurityException(msg); 3444 } 3445 3446 synchronized(this) { 3447 if (mHeavyWeightProcess == null) { 3448 return; 3449 } 3450 3451 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3452 mHeavyWeightProcess.activities); 3453 for (int i=0; i<activities.size(); i++) { 3454 ActivityRecord r = activities.get(i); 3455 if (!r.finishing) { 3456 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3457 null, "finish-heavy", true); 3458 } 3459 } 3460 3461 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3462 mHeavyWeightProcess.userId, 0)); 3463 mHeavyWeightProcess = null; 3464 } 3465 } 3466 3467 @Override 3468 public void crashApplication(int uid, int initialPid, String packageName, 3469 String message) { 3470 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3471 != PackageManager.PERMISSION_GRANTED) { 3472 String msg = "Permission Denial: crashApplication() from pid=" 3473 + Binder.getCallingPid() 3474 + ", uid=" + Binder.getCallingUid() 3475 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3476 Slog.w(TAG, msg); 3477 throw new SecurityException(msg); 3478 } 3479 3480 synchronized(this) { 3481 ProcessRecord proc = null; 3482 3483 // Figure out which process to kill. We don't trust that initialPid 3484 // still has any relation to current pids, so must scan through the 3485 // list. 3486 synchronized (mPidsSelfLocked) { 3487 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3488 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3489 if (p.uid != uid) { 3490 continue; 3491 } 3492 if (p.pid == initialPid) { 3493 proc = p; 3494 break; 3495 } 3496 if (p.pkgList.containsKey(packageName)) { 3497 proc = p; 3498 } 3499 } 3500 } 3501 3502 if (proc == null) { 3503 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3504 + " initialPid=" + initialPid 3505 + " packageName=" + packageName); 3506 return; 3507 } 3508 3509 if (proc.thread != null) { 3510 if (proc.pid == Process.myPid()) { 3511 Log.w(TAG, "crashApplication: trying to crash self!"); 3512 return; 3513 } 3514 long ident = Binder.clearCallingIdentity(); 3515 try { 3516 proc.thread.scheduleCrash(message); 3517 } catch (RemoteException e) { 3518 } 3519 Binder.restoreCallingIdentity(ident); 3520 } 3521 } 3522 } 3523 3524 @Override 3525 public final void finishSubActivity(IBinder token, String resultWho, 3526 int requestCode) { 3527 synchronized(this) { 3528 final long origId = Binder.clearCallingIdentity(); 3529 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3530 if (r != null) { 3531 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3532 } 3533 Binder.restoreCallingIdentity(origId); 3534 } 3535 } 3536 3537 @Override 3538 public boolean finishActivityAffinity(IBinder token) { 3539 synchronized(this) { 3540 final long origId = Binder.clearCallingIdentity(); 3541 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3542 boolean res = false; 3543 if (r != null) { 3544 res = r.task.stack.finishActivityAffinityLocked(r); 3545 } 3546 Binder.restoreCallingIdentity(origId); 3547 return res; 3548 } 3549 } 3550 3551 @Override 3552 public boolean willActivityBeVisible(IBinder token) { 3553 synchronized(this) { 3554 ActivityStack stack = ActivityRecord.getStackLocked(token); 3555 if (stack != null) { 3556 return stack.willActivityBeVisibleLocked(token); 3557 } 3558 return false; 3559 } 3560 } 3561 3562 @Override 3563 public void overridePendingTransition(IBinder token, String packageName, 3564 int enterAnim, int exitAnim) { 3565 synchronized(this) { 3566 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3567 if (self == null) { 3568 return; 3569 } 3570 3571 final long origId = Binder.clearCallingIdentity(); 3572 3573 if (self.state == ActivityState.RESUMED 3574 || self.state == ActivityState.PAUSING) { 3575 mWindowManager.overridePendingAppTransition(packageName, 3576 enterAnim, exitAnim, null); 3577 } 3578 3579 Binder.restoreCallingIdentity(origId); 3580 } 3581 } 3582 3583 /** 3584 * Main function for removing an existing process from the activity manager 3585 * as a result of that process going away. Clears out all connections 3586 * to the process. 3587 */ 3588 private final void handleAppDiedLocked(ProcessRecord app, 3589 boolean restarting, boolean allowRestart) { 3590 int pid = app.pid; 3591 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3592 if (!restarting) { 3593 removeLruProcessLocked(app); 3594 if (pid > 0) { 3595 ProcessList.remove(pid); 3596 } 3597 } 3598 3599 if (mProfileProc == app) { 3600 clearProfilerLocked(); 3601 } 3602 3603 // Remove this application's activities from active lists. 3604 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3605 3606 app.activities.clear(); 3607 3608 if (app.instrumentationClass != null) { 3609 Slog.w(TAG, "Crash of app " + app.processName 3610 + " running instrumentation " + app.instrumentationClass); 3611 Bundle info = new Bundle(); 3612 info.putString("shortMsg", "Process crashed."); 3613 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3614 } 3615 3616 if (!restarting) { 3617 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3618 // If there was nothing to resume, and we are not already 3619 // restarting this process, but there is a visible activity that 3620 // is hosted by the process... then make sure all visible 3621 // activities are running, taking care of restarting this 3622 // process. 3623 if (hasVisibleActivities) { 3624 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3625 } 3626 } 3627 } 3628 } 3629 3630 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3631 IBinder threadBinder = thread.asBinder(); 3632 // Find the application record. 3633 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3634 ProcessRecord rec = mLruProcesses.get(i); 3635 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3636 return i; 3637 } 3638 } 3639 return -1; 3640 } 3641 3642 final ProcessRecord getRecordForAppLocked( 3643 IApplicationThread thread) { 3644 if (thread == null) { 3645 return null; 3646 } 3647 3648 int appIndex = getLRURecordIndexForAppLocked(thread); 3649 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3650 } 3651 3652 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3653 // If there are no longer any background processes running, 3654 // and the app that died was not running instrumentation, 3655 // then tell everyone we are now low on memory. 3656 boolean haveBg = false; 3657 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3658 ProcessRecord rec = mLruProcesses.get(i); 3659 if (rec.thread != null 3660 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3661 haveBg = true; 3662 break; 3663 } 3664 } 3665 3666 if (!haveBg) { 3667 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3668 if (doReport) { 3669 long now = SystemClock.uptimeMillis(); 3670 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3671 doReport = false; 3672 } else { 3673 mLastMemUsageReportTime = now; 3674 } 3675 } 3676 final ArrayList<ProcessMemInfo> memInfos 3677 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3678 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3679 long now = SystemClock.uptimeMillis(); 3680 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3681 ProcessRecord rec = mLruProcesses.get(i); 3682 if (rec == dyingProc || rec.thread == null) { 3683 continue; 3684 } 3685 if (doReport) { 3686 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3687 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3688 } 3689 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3690 // The low memory report is overriding any current 3691 // state for a GC request. Make sure to do 3692 // heavy/important/visible/foreground processes first. 3693 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3694 rec.lastRequestedGc = 0; 3695 } else { 3696 rec.lastRequestedGc = rec.lastLowMemory; 3697 } 3698 rec.reportLowMemory = true; 3699 rec.lastLowMemory = now; 3700 mProcessesToGc.remove(rec); 3701 addProcessToGcListLocked(rec); 3702 } 3703 } 3704 if (doReport) { 3705 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3706 mHandler.sendMessage(msg); 3707 } 3708 scheduleAppGcsLocked(); 3709 } 3710 } 3711 3712 final void appDiedLocked(ProcessRecord app, int pid, 3713 IApplicationThread thread) { 3714 3715 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3716 synchronized (stats) { 3717 stats.noteProcessDiedLocked(app.info.uid, pid); 3718 } 3719 3720 // Clean up already done if the process has been re-started. 3721 if (app.pid == pid && app.thread != null && 3722 app.thread.asBinder() == thread.asBinder()) { 3723 boolean doLowMem = app.instrumentationClass == null; 3724 boolean doOomAdj = doLowMem; 3725 if (!app.killedByAm) { 3726 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3727 + ") has died."); 3728 mAllowLowerMemLevel = true; 3729 } else { 3730 // Note that we always want to do oom adj to update our state with the 3731 // new number of procs. 3732 mAllowLowerMemLevel = false; 3733 doLowMem = false; 3734 } 3735 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3736 if (DEBUG_CLEANUP) Slog.v( 3737 TAG, "Dying app: " + app + ", pid: " + pid 3738 + ", thread: " + thread.asBinder()); 3739 handleAppDiedLocked(app, false, true); 3740 3741 if (doOomAdj) { 3742 updateOomAdjLocked(); 3743 } 3744 if (doLowMem) { 3745 doLowMemReportIfNeededLocked(app); 3746 } 3747 } else if (app.pid != pid) { 3748 // A new process has already been started. 3749 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3750 + ") has died and restarted (pid " + app.pid + ")."); 3751 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3752 } else if (DEBUG_PROCESSES) { 3753 Slog.d(TAG, "Received spurious death notification for thread " 3754 + thread.asBinder()); 3755 } 3756 } 3757 3758 /** 3759 * If a stack trace dump file is configured, dump process stack traces. 3760 * @param clearTraces causes the dump file to be erased prior to the new 3761 * traces being written, if true; when false, the new traces will be 3762 * appended to any existing file content. 3763 * @param firstPids of dalvik VM processes to dump stack traces for first 3764 * @param lastPids of dalvik VM processes to dump stack traces for last 3765 * @param nativeProcs optional list of native process names to dump stack crawls 3766 * @return file containing stack traces, or null if no dump file is configured 3767 */ 3768 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3769 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3770 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3771 if (tracesPath == null || tracesPath.length() == 0) { 3772 return null; 3773 } 3774 3775 File tracesFile = new File(tracesPath); 3776 try { 3777 File tracesDir = tracesFile.getParentFile(); 3778 if (!tracesDir.exists()) { 3779 tracesFile.mkdirs(); 3780 if (!SELinux.restorecon(tracesDir)) { 3781 return null; 3782 } 3783 } 3784 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3785 3786 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3787 tracesFile.createNewFile(); 3788 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3789 } catch (IOException e) { 3790 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3791 return null; 3792 } 3793 3794 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3795 return tracesFile; 3796 } 3797 3798 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3799 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3800 // Use a FileObserver to detect when traces finish writing. 3801 // The order of traces is considered important to maintain for legibility. 3802 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3803 @Override 3804 public synchronized void onEvent(int event, String path) { notify(); } 3805 }; 3806 3807 try { 3808 observer.startWatching(); 3809 3810 // First collect all of the stacks of the most important pids. 3811 if (firstPids != null) { 3812 try { 3813 int num = firstPids.size(); 3814 for (int i = 0; i < num; i++) { 3815 synchronized (observer) { 3816 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3817 observer.wait(200); // Wait for write-close, give up after 200msec 3818 } 3819 } 3820 } catch (InterruptedException e) { 3821 Log.wtf(TAG, e); 3822 } 3823 } 3824 3825 // Next collect the stacks of the native pids 3826 if (nativeProcs != null) { 3827 int[] pids = Process.getPidsForCommands(nativeProcs); 3828 if (pids != null) { 3829 for (int pid : pids) { 3830 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3831 } 3832 } 3833 } 3834 3835 // Lastly, measure CPU usage. 3836 if (processCpuTracker != null) { 3837 processCpuTracker.init(); 3838 System.gc(); 3839 processCpuTracker.update(); 3840 try { 3841 synchronized (processCpuTracker) { 3842 processCpuTracker.wait(500); // measure over 1/2 second. 3843 } 3844 } catch (InterruptedException e) { 3845 } 3846 processCpuTracker.update(); 3847 3848 // We'll take the stack crawls of just the top apps using CPU. 3849 final int N = processCpuTracker.countWorkingStats(); 3850 int numProcs = 0; 3851 for (int i=0; i<N && numProcs<5; i++) { 3852 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3853 if (lastPids.indexOfKey(stats.pid) >= 0) { 3854 numProcs++; 3855 try { 3856 synchronized (observer) { 3857 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3858 observer.wait(200); // Wait for write-close, give up after 200msec 3859 } 3860 } catch (InterruptedException e) { 3861 Log.wtf(TAG, e); 3862 } 3863 3864 } 3865 } 3866 } 3867 } finally { 3868 observer.stopWatching(); 3869 } 3870 } 3871 3872 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3873 if (true || IS_USER_BUILD) { 3874 return; 3875 } 3876 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3877 if (tracesPath == null || tracesPath.length() == 0) { 3878 return; 3879 } 3880 3881 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3882 StrictMode.allowThreadDiskWrites(); 3883 try { 3884 final File tracesFile = new File(tracesPath); 3885 final File tracesDir = tracesFile.getParentFile(); 3886 final File tracesTmp = new File(tracesDir, "__tmp__"); 3887 try { 3888 if (!tracesDir.exists()) { 3889 tracesFile.mkdirs(); 3890 if (!SELinux.restorecon(tracesDir.getPath())) { 3891 return; 3892 } 3893 } 3894 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3895 3896 if (tracesFile.exists()) { 3897 tracesTmp.delete(); 3898 tracesFile.renameTo(tracesTmp); 3899 } 3900 StringBuilder sb = new StringBuilder(); 3901 Time tobj = new Time(); 3902 tobj.set(System.currentTimeMillis()); 3903 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3904 sb.append(": "); 3905 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3906 sb.append(" since "); 3907 sb.append(msg); 3908 FileOutputStream fos = new FileOutputStream(tracesFile); 3909 fos.write(sb.toString().getBytes()); 3910 if (app == null) { 3911 fos.write("\n*** No application process!".getBytes()); 3912 } 3913 fos.close(); 3914 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3915 } catch (IOException e) { 3916 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3917 return; 3918 } 3919 3920 if (app != null) { 3921 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3922 firstPids.add(app.pid); 3923 dumpStackTraces(tracesPath, firstPids, null, null, null); 3924 } 3925 3926 File lastTracesFile = null; 3927 File curTracesFile = null; 3928 for (int i=9; i>=0; i--) { 3929 String name = String.format(Locale.US, "slow%02d.txt", i); 3930 curTracesFile = new File(tracesDir, name); 3931 if (curTracesFile.exists()) { 3932 if (lastTracesFile != null) { 3933 curTracesFile.renameTo(lastTracesFile); 3934 } else { 3935 curTracesFile.delete(); 3936 } 3937 } 3938 lastTracesFile = curTracesFile; 3939 } 3940 tracesFile.renameTo(curTracesFile); 3941 if (tracesTmp.exists()) { 3942 tracesTmp.renameTo(tracesFile); 3943 } 3944 } finally { 3945 StrictMode.setThreadPolicy(oldPolicy); 3946 } 3947 } 3948 3949 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3950 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3951 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3952 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3953 3954 if (mController != null) { 3955 try { 3956 // 0 == continue, -1 = kill process immediately 3957 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3958 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3959 } catch (RemoteException e) { 3960 mController = null; 3961 Watchdog.getInstance().setActivityController(null); 3962 } 3963 } 3964 3965 long anrTime = SystemClock.uptimeMillis(); 3966 if (MONITOR_CPU_USAGE) { 3967 updateCpuStatsNow(); 3968 } 3969 3970 synchronized (this) { 3971 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3972 if (mShuttingDown) { 3973 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3974 return; 3975 } else if (app.notResponding) { 3976 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3977 return; 3978 } else if (app.crashing) { 3979 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3980 return; 3981 } 3982 3983 // In case we come through here for the same app before completing 3984 // this one, mark as anring now so we will bail out. 3985 app.notResponding = true; 3986 3987 // Log the ANR to the event log. 3988 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3989 app.processName, app.info.flags, annotation); 3990 3991 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3992 firstPids.add(app.pid); 3993 3994 int parentPid = app.pid; 3995 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3996 if (parentPid != app.pid) firstPids.add(parentPid); 3997 3998 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3999 4000 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4001 ProcessRecord r = mLruProcesses.get(i); 4002 if (r != null && r.thread != null) { 4003 int pid = r.pid; 4004 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4005 if (r.persistent) { 4006 firstPids.add(pid); 4007 } else { 4008 lastPids.put(pid, Boolean.TRUE); 4009 } 4010 } 4011 } 4012 } 4013 } 4014 4015 // Log the ANR to the main log. 4016 StringBuilder info = new StringBuilder(); 4017 info.setLength(0); 4018 info.append("ANR in ").append(app.processName); 4019 if (activity != null && activity.shortComponentName != null) { 4020 info.append(" (").append(activity.shortComponentName).append(")"); 4021 } 4022 info.append("\n"); 4023 info.append("PID: ").append(app.pid).append("\n"); 4024 if (annotation != null) { 4025 info.append("Reason: ").append(annotation).append("\n"); 4026 } 4027 if (parent != null && parent != activity) { 4028 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4029 } 4030 4031 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4032 4033 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4034 NATIVE_STACKS_OF_INTEREST); 4035 4036 String cpuInfo = null; 4037 if (MONITOR_CPU_USAGE) { 4038 updateCpuStatsNow(); 4039 synchronized (mProcessCpuThread) { 4040 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4041 } 4042 info.append(processCpuTracker.printCurrentLoad()); 4043 info.append(cpuInfo); 4044 } 4045 4046 info.append(processCpuTracker.printCurrentState(anrTime)); 4047 4048 Slog.e(TAG, info.toString()); 4049 if (tracesFile == null) { 4050 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4051 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4052 } 4053 4054 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4055 cpuInfo, tracesFile, null); 4056 4057 if (mController != null) { 4058 try { 4059 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4060 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4061 if (res != 0) { 4062 if (res < 0 && app.pid != MY_PID) { 4063 Process.killProcess(app.pid); 4064 } else { 4065 synchronized (this) { 4066 mServices.scheduleServiceTimeoutLocked(app); 4067 } 4068 } 4069 return; 4070 } 4071 } catch (RemoteException e) { 4072 mController = null; 4073 Watchdog.getInstance().setActivityController(null); 4074 } 4075 } 4076 4077 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4078 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4079 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4080 4081 synchronized (this) { 4082 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4083 killUnneededProcessLocked(app, "background ANR"); 4084 return; 4085 } 4086 4087 // Set the app's notResponding state, and look up the errorReportReceiver 4088 makeAppNotRespondingLocked(app, 4089 activity != null ? activity.shortComponentName : null, 4090 annotation != null ? "ANR " + annotation : "ANR", 4091 info.toString()); 4092 4093 // Bring up the infamous App Not Responding dialog 4094 Message msg = Message.obtain(); 4095 HashMap<String, Object> map = new HashMap<String, Object>(); 4096 msg.what = SHOW_NOT_RESPONDING_MSG; 4097 msg.obj = map; 4098 msg.arg1 = aboveSystem ? 1 : 0; 4099 map.put("app", app); 4100 if (activity != null) { 4101 map.put("activity", activity); 4102 } 4103 4104 mHandler.sendMessage(msg); 4105 } 4106 } 4107 4108 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4109 if (!mLaunchWarningShown) { 4110 mLaunchWarningShown = true; 4111 mHandler.post(new Runnable() { 4112 @Override 4113 public void run() { 4114 synchronized (ActivityManagerService.this) { 4115 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4116 d.show(); 4117 mHandler.postDelayed(new Runnable() { 4118 @Override 4119 public void run() { 4120 synchronized (ActivityManagerService.this) { 4121 d.dismiss(); 4122 mLaunchWarningShown = false; 4123 } 4124 } 4125 }, 4000); 4126 } 4127 } 4128 }); 4129 } 4130 } 4131 4132 @Override 4133 public boolean clearApplicationUserData(final String packageName, 4134 final IPackageDataObserver observer, int userId) { 4135 enforceNotIsolatedCaller("clearApplicationUserData"); 4136 int uid = Binder.getCallingUid(); 4137 int pid = Binder.getCallingPid(); 4138 userId = handleIncomingUser(pid, uid, 4139 userId, false, true, "clearApplicationUserData", null); 4140 long callingId = Binder.clearCallingIdentity(); 4141 try { 4142 IPackageManager pm = AppGlobals.getPackageManager(); 4143 int pkgUid = -1; 4144 synchronized(this) { 4145 try { 4146 pkgUid = pm.getPackageUid(packageName, userId); 4147 } catch (RemoteException e) { 4148 } 4149 if (pkgUid == -1) { 4150 Slog.w(TAG, "Invalid packageName: " + packageName); 4151 if (observer != null) { 4152 try { 4153 observer.onRemoveCompleted(packageName, false); 4154 } catch (RemoteException e) { 4155 Slog.i(TAG, "Observer no longer exists."); 4156 } 4157 } 4158 return false; 4159 } 4160 if (uid == pkgUid || checkComponentPermission( 4161 android.Manifest.permission.CLEAR_APP_USER_DATA, 4162 pid, uid, -1, true) 4163 == PackageManager.PERMISSION_GRANTED) { 4164 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4165 } else { 4166 throw new SecurityException("PID " + pid + " does not have permission " 4167 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4168 + " of package " + packageName); 4169 } 4170 } 4171 4172 try { 4173 // Clear application user data 4174 pm.clearApplicationUserData(packageName, observer, userId); 4175 4176 // Remove all permissions granted from/to this package 4177 removeUriPermissionsForPackageLocked(packageName, userId, true); 4178 4179 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4180 Uri.fromParts("package", packageName, null)); 4181 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4182 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4183 null, null, 0, null, null, null, false, false, userId); 4184 } catch (RemoteException e) { 4185 } 4186 } finally { 4187 Binder.restoreCallingIdentity(callingId); 4188 } 4189 return true; 4190 } 4191 4192 @Override 4193 public void killBackgroundProcesses(final String packageName, int userId) { 4194 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4195 != PackageManager.PERMISSION_GRANTED && 4196 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4197 != PackageManager.PERMISSION_GRANTED) { 4198 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4199 + Binder.getCallingPid() 4200 + ", uid=" + Binder.getCallingUid() 4201 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4202 Slog.w(TAG, msg); 4203 throw new SecurityException(msg); 4204 } 4205 4206 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4207 userId, true, true, "killBackgroundProcesses", null); 4208 long callingId = Binder.clearCallingIdentity(); 4209 try { 4210 IPackageManager pm = AppGlobals.getPackageManager(); 4211 synchronized(this) { 4212 int appId = -1; 4213 try { 4214 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4215 } catch (RemoteException e) { 4216 } 4217 if (appId == -1) { 4218 Slog.w(TAG, "Invalid packageName: " + packageName); 4219 return; 4220 } 4221 killPackageProcessesLocked(packageName, appId, userId, 4222 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4223 } 4224 } finally { 4225 Binder.restoreCallingIdentity(callingId); 4226 } 4227 } 4228 4229 @Override 4230 public void killAllBackgroundProcesses() { 4231 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4232 != PackageManager.PERMISSION_GRANTED) { 4233 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4234 + Binder.getCallingPid() 4235 + ", uid=" + Binder.getCallingUid() 4236 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4237 Slog.w(TAG, msg); 4238 throw new SecurityException(msg); 4239 } 4240 4241 long callingId = Binder.clearCallingIdentity(); 4242 try { 4243 synchronized(this) { 4244 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4245 final int NP = mProcessNames.getMap().size(); 4246 for (int ip=0; ip<NP; ip++) { 4247 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4248 final int NA = apps.size(); 4249 for (int ia=0; ia<NA; ia++) { 4250 ProcessRecord app = apps.valueAt(ia); 4251 if (app.persistent) { 4252 // we don't kill persistent processes 4253 continue; 4254 } 4255 if (app.removed) { 4256 procs.add(app); 4257 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4258 app.removed = true; 4259 procs.add(app); 4260 } 4261 } 4262 } 4263 4264 int N = procs.size(); 4265 for (int i=0; i<N; i++) { 4266 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4267 } 4268 mAllowLowerMemLevel = true; 4269 updateOomAdjLocked(); 4270 doLowMemReportIfNeededLocked(null); 4271 } 4272 } finally { 4273 Binder.restoreCallingIdentity(callingId); 4274 } 4275 } 4276 4277 @Override 4278 public void forceStopPackage(final String packageName, int userId) { 4279 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4280 != PackageManager.PERMISSION_GRANTED) { 4281 String msg = "Permission Denial: forceStopPackage() from pid=" 4282 + Binder.getCallingPid() 4283 + ", uid=" + Binder.getCallingUid() 4284 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4285 Slog.w(TAG, msg); 4286 throw new SecurityException(msg); 4287 } 4288 final int callingPid = Binder.getCallingPid(); 4289 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4290 userId, true, true, "forceStopPackage", null); 4291 long callingId = Binder.clearCallingIdentity(); 4292 try { 4293 IPackageManager pm = AppGlobals.getPackageManager(); 4294 synchronized(this) { 4295 int[] users = userId == UserHandle.USER_ALL 4296 ? getUsersLocked() : new int[] { userId }; 4297 for (int user : users) { 4298 int pkgUid = -1; 4299 try { 4300 pkgUid = pm.getPackageUid(packageName, user); 4301 } catch (RemoteException e) { 4302 } 4303 if (pkgUid == -1) { 4304 Slog.w(TAG, "Invalid packageName: " + packageName); 4305 continue; 4306 } 4307 try { 4308 pm.setPackageStoppedState(packageName, true, user); 4309 } catch (RemoteException e) { 4310 } catch (IllegalArgumentException e) { 4311 Slog.w(TAG, "Failed trying to unstop package " 4312 + packageName + ": " + e); 4313 } 4314 if (isUserRunningLocked(user, false)) { 4315 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4316 } 4317 } 4318 } 4319 } finally { 4320 Binder.restoreCallingIdentity(callingId); 4321 } 4322 } 4323 4324 /* 4325 * The pkg name and app id have to be specified. 4326 */ 4327 @Override 4328 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4329 if (pkg == null) { 4330 return; 4331 } 4332 // Make sure the uid is valid. 4333 if (appid < 0) { 4334 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4335 return; 4336 } 4337 int callerUid = Binder.getCallingUid(); 4338 // Only the system server can kill an application 4339 if (callerUid == Process.SYSTEM_UID) { 4340 // Post an aysnc message to kill the application 4341 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4342 msg.arg1 = appid; 4343 msg.arg2 = 0; 4344 Bundle bundle = new Bundle(); 4345 bundle.putString("pkg", pkg); 4346 bundle.putString("reason", reason); 4347 msg.obj = bundle; 4348 mHandler.sendMessage(msg); 4349 } else { 4350 throw new SecurityException(callerUid + " cannot kill pkg: " + 4351 pkg); 4352 } 4353 } 4354 4355 @Override 4356 public void closeSystemDialogs(String reason) { 4357 enforceNotIsolatedCaller("closeSystemDialogs"); 4358 4359 final int pid = Binder.getCallingPid(); 4360 final int uid = Binder.getCallingUid(); 4361 final long origId = Binder.clearCallingIdentity(); 4362 try { 4363 synchronized (this) { 4364 // Only allow this from foreground processes, so that background 4365 // applications can't abuse it to prevent system UI from being shown. 4366 if (uid >= Process.FIRST_APPLICATION_UID) { 4367 ProcessRecord proc; 4368 synchronized (mPidsSelfLocked) { 4369 proc = mPidsSelfLocked.get(pid); 4370 } 4371 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4372 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4373 + " from background process " + proc); 4374 return; 4375 } 4376 } 4377 closeSystemDialogsLocked(reason); 4378 } 4379 } finally { 4380 Binder.restoreCallingIdentity(origId); 4381 } 4382 } 4383 4384 void closeSystemDialogsLocked(String reason) { 4385 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4386 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4387 | Intent.FLAG_RECEIVER_FOREGROUND); 4388 if (reason != null) { 4389 intent.putExtra("reason", reason); 4390 } 4391 mWindowManager.closeSystemDialogs(reason); 4392 4393 mStackSupervisor.closeSystemDialogsLocked(); 4394 4395 broadcastIntentLocked(null, null, intent, null, 4396 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4397 Process.SYSTEM_UID, UserHandle.USER_ALL); 4398 } 4399 4400 @Override 4401 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4402 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4403 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4404 for (int i=pids.length-1; i>=0; i--) { 4405 ProcessRecord proc; 4406 int oomAdj; 4407 synchronized (this) { 4408 synchronized (mPidsSelfLocked) { 4409 proc = mPidsSelfLocked.get(pids[i]); 4410 oomAdj = proc != null ? proc.setAdj : 0; 4411 } 4412 } 4413 infos[i] = new Debug.MemoryInfo(); 4414 Debug.getMemoryInfo(pids[i], infos[i]); 4415 if (proc != null) { 4416 synchronized (this) { 4417 if (proc.thread != null && proc.setAdj == oomAdj) { 4418 // Record this for posterity if the process has been stable. 4419 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4420 infos[i].getTotalUss(), false, proc.pkgList); 4421 } 4422 } 4423 } 4424 } 4425 return infos; 4426 } 4427 4428 @Override 4429 public long[] getProcessPss(int[] pids) { 4430 enforceNotIsolatedCaller("getProcessPss"); 4431 long[] pss = new long[pids.length]; 4432 for (int i=pids.length-1; i>=0; i--) { 4433 ProcessRecord proc; 4434 int oomAdj; 4435 synchronized (this) { 4436 synchronized (mPidsSelfLocked) { 4437 proc = mPidsSelfLocked.get(pids[i]); 4438 oomAdj = proc != null ? proc.setAdj : 0; 4439 } 4440 } 4441 long[] tmpUss = new long[1]; 4442 pss[i] = Debug.getPss(pids[i], tmpUss); 4443 if (proc != null) { 4444 synchronized (this) { 4445 if (proc.thread != null && proc.setAdj == oomAdj) { 4446 // Record this for posterity if the process has been stable. 4447 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4448 } 4449 } 4450 } 4451 } 4452 return pss; 4453 } 4454 4455 @Override 4456 public void killApplicationProcess(String processName, int uid) { 4457 if (processName == null) { 4458 return; 4459 } 4460 4461 int callerUid = Binder.getCallingUid(); 4462 // Only the system server can kill an application 4463 if (callerUid == Process.SYSTEM_UID) { 4464 synchronized (this) { 4465 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4466 if (app != null && app.thread != null) { 4467 try { 4468 app.thread.scheduleSuicide(); 4469 } catch (RemoteException e) { 4470 // If the other end already died, then our work here is done. 4471 } 4472 } else { 4473 Slog.w(TAG, "Process/uid not found attempting kill of " 4474 + processName + " / " + uid); 4475 } 4476 } 4477 } else { 4478 throw new SecurityException(callerUid + " cannot kill app process: " + 4479 processName); 4480 } 4481 } 4482 4483 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4484 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4485 false, true, false, false, UserHandle.getUserId(uid), reason); 4486 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4487 Uri.fromParts("package", packageName, null)); 4488 if (!mProcessesReady) { 4489 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4490 | Intent.FLAG_RECEIVER_FOREGROUND); 4491 } 4492 intent.putExtra(Intent.EXTRA_UID, uid); 4493 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4494 broadcastIntentLocked(null, null, intent, 4495 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4496 false, false, 4497 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4498 } 4499 4500 private void forceStopUserLocked(int userId, String reason) { 4501 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4502 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4503 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4504 | Intent.FLAG_RECEIVER_FOREGROUND); 4505 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4506 broadcastIntentLocked(null, null, intent, 4507 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4508 false, false, 4509 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4510 } 4511 4512 private final boolean killPackageProcessesLocked(String packageName, int appId, 4513 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4514 boolean doit, boolean evenPersistent, String reason) { 4515 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4516 4517 // Remove all processes this package may have touched: all with the 4518 // same UID (except for the system or root user), and all whose name 4519 // matches the package name. 4520 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4521 final int NP = mProcessNames.getMap().size(); 4522 for (int ip=0; ip<NP; ip++) { 4523 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4524 final int NA = apps.size(); 4525 for (int ia=0; ia<NA; ia++) { 4526 ProcessRecord app = apps.valueAt(ia); 4527 if (app.persistent && !evenPersistent) { 4528 // we don't kill persistent processes 4529 continue; 4530 } 4531 if (app.removed) { 4532 if (doit) { 4533 procs.add(app); 4534 } 4535 continue; 4536 } 4537 4538 // Skip process if it doesn't meet our oom adj requirement. 4539 if (app.setAdj < minOomAdj) { 4540 continue; 4541 } 4542 4543 // If no package is specified, we call all processes under the 4544 // give user id. 4545 if (packageName == null) { 4546 if (app.userId != userId) { 4547 continue; 4548 } 4549 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4550 continue; 4551 } 4552 // Package has been specified, we want to hit all processes 4553 // that match it. We need to qualify this by the processes 4554 // that are running under the specified app and user ID. 4555 } else { 4556 if (UserHandle.getAppId(app.uid) != appId) { 4557 continue; 4558 } 4559 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4560 continue; 4561 } 4562 if (!app.pkgList.containsKey(packageName)) { 4563 continue; 4564 } 4565 } 4566 4567 // Process has passed all conditions, kill it! 4568 if (!doit) { 4569 return true; 4570 } 4571 app.removed = true; 4572 procs.add(app); 4573 } 4574 } 4575 4576 int N = procs.size(); 4577 for (int i=0; i<N; i++) { 4578 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4579 } 4580 updateOomAdjLocked(); 4581 return N > 0; 4582 } 4583 4584 private final boolean forceStopPackageLocked(String name, int appId, 4585 boolean callerWillRestart, boolean purgeCache, boolean doit, 4586 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4587 int i; 4588 int N; 4589 4590 if (userId == UserHandle.USER_ALL && name == null) { 4591 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4592 } 4593 4594 if (appId < 0 && name != null) { 4595 try { 4596 appId = UserHandle.getAppId( 4597 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4598 } catch (RemoteException e) { 4599 } 4600 } 4601 4602 if (doit) { 4603 if (name != null) { 4604 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4605 + " user=" + userId + ": " + reason); 4606 } else { 4607 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4608 } 4609 4610 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4611 for (int ip=pmap.size()-1; ip>=0; ip--) { 4612 SparseArray<Long> ba = pmap.valueAt(ip); 4613 for (i=ba.size()-1; i>=0; i--) { 4614 boolean remove = false; 4615 final int entUid = ba.keyAt(i); 4616 if (name != null) { 4617 if (userId == UserHandle.USER_ALL) { 4618 if (UserHandle.getAppId(entUid) == appId) { 4619 remove = true; 4620 } 4621 } else { 4622 if (entUid == UserHandle.getUid(userId, appId)) { 4623 remove = true; 4624 } 4625 } 4626 } else if (UserHandle.getUserId(entUid) == userId) { 4627 remove = true; 4628 } 4629 if (remove) { 4630 ba.removeAt(i); 4631 } 4632 } 4633 if (ba.size() == 0) { 4634 pmap.removeAt(ip); 4635 } 4636 } 4637 } 4638 4639 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4640 -100, callerWillRestart, true, doit, evenPersistent, 4641 name == null ? ("stop user " + userId) : ("stop " + name)); 4642 4643 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4644 if (!doit) { 4645 return true; 4646 } 4647 didSomething = true; 4648 } 4649 4650 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4651 if (!doit) { 4652 return true; 4653 } 4654 didSomething = true; 4655 } 4656 4657 if (name == null) { 4658 // Remove all sticky broadcasts from this user. 4659 mStickyBroadcasts.remove(userId); 4660 } 4661 4662 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4663 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4664 userId, providers)) { 4665 if (!doit) { 4666 return true; 4667 } 4668 didSomething = true; 4669 } 4670 N = providers.size(); 4671 for (i=0; i<N; i++) { 4672 removeDyingProviderLocked(null, providers.get(i), true); 4673 } 4674 4675 // Remove transient permissions granted from/to this package/user 4676 removeUriPermissionsForPackageLocked(name, userId, false); 4677 4678 if (name == null || uninstalling) { 4679 // Remove pending intents. For now we only do this when force 4680 // stopping users, because we have some problems when doing this 4681 // for packages -- app widgets are not currently cleaned up for 4682 // such packages, so they can be left with bad pending intents. 4683 if (mIntentSenderRecords.size() > 0) { 4684 Iterator<WeakReference<PendingIntentRecord>> it 4685 = mIntentSenderRecords.values().iterator(); 4686 while (it.hasNext()) { 4687 WeakReference<PendingIntentRecord> wpir = it.next(); 4688 if (wpir == null) { 4689 it.remove(); 4690 continue; 4691 } 4692 PendingIntentRecord pir = wpir.get(); 4693 if (pir == null) { 4694 it.remove(); 4695 continue; 4696 } 4697 if (name == null) { 4698 // Stopping user, remove all objects for the user. 4699 if (pir.key.userId != userId) { 4700 // Not the same user, skip it. 4701 continue; 4702 } 4703 } else { 4704 if (UserHandle.getAppId(pir.uid) != appId) { 4705 // Different app id, skip it. 4706 continue; 4707 } 4708 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4709 // Different user, skip it. 4710 continue; 4711 } 4712 if (!pir.key.packageName.equals(name)) { 4713 // Different package, skip it. 4714 continue; 4715 } 4716 } 4717 if (!doit) { 4718 return true; 4719 } 4720 didSomething = true; 4721 it.remove(); 4722 pir.canceled = true; 4723 if (pir.key.activity != null) { 4724 pir.key.activity.pendingResults.remove(pir.ref); 4725 } 4726 } 4727 } 4728 } 4729 4730 if (doit) { 4731 if (purgeCache && name != null) { 4732 AttributeCache ac = AttributeCache.instance(); 4733 if (ac != null) { 4734 ac.removePackage(name); 4735 } 4736 } 4737 if (mBooted) { 4738 mStackSupervisor.resumeTopActivitiesLocked(); 4739 mStackSupervisor.scheduleIdleLocked(); 4740 } 4741 } 4742 4743 return didSomething; 4744 } 4745 4746 private final boolean removeProcessLocked(ProcessRecord app, 4747 boolean callerWillRestart, boolean allowRestart, String reason) { 4748 final String name = app.processName; 4749 final int uid = app.uid; 4750 if (DEBUG_PROCESSES) Slog.d( 4751 TAG, "Force removing proc " + app.toShortString() + " (" + name 4752 + "/" + uid + ")"); 4753 4754 mProcessNames.remove(name, uid); 4755 mIsolatedProcesses.remove(app.uid); 4756 if (mHeavyWeightProcess == app) { 4757 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4758 mHeavyWeightProcess.userId, 0)); 4759 mHeavyWeightProcess = null; 4760 } 4761 boolean needRestart = false; 4762 if (app.pid > 0 && app.pid != MY_PID) { 4763 int pid = app.pid; 4764 synchronized (mPidsSelfLocked) { 4765 mPidsSelfLocked.remove(pid); 4766 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4767 } 4768 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4769 app.processName, app.info.uid); 4770 if (app.isolated) { 4771 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4772 } 4773 killUnneededProcessLocked(app, reason); 4774 handleAppDiedLocked(app, true, allowRestart); 4775 removeLruProcessLocked(app); 4776 4777 if (app.persistent && !app.isolated) { 4778 if (!callerWillRestart) { 4779 addAppLocked(app.info, false); 4780 } else { 4781 needRestart = true; 4782 } 4783 } 4784 } else { 4785 mRemovedProcesses.add(app); 4786 } 4787 4788 return needRestart; 4789 } 4790 4791 private final void processStartTimedOutLocked(ProcessRecord app) { 4792 final int pid = app.pid; 4793 boolean gone = false; 4794 synchronized (mPidsSelfLocked) { 4795 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4796 if (knownApp != null && knownApp.thread == null) { 4797 mPidsSelfLocked.remove(pid); 4798 gone = true; 4799 } 4800 } 4801 4802 if (gone) { 4803 Slog.w(TAG, "Process " + app + " failed to attach"); 4804 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4805 pid, app.uid, app.processName); 4806 mProcessNames.remove(app.processName, app.uid); 4807 mIsolatedProcesses.remove(app.uid); 4808 if (mHeavyWeightProcess == app) { 4809 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4810 mHeavyWeightProcess.userId, 0)); 4811 mHeavyWeightProcess = null; 4812 } 4813 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4814 app.processName, app.info.uid); 4815 if (app.isolated) { 4816 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4817 } 4818 // Take care of any launching providers waiting for this process. 4819 checkAppInLaunchingProvidersLocked(app, true); 4820 // Take care of any services that are waiting for the process. 4821 mServices.processStartTimedOutLocked(app); 4822 killUnneededProcessLocked(app, "start timeout"); 4823 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4824 Slog.w(TAG, "Unattached app died before backup, skipping"); 4825 try { 4826 IBackupManager bm = IBackupManager.Stub.asInterface( 4827 ServiceManager.getService(Context.BACKUP_SERVICE)); 4828 bm.agentDisconnected(app.info.packageName); 4829 } catch (RemoteException e) { 4830 // Can't happen; the backup manager is local 4831 } 4832 } 4833 if (isPendingBroadcastProcessLocked(pid)) { 4834 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4835 skipPendingBroadcastLocked(pid); 4836 } 4837 } else { 4838 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4839 } 4840 } 4841 4842 private final boolean attachApplicationLocked(IApplicationThread thread, 4843 int pid) { 4844 4845 // Find the application record that is being attached... either via 4846 // the pid if we are running in multiple processes, or just pull the 4847 // next app record if we are emulating process with anonymous threads. 4848 ProcessRecord app; 4849 if (pid != MY_PID && pid >= 0) { 4850 synchronized (mPidsSelfLocked) { 4851 app = mPidsSelfLocked.get(pid); 4852 } 4853 } else { 4854 app = null; 4855 } 4856 4857 if (app == null) { 4858 Slog.w(TAG, "No pending application record for pid " + pid 4859 + " (IApplicationThread " + thread + "); dropping process"); 4860 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4861 if (pid > 0 && pid != MY_PID) { 4862 Process.killProcessQuiet(pid); 4863 } else { 4864 try { 4865 thread.scheduleExit(); 4866 } catch (Exception e) { 4867 // Ignore exceptions. 4868 } 4869 } 4870 return false; 4871 } 4872 4873 // If this application record is still attached to a previous 4874 // process, clean it up now. 4875 if (app.thread != null) { 4876 handleAppDiedLocked(app, true, true); 4877 } 4878 4879 // Tell the process all about itself. 4880 4881 if (localLOGV) Slog.v( 4882 TAG, "Binding process pid " + pid + " to record " + app); 4883 4884 final String processName = app.processName; 4885 try { 4886 AppDeathRecipient adr = new AppDeathRecipient( 4887 app, pid, thread); 4888 thread.asBinder().linkToDeath(adr, 0); 4889 app.deathRecipient = adr; 4890 } catch (RemoteException e) { 4891 app.resetPackageList(mProcessStats); 4892 startProcessLocked(app, "link fail", processName); 4893 return false; 4894 } 4895 4896 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4897 4898 app.makeActive(thread, mProcessStats); 4899 app.curAdj = app.setAdj = -100; 4900 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4901 app.forcingToForeground = null; 4902 updateProcessForegroundLocked(app, false, false); 4903 app.hasShownUi = false; 4904 app.debugging = false; 4905 app.cached = false; 4906 4907 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4908 4909 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4910 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4911 4912 if (!normalMode) { 4913 Slog.i(TAG, "Launching preboot mode app: " + app); 4914 } 4915 4916 if (localLOGV) Slog.v( 4917 TAG, "New app record " + app 4918 + " thread=" + thread.asBinder() + " pid=" + pid); 4919 try { 4920 int testMode = IApplicationThread.DEBUG_OFF; 4921 if (mDebugApp != null && mDebugApp.equals(processName)) { 4922 testMode = mWaitForDebugger 4923 ? IApplicationThread.DEBUG_WAIT 4924 : IApplicationThread.DEBUG_ON; 4925 app.debugging = true; 4926 if (mDebugTransient) { 4927 mDebugApp = mOrigDebugApp; 4928 mWaitForDebugger = mOrigWaitForDebugger; 4929 } 4930 } 4931 String profileFile = app.instrumentationProfileFile; 4932 ParcelFileDescriptor profileFd = null; 4933 boolean profileAutoStop = false; 4934 if (mProfileApp != null && mProfileApp.equals(processName)) { 4935 mProfileProc = app; 4936 profileFile = mProfileFile; 4937 profileFd = mProfileFd; 4938 profileAutoStop = mAutoStopProfiler; 4939 } 4940 boolean enableOpenGlTrace = false; 4941 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4942 enableOpenGlTrace = true; 4943 mOpenGlTraceApp = null; 4944 } 4945 4946 // If the app is being launched for restore or full backup, set it up specially 4947 boolean isRestrictedBackupMode = false; 4948 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4949 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4950 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4951 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4952 } 4953 4954 ensurePackageDexOpt(app.instrumentationInfo != null 4955 ? app.instrumentationInfo.packageName 4956 : app.info.packageName); 4957 if (app.instrumentationClass != null) { 4958 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4959 } 4960 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4961 + processName + " with config " + mConfiguration); 4962 ApplicationInfo appInfo = app.instrumentationInfo != null 4963 ? app.instrumentationInfo : app.info; 4964 app.compat = compatibilityInfoForPackageLocked(appInfo); 4965 if (profileFd != null) { 4966 profileFd = profileFd.dup(); 4967 } 4968 thread.bindApplication(processName, appInfo, providers, 4969 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4970 app.instrumentationArguments, app.instrumentationWatcher, 4971 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4972 isRestrictedBackupMode || !normalMode, app.persistent, 4973 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4974 mCoreSettingsObserver.getCoreSettingsLocked()); 4975 updateLruProcessLocked(app, false, null); 4976 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4977 } catch (Exception e) { 4978 // todo: Yikes! What should we do? For now we will try to 4979 // start another process, but that could easily get us in 4980 // an infinite loop of restarting processes... 4981 Slog.w(TAG, "Exception thrown during bind!", e); 4982 4983 app.resetPackageList(mProcessStats); 4984 app.unlinkDeathRecipient(); 4985 startProcessLocked(app, "bind fail", processName); 4986 return false; 4987 } 4988 4989 // Remove this record from the list of starting applications. 4990 mPersistentStartingProcesses.remove(app); 4991 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4992 "Attach application locked removing on hold: " + app); 4993 mProcessesOnHold.remove(app); 4994 4995 boolean badApp = false; 4996 boolean didSomething = false; 4997 4998 // See if the top visible activity is waiting to run in this process... 4999 if (normalMode) { 5000 try { 5001 if (mStackSupervisor.attachApplicationLocked(app)) { 5002 didSomething = true; 5003 } 5004 } catch (Exception e) { 5005 badApp = true; 5006 } 5007 } 5008 5009 // Find any services that should be running in this process... 5010 if (!badApp) { 5011 try { 5012 didSomething |= mServices.attachApplicationLocked(app, processName); 5013 } catch (Exception e) { 5014 badApp = true; 5015 } 5016 } 5017 5018 // Check if a next-broadcast receiver is in this process... 5019 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5020 try { 5021 didSomething |= sendPendingBroadcastsLocked(app); 5022 } catch (Exception e) { 5023 // If the app died trying to launch the receiver we declare it 'bad' 5024 badApp = true; 5025 } 5026 } 5027 5028 // Check whether the next backup agent is in this process... 5029 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5030 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5031 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5032 try { 5033 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5034 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5035 mBackupTarget.backupMode); 5036 } catch (Exception e) { 5037 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5038 e.printStackTrace(); 5039 } 5040 } 5041 5042 if (badApp) { 5043 // todo: Also need to kill application to deal with all 5044 // kinds of exceptions. 5045 handleAppDiedLocked(app, false, true); 5046 return false; 5047 } 5048 5049 if (!didSomething) { 5050 updateOomAdjLocked(); 5051 } 5052 5053 return true; 5054 } 5055 5056 @Override 5057 public final void attachApplication(IApplicationThread thread) { 5058 synchronized (this) { 5059 int callingPid = Binder.getCallingPid(); 5060 final long origId = Binder.clearCallingIdentity(); 5061 attachApplicationLocked(thread, callingPid); 5062 Binder.restoreCallingIdentity(origId); 5063 } 5064 } 5065 5066 @Override 5067 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5068 final long origId = Binder.clearCallingIdentity(); 5069 synchronized (this) { 5070 ActivityStack stack = ActivityRecord.getStackLocked(token); 5071 if (stack != null) { 5072 ActivityRecord r = 5073 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5074 if (stopProfiling) { 5075 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5076 try { 5077 mProfileFd.close(); 5078 } catch (IOException e) { 5079 } 5080 clearProfilerLocked(); 5081 } 5082 } 5083 } 5084 } 5085 Binder.restoreCallingIdentity(origId); 5086 } 5087 5088 void enableScreenAfterBoot() { 5089 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5090 SystemClock.uptimeMillis()); 5091 mWindowManager.enableScreenAfterBoot(); 5092 5093 synchronized (this) { 5094 updateEventDispatchingLocked(); 5095 } 5096 } 5097 5098 @Override 5099 public void showBootMessage(final CharSequence msg, final boolean always) { 5100 enforceNotIsolatedCaller("showBootMessage"); 5101 mWindowManager.showBootMessage(msg, always); 5102 } 5103 5104 @Override 5105 public void dismissKeyguardOnNextActivity() { 5106 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5107 final long token = Binder.clearCallingIdentity(); 5108 try { 5109 synchronized (this) { 5110 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5111 if (mLockScreenShown) { 5112 mLockScreenShown = false; 5113 comeOutOfSleepIfNeededLocked(); 5114 } 5115 mStackSupervisor.setDismissKeyguard(true); 5116 } 5117 } finally { 5118 Binder.restoreCallingIdentity(token); 5119 } 5120 } 5121 5122 final void finishBooting() { 5123 IntentFilter pkgFilter = new IntentFilter(); 5124 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5125 pkgFilter.addDataScheme("package"); 5126 mContext.registerReceiver(new BroadcastReceiver() { 5127 @Override 5128 public void onReceive(Context context, Intent intent) { 5129 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5130 if (pkgs != null) { 5131 for (String pkg : pkgs) { 5132 synchronized (ActivityManagerService.this) { 5133 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 5134 "finished booting")) { 5135 setResultCode(Activity.RESULT_OK); 5136 return; 5137 } 5138 } 5139 } 5140 } 5141 } 5142 }, pkgFilter); 5143 5144 synchronized (this) { 5145 // Ensure that any processes we had put on hold are now started 5146 // up. 5147 final int NP = mProcessesOnHold.size(); 5148 if (NP > 0) { 5149 ArrayList<ProcessRecord> procs = 5150 new ArrayList<ProcessRecord>(mProcessesOnHold); 5151 for (int ip=0; ip<NP; ip++) { 5152 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5153 + procs.get(ip)); 5154 startProcessLocked(procs.get(ip), "on-hold", null); 5155 } 5156 } 5157 5158 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5159 // Start looking for apps that are abusing wake locks. 5160 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5161 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5162 // Tell anyone interested that we are done booting! 5163 SystemProperties.set("sys.boot_completed", "1"); 5164 SystemProperties.set("dev.bootcomplete", "1"); 5165 for (int i=0; i<mStartedUsers.size(); i++) { 5166 UserStartedState uss = mStartedUsers.valueAt(i); 5167 if (uss.mState == UserStartedState.STATE_BOOTING) { 5168 uss.mState = UserStartedState.STATE_RUNNING; 5169 final int userId = mStartedUsers.keyAt(i); 5170 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5171 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5172 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5173 broadcastIntentLocked(null, null, intent, null, 5174 new IIntentReceiver.Stub() { 5175 @Override 5176 public void performReceive(Intent intent, int resultCode, 5177 String data, Bundle extras, boolean ordered, 5178 boolean sticky, int sendingUser) { 5179 synchronized (ActivityManagerService.this) { 5180 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5181 true, false); 5182 } 5183 } 5184 }, 5185 0, null, null, 5186 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5187 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5188 userId); 5189 } 5190 } 5191 scheduleStartRelatedUsersLocked(); 5192 } 5193 } 5194 } 5195 5196 final void ensureBootCompleted() { 5197 boolean booting; 5198 boolean enableScreen; 5199 synchronized (this) { 5200 booting = mBooting; 5201 mBooting = false; 5202 enableScreen = !mBooted; 5203 mBooted = true; 5204 } 5205 5206 if (booting) { 5207 finishBooting(); 5208 } 5209 5210 if (enableScreen) { 5211 enableScreenAfterBoot(); 5212 } 5213 } 5214 5215 @Override 5216 public final void activityResumed(IBinder token) { 5217 final long origId = Binder.clearCallingIdentity(); 5218 synchronized(this) { 5219 ActivityStack stack = ActivityRecord.getStackLocked(token); 5220 if (stack != null) { 5221 ActivityRecord.activityResumedLocked(token); 5222 } 5223 } 5224 Binder.restoreCallingIdentity(origId); 5225 } 5226 5227 @Override 5228 public final void activityPaused(IBinder token) { 5229 final long origId = Binder.clearCallingIdentity(); 5230 synchronized(this) { 5231 ActivityStack stack = ActivityRecord.getStackLocked(token); 5232 if (stack != null) { 5233 stack.activityPausedLocked(token, false); 5234 } 5235 } 5236 Binder.restoreCallingIdentity(origId); 5237 } 5238 5239 @Override 5240 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5241 CharSequence description) { 5242 if (localLOGV) Slog.v( 5243 TAG, "Activity stopped: token=" + token); 5244 5245 // Refuse possible leaked file descriptors 5246 if (icicle != null && icicle.hasFileDescriptors()) { 5247 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5248 } 5249 5250 ActivityRecord r = null; 5251 5252 final long origId = Binder.clearCallingIdentity(); 5253 5254 synchronized (this) { 5255 r = ActivityRecord.isInStackLocked(token); 5256 if (r != null) { 5257 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5258 } 5259 } 5260 5261 if (r != null) { 5262 sendPendingThumbnail(r, null, null, null, false); 5263 } 5264 5265 trimApplications(); 5266 5267 Binder.restoreCallingIdentity(origId); 5268 } 5269 5270 @Override 5271 public final void activityDestroyed(IBinder token) { 5272 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5273 synchronized (this) { 5274 ActivityStack stack = ActivityRecord.getStackLocked(token); 5275 if (stack != null) { 5276 stack.activityDestroyedLocked(token); 5277 } 5278 } 5279 } 5280 5281 @Override 5282 public String getCallingPackage(IBinder token) { 5283 synchronized (this) { 5284 ActivityRecord r = getCallingRecordLocked(token); 5285 return r != null ? r.info.packageName : null; 5286 } 5287 } 5288 5289 @Override 5290 public ComponentName getCallingActivity(IBinder token) { 5291 synchronized (this) { 5292 ActivityRecord r = getCallingRecordLocked(token); 5293 return r != null ? r.intent.getComponent() : null; 5294 } 5295 } 5296 5297 private ActivityRecord getCallingRecordLocked(IBinder token) { 5298 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5299 if (r == null) { 5300 return null; 5301 } 5302 return r.resultTo; 5303 } 5304 5305 @Override 5306 public ComponentName getActivityClassForToken(IBinder token) { 5307 synchronized(this) { 5308 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5309 if (r == null) { 5310 return null; 5311 } 5312 return r.intent.getComponent(); 5313 } 5314 } 5315 5316 @Override 5317 public String getPackageForToken(IBinder token) { 5318 synchronized(this) { 5319 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5320 if (r == null) { 5321 return null; 5322 } 5323 return r.packageName; 5324 } 5325 } 5326 5327 @Override 5328 public IIntentSender getIntentSender(int type, 5329 String packageName, IBinder token, String resultWho, 5330 int requestCode, Intent[] intents, String[] resolvedTypes, 5331 int flags, Bundle options, int userId) { 5332 enforceNotIsolatedCaller("getIntentSender"); 5333 // Refuse possible leaked file descriptors 5334 if (intents != null) { 5335 if (intents.length < 1) { 5336 throw new IllegalArgumentException("Intents array length must be >= 1"); 5337 } 5338 for (int i=0; i<intents.length; i++) { 5339 Intent intent = intents[i]; 5340 if (intent != null) { 5341 if (intent.hasFileDescriptors()) { 5342 throw new IllegalArgumentException("File descriptors passed in Intent"); 5343 } 5344 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5345 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5346 throw new IllegalArgumentException( 5347 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5348 } 5349 intents[i] = new Intent(intent); 5350 } 5351 } 5352 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5353 throw new IllegalArgumentException( 5354 "Intent array length does not match resolvedTypes length"); 5355 } 5356 } 5357 if (options != null) { 5358 if (options.hasFileDescriptors()) { 5359 throw new IllegalArgumentException("File descriptors passed in options"); 5360 } 5361 } 5362 5363 synchronized(this) { 5364 int callingUid = Binder.getCallingUid(); 5365 int origUserId = userId; 5366 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5367 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5368 "getIntentSender", null); 5369 if (origUserId == UserHandle.USER_CURRENT) { 5370 // We don't want to evaluate this until the pending intent is 5371 // actually executed. However, we do want to always do the 5372 // security checking for it above. 5373 userId = UserHandle.USER_CURRENT; 5374 } 5375 try { 5376 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5377 int uid = AppGlobals.getPackageManager() 5378 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5379 if (!UserHandle.isSameApp(callingUid, uid)) { 5380 String msg = "Permission Denial: getIntentSender() from pid=" 5381 + Binder.getCallingPid() 5382 + ", uid=" + Binder.getCallingUid() 5383 + ", (need uid=" + uid + ")" 5384 + " is not allowed to send as package " + packageName; 5385 Slog.w(TAG, msg); 5386 throw new SecurityException(msg); 5387 } 5388 } 5389 5390 return getIntentSenderLocked(type, packageName, callingUid, userId, 5391 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5392 5393 } catch (RemoteException e) { 5394 throw new SecurityException(e); 5395 } 5396 } 5397 } 5398 5399 IIntentSender getIntentSenderLocked(int type, String packageName, 5400 int callingUid, int userId, IBinder token, String resultWho, 5401 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5402 Bundle options) { 5403 if (DEBUG_MU) 5404 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5405 ActivityRecord activity = null; 5406 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5407 activity = ActivityRecord.isInStackLocked(token); 5408 if (activity == null) { 5409 return null; 5410 } 5411 if (activity.finishing) { 5412 return null; 5413 } 5414 } 5415 5416 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5417 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5418 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5419 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5420 |PendingIntent.FLAG_UPDATE_CURRENT); 5421 5422 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5423 type, packageName, activity, resultWho, 5424 requestCode, intents, resolvedTypes, flags, options, userId); 5425 WeakReference<PendingIntentRecord> ref; 5426 ref = mIntentSenderRecords.get(key); 5427 PendingIntentRecord rec = ref != null ? ref.get() : null; 5428 if (rec != null) { 5429 if (!cancelCurrent) { 5430 if (updateCurrent) { 5431 if (rec.key.requestIntent != null) { 5432 rec.key.requestIntent.replaceExtras(intents != null ? 5433 intents[intents.length - 1] : null); 5434 } 5435 if (intents != null) { 5436 intents[intents.length-1] = rec.key.requestIntent; 5437 rec.key.allIntents = intents; 5438 rec.key.allResolvedTypes = resolvedTypes; 5439 } else { 5440 rec.key.allIntents = null; 5441 rec.key.allResolvedTypes = null; 5442 } 5443 } 5444 return rec; 5445 } 5446 rec.canceled = true; 5447 mIntentSenderRecords.remove(key); 5448 } 5449 if (noCreate) { 5450 return rec; 5451 } 5452 rec = new PendingIntentRecord(this, key, callingUid); 5453 mIntentSenderRecords.put(key, rec.ref); 5454 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5455 if (activity.pendingResults == null) { 5456 activity.pendingResults 5457 = new HashSet<WeakReference<PendingIntentRecord>>(); 5458 } 5459 activity.pendingResults.add(rec.ref); 5460 } 5461 return rec; 5462 } 5463 5464 @Override 5465 public void cancelIntentSender(IIntentSender sender) { 5466 if (!(sender instanceof PendingIntentRecord)) { 5467 return; 5468 } 5469 synchronized(this) { 5470 PendingIntentRecord rec = (PendingIntentRecord)sender; 5471 try { 5472 int uid = AppGlobals.getPackageManager() 5473 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5474 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5475 String msg = "Permission Denial: cancelIntentSender() from pid=" 5476 + Binder.getCallingPid() 5477 + ", uid=" + Binder.getCallingUid() 5478 + " is not allowed to cancel packges " 5479 + rec.key.packageName; 5480 Slog.w(TAG, msg); 5481 throw new SecurityException(msg); 5482 } 5483 } catch (RemoteException e) { 5484 throw new SecurityException(e); 5485 } 5486 cancelIntentSenderLocked(rec, true); 5487 } 5488 } 5489 5490 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5491 rec.canceled = true; 5492 mIntentSenderRecords.remove(rec.key); 5493 if (cleanActivity && rec.key.activity != null) { 5494 rec.key.activity.pendingResults.remove(rec.ref); 5495 } 5496 } 5497 5498 @Override 5499 public String getPackageForIntentSender(IIntentSender pendingResult) { 5500 if (!(pendingResult instanceof PendingIntentRecord)) { 5501 return null; 5502 } 5503 try { 5504 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5505 return res.key.packageName; 5506 } catch (ClassCastException e) { 5507 } 5508 return null; 5509 } 5510 5511 @Override 5512 public int getUidForIntentSender(IIntentSender sender) { 5513 if (sender instanceof PendingIntentRecord) { 5514 try { 5515 PendingIntentRecord res = (PendingIntentRecord)sender; 5516 return res.uid; 5517 } catch (ClassCastException e) { 5518 } 5519 } 5520 return -1; 5521 } 5522 5523 @Override 5524 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5525 if (!(pendingResult instanceof PendingIntentRecord)) { 5526 return false; 5527 } 5528 try { 5529 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5530 if (res.key.allIntents == null) { 5531 return false; 5532 } 5533 for (int i=0; i<res.key.allIntents.length; i++) { 5534 Intent intent = res.key.allIntents[i]; 5535 if (intent.getPackage() != null && intent.getComponent() != null) { 5536 return false; 5537 } 5538 } 5539 return true; 5540 } catch (ClassCastException e) { 5541 } 5542 return false; 5543 } 5544 5545 @Override 5546 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5547 if (!(pendingResult instanceof PendingIntentRecord)) { 5548 return false; 5549 } 5550 try { 5551 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5552 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5553 return true; 5554 } 5555 return false; 5556 } catch (ClassCastException e) { 5557 } 5558 return false; 5559 } 5560 5561 @Override 5562 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5563 if (!(pendingResult instanceof PendingIntentRecord)) { 5564 return null; 5565 } 5566 try { 5567 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5568 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5569 } catch (ClassCastException e) { 5570 } 5571 return null; 5572 } 5573 5574 @Override 5575 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5576 if (!(pendingResult instanceof PendingIntentRecord)) { 5577 return null; 5578 } 5579 try { 5580 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5581 Intent intent = res.key.requestIntent; 5582 if (intent != null) { 5583 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5584 || res.lastTagPrefix.equals(prefix))) { 5585 return res.lastTag; 5586 } 5587 res.lastTagPrefix = prefix; 5588 StringBuilder sb = new StringBuilder(128); 5589 if (prefix != null) { 5590 sb.append(prefix); 5591 } 5592 if (intent.getAction() != null) { 5593 sb.append(intent.getAction()); 5594 } else if (intent.getComponent() != null) { 5595 intent.getComponent().appendShortString(sb); 5596 } else { 5597 sb.append("?"); 5598 } 5599 return res.lastTag = sb.toString(); 5600 } 5601 } catch (ClassCastException e) { 5602 } 5603 return null; 5604 } 5605 5606 @Override 5607 public void setProcessLimit(int max) { 5608 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5609 "setProcessLimit()"); 5610 synchronized (this) { 5611 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5612 mProcessLimitOverride = max; 5613 } 5614 trimApplications(); 5615 } 5616 5617 @Override 5618 public int getProcessLimit() { 5619 synchronized (this) { 5620 return mProcessLimitOverride; 5621 } 5622 } 5623 5624 void foregroundTokenDied(ForegroundToken token) { 5625 synchronized (ActivityManagerService.this) { 5626 synchronized (mPidsSelfLocked) { 5627 ForegroundToken cur 5628 = mForegroundProcesses.get(token.pid); 5629 if (cur != token) { 5630 return; 5631 } 5632 mForegroundProcesses.remove(token.pid); 5633 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5634 if (pr == null) { 5635 return; 5636 } 5637 pr.forcingToForeground = null; 5638 updateProcessForegroundLocked(pr, false, false); 5639 } 5640 updateOomAdjLocked(); 5641 } 5642 } 5643 5644 @Override 5645 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5646 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5647 "setProcessForeground()"); 5648 synchronized(this) { 5649 boolean changed = false; 5650 5651 synchronized (mPidsSelfLocked) { 5652 ProcessRecord pr = mPidsSelfLocked.get(pid); 5653 if (pr == null && isForeground) { 5654 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5655 return; 5656 } 5657 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5658 if (oldToken != null) { 5659 oldToken.token.unlinkToDeath(oldToken, 0); 5660 mForegroundProcesses.remove(pid); 5661 if (pr != null) { 5662 pr.forcingToForeground = null; 5663 } 5664 changed = true; 5665 } 5666 if (isForeground && token != null) { 5667 ForegroundToken newToken = new ForegroundToken() { 5668 @Override 5669 public void binderDied() { 5670 foregroundTokenDied(this); 5671 } 5672 }; 5673 newToken.pid = pid; 5674 newToken.token = token; 5675 try { 5676 token.linkToDeath(newToken, 0); 5677 mForegroundProcesses.put(pid, newToken); 5678 pr.forcingToForeground = token; 5679 changed = true; 5680 } catch (RemoteException e) { 5681 // If the process died while doing this, we will later 5682 // do the cleanup with the process death link. 5683 } 5684 } 5685 } 5686 5687 if (changed) { 5688 updateOomAdjLocked(); 5689 } 5690 } 5691 } 5692 5693 // ========================================================= 5694 // PERMISSIONS 5695 // ========================================================= 5696 5697 static class PermissionController extends IPermissionController.Stub { 5698 ActivityManagerService mActivityManagerService; 5699 PermissionController(ActivityManagerService activityManagerService) { 5700 mActivityManagerService = activityManagerService; 5701 } 5702 5703 @Override 5704 public boolean checkPermission(String permission, int pid, int uid) { 5705 return mActivityManagerService.checkPermission(permission, pid, 5706 uid) == PackageManager.PERMISSION_GRANTED; 5707 } 5708 } 5709 5710 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5711 @Override 5712 public int checkComponentPermission(String permission, int pid, int uid, 5713 int owningUid, boolean exported) { 5714 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5715 owningUid, exported); 5716 } 5717 5718 @Override 5719 public Object getAMSLock() { 5720 return ActivityManagerService.this; 5721 } 5722 } 5723 5724 /** 5725 * This can be called with or without the global lock held. 5726 */ 5727 int checkComponentPermission(String permission, int pid, int uid, 5728 int owningUid, boolean exported) { 5729 // We might be performing an operation on behalf of an indirect binder 5730 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5731 // client identity accordingly before proceeding. 5732 Identity tlsIdentity = sCallerIdentity.get(); 5733 if (tlsIdentity != null) { 5734 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5735 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5736 uid = tlsIdentity.uid; 5737 pid = tlsIdentity.pid; 5738 } 5739 5740 if (pid == MY_PID) { 5741 return PackageManager.PERMISSION_GRANTED; 5742 } 5743 5744 return ActivityManager.checkComponentPermission(permission, uid, 5745 owningUid, exported); 5746 } 5747 5748 /** 5749 * As the only public entry point for permissions checking, this method 5750 * can enforce the semantic that requesting a check on a null global 5751 * permission is automatically denied. (Internally a null permission 5752 * string is used when calling {@link #checkComponentPermission} in cases 5753 * when only uid-based security is needed.) 5754 * 5755 * This can be called with or without the global lock held. 5756 */ 5757 @Override 5758 public int checkPermission(String permission, int pid, int uid) { 5759 if (permission == null) { 5760 return PackageManager.PERMISSION_DENIED; 5761 } 5762 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5763 } 5764 5765 /** 5766 * Binder IPC calls go through the public entry point. 5767 * This can be called with or without the global lock held. 5768 */ 5769 int checkCallingPermission(String permission) { 5770 return checkPermission(permission, 5771 Binder.getCallingPid(), 5772 UserHandle.getAppId(Binder.getCallingUid())); 5773 } 5774 5775 /** 5776 * This can be called with or without the global lock held. 5777 */ 5778 void enforceCallingPermission(String permission, String func) { 5779 if (checkCallingPermission(permission) 5780 == PackageManager.PERMISSION_GRANTED) { 5781 return; 5782 } 5783 5784 String msg = "Permission Denial: " + func + " from pid=" 5785 + Binder.getCallingPid() 5786 + ", uid=" + Binder.getCallingUid() 5787 + " requires " + permission; 5788 Slog.w(TAG, msg); 5789 throw new SecurityException(msg); 5790 } 5791 5792 /** 5793 * Determine if UID is holding permissions required to access {@link Uri} in 5794 * the given {@link ProviderInfo}. Final permission checking is always done 5795 * in {@link ContentProvider}. 5796 */ 5797 private final boolean checkHoldingPermissionsLocked( 5798 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5799 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5800 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5801 5802 if (pi.applicationInfo.uid == uid) { 5803 return true; 5804 } else if (!pi.exported) { 5805 return false; 5806 } 5807 5808 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5809 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5810 try { 5811 // check if target holds top-level <provider> permissions 5812 if (!readMet && pi.readPermission != null 5813 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5814 readMet = true; 5815 } 5816 if (!writeMet && pi.writePermission != null 5817 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5818 writeMet = true; 5819 } 5820 5821 // track if unprotected read/write is allowed; any denied 5822 // <path-permission> below removes this ability 5823 boolean allowDefaultRead = pi.readPermission == null; 5824 boolean allowDefaultWrite = pi.writePermission == null; 5825 5826 // check if target holds any <path-permission> that match uri 5827 final PathPermission[] pps = pi.pathPermissions; 5828 if (pps != null) { 5829 final String path = uri.getPath(); 5830 int i = pps.length; 5831 while (i > 0 && (!readMet || !writeMet)) { 5832 i--; 5833 PathPermission pp = pps[i]; 5834 if (pp.match(path)) { 5835 if (!readMet) { 5836 final String pprperm = pp.getReadPermission(); 5837 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5838 + pprperm + " for " + pp.getPath() 5839 + ": match=" + pp.match(path) 5840 + " check=" + pm.checkUidPermission(pprperm, uid)); 5841 if (pprperm != null) { 5842 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5843 readMet = true; 5844 } else { 5845 allowDefaultRead = false; 5846 } 5847 } 5848 } 5849 if (!writeMet) { 5850 final String ppwperm = pp.getWritePermission(); 5851 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5852 + ppwperm + " for " + pp.getPath() 5853 + ": match=" + pp.match(path) 5854 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5855 if (ppwperm != null) { 5856 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5857 writeMet = true; 5858 } else { 5859 allowDefaultWrite = false; 5860 } 5861 } 5862 } 5863 } 5864 } 5865 } 5866 5867 // grant unprotected <provider> read/write, if not blocked by 5868 // <path-permission> above 5869 if (allowDefaultRead) readMet = true; 5870 if (allowDefaultWrite) writeMet = true; 5871 5872 } catch (RemoteException e) { 5873 return false; 5874 } 5875 5876 return readMet && writeMet; 5877 } 5878 5879 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5880 ProviderInfo pi = null; 5881 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5882 if (cpr != null) { 5883 pi = cpr.info; 5884 } else { 5885 try { 5886 pi = AppGlobals.getPackageManager().resolveContentProvider( 5887 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5888 } catch (RemoteException ex) { 5889 } 5890 } 5891 return pi; 5892 } 5893 5894 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5895 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5896 if (targetUris != null) { 5897 return targetUris.get(uri); 5898 } else { 5899 return null; 5900 } 5901 } 5902 5903 private UriPermission findOrCreateUriPermissionLocked( 5904 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5905 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5906 if (targetUris == null) { 5907 targetUris = Maps.newArrayMap(); 5908 mGrantedUriPermissions.put(targetUid, targetUris); 5909 } 5910 5911 UriPermission perm = targetUris.get(uri); 5912 if (perm == null) { 5913 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5914 targetUris.put(uri, perm); 5915 } 5916 5917 return perm; 5918 } 5919 5920 private final boolean checkUriPermissionLocked( 5921 Uri uri, int uid, int modeFlags, int minStrength) { 5922 // Root gets to do everything. 5923 if (uid == 0) { 5924 return true; 5925 } 5926 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5927 if (perms == null) return false; 5928 UriPermission perm = perms.get(uri); 5929 if (perm == null) return false; 5930 return perm.getStrength(modeFlags) >= minStrength; 5931 } 5932 5933 @Override 5934 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5935 enforceNotIsolatedCaller("checkUriPermission"); 5936 5937 // Another redirected-binder-call permissions check as in 5938 // {@link checkComponentPermission}. 5939 Identity tlsIdentity = sCallerIdentity.get(); 5940 if (tlsIdentity != null) { 5941 uid = tlsIdentity.uid; 5942 pid = tlsIdentity.pid; 5943 } 5944 5945 // Our own process gets to do everything. 5946 if (pid == MY_PID) { 5947 return PackageManager.PERMISSION_GRANTED; 5948 } 5949 synchronized(this) { 5950 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5951 ? PackageManager.PERMISSION_GRANTED 5952 : PackageManager.PERMISSION_DENIED; 5953 } 5954 } 5955 5956 /** 5957 * Check if the targetPkg can be granted permission to access uri by 5958 * the callingUid using the given modeFlags. Throws a security exception 5959 * if callingUid is not allowed to do this. Returns the uid of the target 5960 * if the URI permission grant should be performed; returns -1 if it is not 5961 * needed (for example targetPkg already has permission to access the URI). 5962 * If you already know the uid of the target, you can supply it in 5963 * lastTargetUid else set that to -1. 5964 */ 5965 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5966 Uri uri, int modeFlags, int lastTargetUid) { 5967 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5968 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5969 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5970 if (modeFlags == 0) { 5971 return -1; 5972 } 5973 5974 if (targetPkg != null) { 5975 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5976 "Checking grant " + targetPkg + " permission to " + uri); 5977 } 5978 5979 final IPackageManager pm = AppGlobals.getPackageManager(); 5980 5981 // If this is not a content: uri, we can't do anything with it. 5982 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5983 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5984 "Can't grant URI permission for non-content URI: " + uri); 5985 return -1; 5986 } 5987 5988 final String authority = uri.getAuthority(); 5989 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 5990 if (pi == null) { 5991 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5992 return -1; 5993 } 5994 5995 int targetUid = lastTargetUid; 5996 if (targetUid < 0 && targetPkg != null) { 5997 try { 5998 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5999 if (targetUid < 0) { 6000 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6001 "Can't grant URI permission no uid for: " + targetPkg); 6002 return -1; 6003 } 6004 } catch (RemoteException ex) { 6005 return -1; 6006 } 6007 } 6008 6009 if (targetUid >= 0) { 6010 // First... does the target actually need this permission? 6011 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6012 // No need to grant the target this permission. 6013 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6014 "Target " + targetPkg + " already has full permission to " + uri); 6015 return -1; 6016 } 6017 } else { 6018 // First... there is no target package, so can anyone access it? 6019 boolean allowed = pi.exported; 6020 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6021 if (pi.readPermission != null) { 6022 allowed = false; 6023 } 6024 } 6025 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6026 if (pi.writePermission != null) { 6027 allowed = false; 6028 } 6029 } 6030 if (allowed) { 6031 return -1; 6032 } 6033 } 6034 6035 // Second... is the provider allowing granting of URI permissions? 6036 if (!pi.grantUriPermissions) { 6037 throw new SecurityException("Provider " + pi.packageName 6038 + "/" + pi.name 6039 + " does not allow granting of Uri permissions (uri " 6040 + uri + ")"); 6041 } 6042 if (pi.uriPermissionPatterns != null) { 6043 final int N = pi.uriPermissionPatterns.length; 6044 boolean allowed = false; 6045 for (int i=0; i<N; i++) { 6046 if (pi.uriPermissionPatterns[i] != null 6047 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6048 allowed = true; 6049 break; 6050 } 6051 } 6052 if (!allowed) { 6053 throw new SecurityException("Provider " + pi.packageName 6054 + "/" + pi.name 6055 + " does not allow granting of permission to path of Uri " 6056 + uri); 6057 } 6058 } 6059 6060 // Third... does the caller itself have permission to access 6061 // this uri? 6062 if (callingUid != Process.myUid()) { 6063 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6064 // Require they hold a strong enough Uri permission 6065 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6066 : UriPermission.STRENGTH_OWNED; 6067 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6068 throw new SecurityException("Uid " + callingUid 6069 + " does not have permission to uri " + uri); 6070 } 6071 } 6072 } 6073 6074 return targetUid; 6075 } 6076 6077 @Override 6078 public int checkGrantUriPermission(int callingUid, String targetPkg, 6079 Uri uri, int modeFlags) { 6080 enforceNotIsolatedCaller("checkGrantUriPermission"); 6081 synchronized(this) { 6082 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6083 } 6084 } 6085 6086 void grantUriPermissionUncheckedLocked( 6087 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6088 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6089 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6090 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6091 if (modeFlags == 0) { 6092 return; 6093 } 6094 6095 // So here we are: the caller has the assumed permission 6096 // to the uri, and the target doesn't. Let's now give this to 6097 // the target. 6098 6099 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6100 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6101 6102 final String authority = uri.getAuthority(); 6103 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6104 if (pi == null) { 6105 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6106 return; 6107 } 6108 6109 final UriPermission perm = findOrCreateUriPermissionLocked( 6110 pi.packageName, targetPkg, targetUid, uri); 6111 perm.grantModes(modeFlags, persistable, owner); 6112 } 6113 6114 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6115 int modeFlags, UriPermissionOwner owner) { 6116 if (targetPkg == null) { 6117 throw new NullPointerException("targetPkg"); 6118 } 6119 6120 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6121 if (targetUid < 0) { 6122 return; 6123 } 6124 6125 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6126 } 6127 6128 static class NeededUriGrants extends ArrayList<Uri> { 6129 final String targetPkg; 6130 final int targetUid; 6131 final int flags; 6132 6133 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6134 this.targetPkg = targetPkg; 6135 this.targetUid = targetUid; 6136 this.flags = flags; 6137 } 6138 } 6139 6140 /** 6141 * Like checkGrantUriPermissionLocked, but takes an Intent. 6142 */ 6143 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6144 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6145 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6146 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6147 + " clip=" + (intent != null ? intent.getClipData() : null) 6148 + " from " + intent + "; flags=0x" 6149 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6150 6151 if (targetPkg == null) { 6152 throw new NullPointerException("targetPkg"); 6153 } 6154 6155 if (intent == null) { 6156 return null; 6157 } 6158 Uri data = intent.getData(); 6159 ClipData clip = intent.getClipData(); 6160 if (data == null && clip == null) { 6161 return null; 6162 } 6163 6164 if (data != null) { 6165 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6166 mode, needed != null ? needed.targetUid : -1); 6167 if (targetUid > 0) { 6168 if (needed == null) { 6169 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6170 } 6171 needed.add(data); 6172 } 6173 } 6174 if (clip != null) { 6175 for (int i=0; i<clip.getItemCount(); i++) { 6176 Uri uri = clip.getItemAt(i).getUri(); 6177 if (uri != null) { 6178 int targetUid = -1; 6179 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6180 mode, needed != null ? needed.targetUid : -1); 6181 if (targetUid > 0) { 6182 if (needed == null) { 6183 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6184 } 6185 needed.add(uri); 6186 } 6187 } else { 6188 Intent clipIntent = clip.getItemAt(i).getIntent(); 6189 if (clipIntent != null) { 6190 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6191 callingUid, targetPkg, clipIntent, mode, needed); 6192 if (newNeeded != null) { 6193 needed = newNeeded; 6194 } 6195 } 6196 } 6197 } 6198 } 6199 6200 return needed; 6201 } 6202 6203 /** 6204 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6205 */ 6206 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6207 UriPermissionOwner owner) { 6208 if (needed != null) { 6209 for (int i=0; i<needed.size(); i++) { 6210 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6211 needed.get(i), needed.flags, owner); 6212 } 6213 } 6214 } 6215 6216 void grantUriPermissionFromIntentLocked(int callingUid, 6217 String targetPkg, Intent intent, UriPermissionOwner owner) { 6218 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6219 intent, intent != null ? intent.getFlags() : 0, null); 6220 if (needed == null) { 6221 return; 6222 } 6223 6224 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6225 } 6226 6227 @Override 6228 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6229 Uri uri, int modeFlags) { 6230 enforceNotIsolatedCaller("grantUriPermission"); 6231 synchronized(this) { 6232 final ProcessRecord r = getRecordForAppLocked(caller); 6233 if (r == null) { 6234 throw new SecurityException("Unable to find app for caller " 6235 + caller 6236 + " when granting permission to uri " + uri); 6237 } 6238 if (targetPkg == null) { 6239 throw new IllegalArgumentException("null target"); 6240 } 6241 if (uri == null) { 6242 throw new IllegalArgumentException("null uri"); 6243 } 6244 6245 // Persistable only supported through Intents 6246 Preconditions.checkFlagsArgument(modeFlags, 6247 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6248 6249 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6250 null); 6251 } 6252 } 6253 6254 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6255 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6256 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6257 ArrayMap<Uri, UriPermission> perms 6258 = mGrantedUriPermissions.get(perm.targetUid); 6259 if (perms != null) { 6260 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6261 "Removing " + perm.targetUid + " permission to " + perm.uri); 6262 perms.remove(perm.uri); 6263 if (perms.size() == 0) { 6264 mGrantedUriPermissions.remove(perm.targetUid); 6265 } 6266 } 6267 } 6268 } 6269 6270 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6271 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6272 6273 final IPackageManager pm = AppGlobals.getPackageManager(); 6274 final String authority = uri.getAuthority(); 6275 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6276 if (pi == null) { 6277 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6278 return; 6279 } 6280 6281 // Does the caller have this permission on the URI? 6282 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6283 // Right now, if you are not the original owner of the permission, 6284 // you are not allowed to revoke it. 6285 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6286 throw new SecurityException("Uid " + callingUid 6287 + " does not have permission to uri " + uri); 6288 //} 6289 } 6290 6291 boolean persistChanged = false; 6292 6293 // Go through all of the permissions and remove any that match. 6294 final List<String> SEGMENTS = uri.getPathSegments(); 6295 if (SEGMENTS != null) { 6296 final int NS = SEGMENTS.size(); 6297 int N = mGrantedUriPermissions.size(); 6298 for (int i=0; i<N; i++) { 6299 ArrayMap<Uri, UriPermission> perms 6300 = mGrantedUriPermissions.valueAt(i); 6301 Iterator<UriPermission> it = perms.values().iterator(); 6302 toploop: 6303 while (it.hasNext()) { 6304 UriPermission perm = it.next(); 6305 Uri targetUri = perm.uri; 6306 if (!authority.equals(targetUri.getAuthority())) { 6307 continue; 6308 } 6309 List<String> targetSegments = targetUri.getPathSegments(); 6310 if (targetSegments == null) { 6311 continue; 6312 } 6313 if (targetSegments.size() < NS) { 6314 continue; 6315 } 6316 for (int j=0; j<NS; j++) { 6317 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6318 continue toploop; 6319 } 6320 } 6321 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6322 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6323 persistChanged |= perm.clearModes(modeFlags, true); 6324 if (perm.modeFlags == 0) { 6325 it.remove(); 6326 } 6327 } 6328 if (perms.size() == 0) { 6329 mGrantedUriPermissions.remove( 6330 mGrantedUriPermissions.keyAt(i)); 6331 N--; 6332 i--; 6333 } 6334 } 6335 } 6336 6337 if (persistChanged) { 6338 schedulePersistUriGrants(); 6339 } 6340 } 6341 6342 @Override 6343 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6344 int modeFlags) { 6345 enforceNotIsolatedCaller("revokeUriPermission"); 6346 synchronized(this) { 6347 final ProcessRecord r = getRecordForAppLocked(caller); 6348 if (r == null) { 6349 throw new SecurityException("Unable to find app for caller " 6350 + caller 6351 + " when revoking permission to uri " + uri); 6352 } 6353 if (uri == null) { 6354 Slog.w(TAG, "revokeUriPermission: null uri"); 6355 return; 6356 } 6357 6358 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6359 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6360 if (modeFlags == 0) { 6361 return; 6362 } 6363 6364 final IPackageManager pm = AppGlobals.getPackageManager(); 6365 final String authority = uri.getAuthority(); 6366 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6367 if (pi == null) { 6368 Slog.w(TAG, "No content provider found for permission revoke: " 6369 + uri.toSafeString()); 6370 return; 6371 } 6372 6373 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6374 } 6375 } 6376 6377 /** 6378 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6379 * given package. 6380 * 6381 * @param packageName Package name to match, or {@code null} to apply to all 6382 * packages. 6383 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6384 * to all users. 6385 * @param persistable If persistable grants should be removed. 6386 */ 6387 private void removeUriPermissionsForPackageLocked( 6388 String packageName, int userHandle, boolean persistable) { 6389 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6390 throw new IllegalArgumentException("Must narrow by either package or user"); 6391 } 6392 6393 boolean persistChanged = false; 6394 6395 final int size = mGrantedUriPermissions.size(); 6396 for (int i = 0; i < size; i++) { 6397 // Only inspect grants matching user 6398 if (userHandle == UserHandle.USER_ALL 6399 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6400 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6401 .values().iterator(); 6402 while (it.hasNext()) { 6403 final UriPermission perm = it.next(); 6404 6405 // Only inspect grants matching package 6406 if (packageName == null || perm.sourcePkg.equals(packageName) 6407 || perm.targetPkg.equals(packageName)) { 6408 persistChanged |= perm.clearModes(~0, persistable); 6409 6410 // Only remove when no modes remain; any persisted grants 6411 // will keep this alive. 6412 if (perm.modeFlags == 0) { 6413 it.remove(); 6414 } 6415 } 6416 } 6417 } 6418 } 6419 6420 if (persistChanged) { 6421 schedulePersistUriGrants(); 6422 } 6423 } 6424 6425 @Override 6426 public IBinder newUriPermissionOwner(String name) { 6427 enforceNotIsolatedCaller("newUriPermissionOwner"); 6428 synchronized(this) { 6429 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6430 return owner.getExternalTokenLocked(); 6431 } 6432 } 6433 6434 @Override 6435 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6436 Uri uri, int modeFlags) { 6437 synchronized(this) { 6438 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6439 if (owner == null) { 6440 throw new IllegalArgumentException("Unknown owner: " + token); 6441 } 6442 if (fromUid != Binder.getCallingUid()) { 6443 if (Binder.getCallingUid() != Process.myUid()) { 6444 // Only system code can grant URI permissions on behalf 6445 // of other users. 6446 throw new SecurityException("nice try"); 6447 } 6448 } 6449 if (targetPkg == null) { 6450 throw new IllegalArgumentException("null target"); 6451 } 6452 if (uri == null) { 6453 throw new IllegalArgumentException("null uri"); 6454 } 6455 6456 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6457 } 6458 } 6459 6460 @Override 6461 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6462 synchronized(this) { 6463 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6464 if (owner == null) { 6465 throw new IllegalArgumentException("Unknown owner: " + token); 6466 } 6467 6468 if (uri == null) { 6469 owner.removeUriPermissionsLocked(mode); 6470 } else { 6471 owner.removeUriPermissionLocked(uri, mode); 6472 } 6473 } 6474 } 6475 6476 private void schedulePersistUriGrants() { 6477 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6478 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6479 10 * DateUtils.SECOND_IN_MILLIS); 6480 } 6481 } 6482 6483 private void writeGrantedUriPermissions() { 6484 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6485 6486 // Snapshot permissions so we can persist without lock 6487 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6488 synchronized (this) { 6489 final int size = mGrantedUriPermissions.size(); 6490 for (int i = 0 ; i < size; i++) { 6491 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6492 if (perm.persistedModeFlags != 0) { 6493 persist.add(perm.snapshot()); 6494 } 6495 } 6496 } 6497 } 6498 6499 FileOutputStream fos = null; 6500 try { 6501 fos = mGrantFile.startWrite(); 6502 6503 XmlSerializer out = new FastXmlSerializer(); 6504 out.setOutput(fos, "utf-8"); 6505 out.startDocument(null, true); 6506 out.startTag(null, TAG_URI_GRANTS); 6507 for (UriPermission.Snapshot perm : persist) { 6508 out.startTag(null, TAG_URI_GRANT); 6509 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6510 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6511 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6512 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6513 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6514 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6515 out.endTag(null, TAG_URI_GRANT); 6516 } 6517 out.endTag(null, TAG_URI_GRANTS); 6518 out.endDocument(); 6519 6520 mGrantFile.finishWrite(fos); 6521 } catch (IOException e) { 6522 if (fos != null) { 6523 mGrantFile.failWrite(fos); 6524 } 6525 } 6526 } 6527 6528 private void readGrantedUriPermissionsLocked() { 6529 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6530 6531 final long now = System.currentTimeMillis(); 6532 6533 FileInputStream fis = null; 6534 try { 6535 fis = mGrantFile.openRead(); 6536 final XmlPullParser in = Xml.newPullParser(); 6537 in.setInput(fis, null); 6538 6539 int type; 6540 while ((type = in.next()) != END_DOCUMENT) { 6541 final String tag = in.getName(); 6542 if (type == START_TAG) { 6543 if (TAG_URI_GRANT.equals(tag)) { 6544 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6545 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6546 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6547 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6548 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6549 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6550 6551 // Sanity check that provider still belongs to source package 6552 final ProviderInfo pi = getProviderInfoLocked( 6553 uri.getAuthority(), userHandle); 6554 if (pi != null && sourcePkg.equals(pi.packageName)) { 6555 int targetUid = -1; 6556 try { 6557 targetUid = AppGlobals.getPackageManager() 6558 .getPackageUid(targetPkg, userHandle); 6559 } catch (RemoteException e) { 6560 } 6561 if (targetUid != -1) { 6562 final UriPermission perm = findOrCreateUriPermissionLocked( 6563 sourcePkg, targetPkg, targetUid, uri); 6564 perm.initPersistedModes(modeFlags, createdTime); 6565 } 6566 } else { 6567 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6568 + " but instead found " + pi); 6569 } 6570 } 6571 } 6572 } 6573 } catch (FileNotFoundException e) { 6574 // Missing grants is okay 6575 } catch (IOException e) { 6576 Log.wtf(TAG, "Failed reading Uri grants", e); 6577 } catch (XmlPullParserException e) { 6578 Log.wtf(TAG, "Failed reading Uri grants", e); 6579 } finally { 6580 IoUtils.closeQuietly(fis); 6581 } 6582 } 6583 6584 @Override 6585 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6586 enforceNotIsolatedCaller("takePersistableUriPermission"); 6587 6588 Preconditions.checkFlagsArgument(modeFlags, 6589 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6590 6591 synchronized (this) { 6592 final int callingUid = Binder.getCallingUid(); 6593 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6594 if (perm == null) { 6595 throw new SecurityException("No permission grant found for UID " + callingUid 6596 + " and Uri " + uri.toSafeString()); 6597 } 6598 6599 boolean persistChanged = perm.takePersistableModes(modeFlags); 6600 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6601 6602 if (persistChanged) { 6603 schedulePersistUriGrants(); 6604 } 6605 } 6606 } 6607 6608 @Override 6609 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6610 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6611 6612 Preconditions.checkFlagsArgument(modeFlags, 6613 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6614 6615 synchronized (this) { 6616 final int callingUid = Binder.getCallingUid(); 6617 6618 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6619 if (perm == null) { 6620 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6621 + uri.toSafeString()); 6622 return; 6623 } 6624 6625 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6626 removeUriPermissionIfNeededLocked(perm); 6627 if (persistChanged) { 6628 schedulePersistUriGrants(); 6629 } 6630 } 6631 } 6632 6633 /** 6634 * Prune any older {@link UriPermission} for the given UID until outstanding 6635 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6636 * 6637 * @return if any mutations occured that require persisting. 6638 */ 6639 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6640 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6641 if (perms == null) return false; 6642 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6643 6644 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6645 for (UriPermission perm : perms.values()) { 6646 if (perm.persistedModeFlags != 0) { 6647 persisted.add(perm); 6648 } 6649 } 6650 6651 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6652 if (trimCount <= 0) return false; 6653 6654 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6655 for (int i = 0; i < trimCount; i++) { 6656 final UriPermission perm = persisted.get(i); 6657 6658 if (DEBUG_URI_PERMISSION) { 6659 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6660 } 6661 6662 perm.releasePersistableModes(~0); 6663 removeUriPermissionIfNeededLocked(perm); 6664 } 6665 6666 return true; 6667 } 6668 6669 @Override 6670 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6671 String packageName, boolean incoming) { 6672 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6673 Preconditions.checkNotNull(packageName, "packageName"); 6674 6675 final int callingUid = Binder.getCallingUid(); 6676 final IPackageManager pm = AppGlobals.getPackageManager(); 6677 try { 6678 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6679 if (packageUid != callingUid) { 6680 throw new SecurityException( 6681 "Package " + packageName + " does not belong to calling UID " + callingUid); 6682 } 6683 } catch (RemoteException e) { 6684 throw new SecurityException("Failed to verify package name ownership"); 6685 } 6686 6687 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6688 synchronized (this) { 6689 if (incoming) { 6690 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6691 if (perms == null) { 6692 Slog.w(TAG, "No permission grants found for " + packageName); 6693 } else { 6694 final int size = perms.size(); 6695 for (int i = 0; i < size; i++) { 6696 final UriPermission perm = perms.valueAt(i); 6697 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6698 result.add(perm.buildPersistedPublicApiObject()); 6699 } 6700 } 6701 } 6702 } else { 6703 final int size = mGrantedUriPermissions.size(); 6704 for (int i = 0; i < size; i++) { 6705 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6706 final int permsSize = perms.size(); 6707 for (int j = 0; j < permsSize; j++) { 6708 final UriPermission perm = perms.valueAt(j); 6709 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6710 result.add(perm.buildPersistedPublicApiObject()); 6711 } 6712 } 6713 } 6714 } 6715 } 6716 return new ParceledListSlice<android.content.UriPermission>(result); 6717 } 6718 6719 @Override 6720 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6721 synchronized (this) { 6722 ProcessRecord app = 6723 who != null ? getRecordForAppLocked(who) : null; 6724 if (app == null) return; 6725 6726 Message msg = Message.obtain(); 6727 msg.what = WAIT_FOR_DEBUGGER_MSG; 6728 msg.obj = app; 6729 msg.arg1 = waiting ? 1 : 0; 6730 mHandler.sendMessage(msg); 6731 } 6732 } 6733 6734 @Override 6735 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6736 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6737 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6738 outInfo.availMem = Process.getFreeMemory(); 6739 outInfo.totalMem = Process.getTotalMemory(); 6740 outInfo.threshold = homeAppMem; 6741 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6742 outInfo.hiddenAppThreshold = cachedAppMem; 6743 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6744 ProcessList.SERVICE_ADJ); 6745 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6746 ProcessList.VISIBLE_APP_ADJ); 6747 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6748 ProcessList.FOREGROUND_APP_ADJ); 6749 } 6750 6751 // ========================================================= 6752 // TASK MANAGEMENT 6753 // ========================================================= 6754 6755 @Override 6756 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6757 IThumbnailReceiver receiver) { 6758 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6759 6760 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6761 ActivityRecord topRecord = null; 6762 6763 synchronized(this) { 6764 if (localLOGV) Slog.v( 6765 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6766 + ", receiver=" + receiver); 6767 6768 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6769 != PackageManager.PERMISSION_GRANTED) { 6770 if (receiver != null) { 6771 // If the caller wants to wait for pending thumbnails, 6772 // it ain't gonna get them. 6773 try { 6774 receiver.finished(); 6775 } catch (RemoteException ex) { 6776 } 6777 } 6778 String msg = "Permission Denial: getTasks() from pid=" 6779 + Binder.getCallingPid() 6780 + ", uid=" + Binder.getCallingUid() 6781 + " requires " + android.Manifest.permission.GET_TASKS; 6782 Slog.w(TAG, msg); 6783 throw new SecurityException(msg); 6784 } 6785 6786 // TODO: Improve with MRU list from all ActivityStacks. 6787 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6788 6789 if (!pending.pendingRecords.isEmpty()) { 6790 mPendingThumbnails.add(pending); 6791 } 6792 } 6793 6794 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6795 6796 if (topRecord != null) { 6797 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6798 try { 6799 IApplicationThread topThumbnail = topRecord.app.thread; 6800 topThumbnail.requestThumbnail(topRecord.appToken); 6801 } catch (Exception e) { 6802 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6803 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6804 } 6805 } 6806 6807 if (pending == null && receiver != null) { 6808 // In this case all thumbnails were available and the client 6809 // is being asked to be told when the remaining ones come in... 6810 // which is unusually, since the top-most currently running 6811 // activity should never have a canned thumbnail! Oh well. 6812 try { 6813 receiver.finished(); 6814 } catch (RemoteException ex) { 6815 } 6816 } 6817 6818 return list; 6819 } 6820 6821 TaskRecord getMostRecentTask() { 6822 return mRecentTasks.get(0); 6823 } 6824 6825 @Override 6826 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6827 int flags, int userId) { 6828 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6829 false, true, "getRecentTasks", null); 6830 6831 synchronized (this) { 6832 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6833 "getRecentTasks()"); 6834 final boolean detailed = checkCallingPermission( 6835 android.Manifest.permission.GET_DETAILED_TASKS) 6836 == PackageManager.PERMISSION_GRANTED; 6837 6838 IPackageManager pm = AppGlobals.getPackageManager(); 6839 6840 final int N = mRecentTasks.size(); 6841 ArrayList<ActivityManager.RecentTaskInfo> res 6842 = new ArrayList<ActivityManager.RecentTaskInfo>( 6843 maxNum < N ? maxNum : N); 6844 for (int i=0; i<N && maxNum > 0; i++) { 6845 TaskRecord tr = mRecentTasks.get(i); 6846 // Only add calling user's recent tasks 6847 if (tr.userId != userId) continue; 6848 // Return the entry if desired by the caller. We always return 6849 // the first entry, because callers always expect this to be the 6850 // foreground app. We may filter others if the caller has 6851 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6852 // we should exclude the entry. 6853 6854 if (i == 0 6855 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6856 || (tr.intent == null) 6857 || ((tr.intent.getFlags() 6858 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6859 ActivityManager.RecentTaskInfo rti 6860 = new ActivityManager.RecentTaskInfo(); 6861 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6862 rti.persistentId = tr.taskId; 6863 rti.baseIntent = new Intent( 6864 tr.intent != null ? tr.intent : tr.affinityIntent); 6865 if (!detailed) { 6866 rti.baseIntent.replaceExtras((Bundle)null); 6867 } 6868 rti.origActivity = tr.origActivity; 6869 rti.description = tr.lastDescription; 6870 rti.stackId = tr.stack.mStackId; 6871 6872 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6873 // Check whether this activity is currently available. 6874 try { 6875 if (rti.origActivity != null) { 6876 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6877 == null) { 6878 continue; 6879 } 6880 } else if (rti.baseIntent != null) { 6881 if (pm.queryIntentActivities(rti.baseIntent, 6882 null, 0, userId) == null) { 6883 continue; 6884 } 6885 } 6886 } catch (RemoteException e) { 6887 // Will never happen. 6888 } 6889 } 6890 6891 res.add(rti); 6892 maxNum--; 6893 } 6894 } 6895 return res; 6896 } 6897 } 6898 6899 private TaskRecord recentTaskForIdLocked(int id) { 6900 final int N = mRecentTasks.size(); 6901 for (int i=0; i<N; i++) { 6902 TaskRecord tr = mRecentTasks.get(i); 6903 if (tr.taskId == id) { 6904 return tr; 6905 } 6906 } 6907 return null; 6908 } 6909 6910 @Override 6911 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6912 synchronized (this) { 6913 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6914 "getTaskThumbnails()"); 6915 TaskRecord tr = recentTaskForIdLocked(id); 6916 if (tr != null) { 6917 return tr.getTaskThumbnailsLocked(); 6918 } 6919 } 6920 return null; 6921 } 6922 6923 @Override 6924 public Bitmap getTaskTopThumbnail(int id) { 6925 synchronized (this) { 6926 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6927 "getTaskTopThumbnail()"); 6928 TaskRecord tr = recentTaskForIdLocked(id); 6929 if (tr != null) { 6930 return tr.getTaskTopThumbnailLocked(); 6931 } 6932 } 6933 return null; 6934 } 6935 6936 @Override 6937 public boolean removeSubTask(int taskId, int subTaskIndex) { 6938 synchronized (this) { 6939 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6940 "removeSubTask()"); 6941 long ident = Binder.clearCallingIdentity(); 6942 try { 6943 TaskRecord tr = recentTaskForIdLocked(taskId); 6944 if (tr != null) { 6945 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6946 } 6947 return false; 6948 } finally { 6949 Binder.restoreCallingIdentity(ident); 6950 } 6951 } 6952 } 6953 6954 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6955 if (!pr.killedByAm) { 6956 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6957 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6958 pr.processName, pr.setAdj, reason); 6959 pr.killedByAm = true; 6960 Process.killProcessQuiet(pr.pid); 6961 } 6962 } 6963 6964 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6965 tr.disposeThumbnail(); 6966 mRecentTasks.remove(tr); 6967 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6968 Intent baseIntent = new Intent( 6969 tr.intent != null ? tr.intent : tr.affinityIntent); 6970 ComponentName component = baseIntent.getComponent(); 6971 if (component == null) { 6972 Slog.w(TAG, "Now component for base intent of task: " + tr); 6973 return; 6974 } 6975 6976 // Find any running services associated with this app. 6977 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6978 6979 if (killProcesses) { 6980 // Find any running processes associated with this app. 6981 final String pkg = component.getPackageName(); 6982 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6983 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 6984 for (int i=0; i<pmap.size(); i++) { 6985 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 6986 for (int j=0; j<uids.size(); j++) { 6987 ProcessRecord proc = uids.valueAt(j); 6988 if (proc.userId != tr.userId) { 6989 continue; 6990 } 6991 if (!proc.pkgList.containsKey(pkg)) { 6992 continue; 6993 } 6994 procs.add(proc); 6995 } 6996 } 6997 6998 // Kill the running processes. 6999 for (int i=0; i<procs.size(); i++) { 7000 ProcessRecord pr = procs.get(i); 7001 if (pr == mHomeProcess) { 7002 // Don't kill the home process along with tasks from the same package. 7003 continue; 7004 } 7005 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7006 killUnneededProcessLocked(pr, "remove task"); 7007 } else { 7008 pr.waitingToKill = "remove task"; 7009 } 7010 } 7011 } 7012 } 7013 7014 @Override 7015 public boolean removeTask(int taskId, int flags) { 7016 synchronized (this) { 7017 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7018 "removeTask()"); 7019 long ident = Binder.clearCallingIdentity(); 7020 try { 7021 TaskRecord tr = recentTaskForIdLocked(taskId); 7022 if (tr != null) { 7023 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 7024 if (r != null) { 7025 cleanUpRemovedTaskLocked(tr, flags); 7026 return true; 7027 } 7028 if (tr.mActivities.size() == 0) { 7029 // Caller is just removing a recent task that is 7030 // not actively running. That is easy! 7031 cleanUpRemovedTaskLocked(tr, flags); 7032 return true; 7033 } 7034 Slog.w(TAG, "removeTask: task " + taskId 7035 + " does not have activities to remove, " 7036 + " but numActivities=" + tr.numActivities 7037 + ": " + tr); 7038 } 7039 } finally { 7040 Binder.restoreCallingIdentity(ident); 7041 } 7042 } 7043 return false; 7044 } 7045 7046 /** 7047 * TODO: Add mController hook 7048 */ 7049 @Override 7050 public void moveTaskToFront(int task, int flags, Bundle options) { 7051 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7052 "moveTaskToFront()"); 7053 7054 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task); 7055 synchronized(this) { 7056 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7057 Binder.getCallingUid(), "Task to front")) { 7058 ActivityOptions.abort(options); 7059 return; 7060 } 7061 final long origId = Binder.clearCallingIdentity(); 7062 try { 7063 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7064 } finally { 7065 Binder.restoreCallingIdentity(origId); 7066 } 7067 ActivityOptions.abort(options); 7068 } 7069 } 7070 7071 @Override 7072 public void moveTaskToBack(int taskId) { 7073 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7074 "moveTaskToBack()"); 7075 7076 synchronized(this) { 7077 TaskRecord tr = recentTaskForIdLocked(taskId); 7078 if (tr != null) { 7079 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7080 ActivityStack stack = tr.stack; 7081 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7082 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7083 Binder.getCallingUid(), "Task to back")) { 7084 return; 7085 } 7086 } 7087 final long origId = Binder.clearCallingIdentity(); 7088 try { 7089 stack.moveTaskToBackLocked(taskId, null); 7090 } finally { 7091 Binder.restoreCallingIdentity(origId); 7092 } 7093 } 7094 } 7095 } 7096 7097 /** 7098 * Moves an activity, and all of the other activities within the same task, to the bottom 7099 * of the history stack. The activity's order within the task is unchanged. 7100 * 7101 * @param token A reference to the activity we wish to move 7102 * @param nonRoot If false then this only works if the activity is the root 7103 * of a task; if true it will work for any activity in a task. 7104 * @return Returns true if the move completed, false if not. 7105 */ 7106 @Override 7107 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7108 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7109 synchronized(this) { 7110 final long origId = Binder.clearCallingIdentity(); 7111 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7112 if (taskId >= 0) { 7113 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7114 } 7115 Binder.restoreCallingIdentity(origId); 7116 } 7117 return false; 7118 } 7119 7120 @Override 7121 public void moveTaskBackwards(int task) { 7122 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7123 "moveTaskBackwards()"); 7124 7125 synchronized(this) { 7126 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7127 Binder.getCallingUid(), "Task backwards")) { 7128 return; 7129 } 7130 final long origId = Binder.clearCallingIdentity(); 7131 moveTaskBackwardsLocked(task); 7132 Binder.restoreCallingIdentity(origId); 7133 } 7134 } 7135 7136 private final void moveTaskBackwardsLocked(int task) { 7137 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7138 } 7139 7140 @Override 7141 public IBinder getHomeActivityToken() throws RemoteException { 7142 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7143 "getHomeActivityToken()"); 7144 synchronized (this) { 7145 return mStackSupervisor.getHomeActivityToken(); 7146 } 7147 } 7148 7149 @Override 7150 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7151 IActivityContainerCallback callback) throws RemoteException { 7152 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7153 "createActivityContainer()"); 7154 synchronized (this) { 7155 if (parentActivityToken == null) { 7156 throw new IllegalArgumentException("parent token must not be null"); 7157 } 7158 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7159 if (r == null) { 7160 return null; 7161 } 7162 return mStackSupervisor.createActivityContainer(r, callback); 7163 } 7164 } 7165 7166 @Override 7167 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7168 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7169 "deleteActivityContainer()"); 7170 synchronized (this) { 7171 mStackSupervisor.deleteActivityContainer(container); 7172 } 7173 } 7174 7175 @Override 7176 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7177 throws RemoteException { 7178 synchronized (this) { 7179 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7180 if (stack != null) { 7181 return stack.mActivityContainer; 7182 } 7183 return null; 7184 } 7185 } 7186 7187 @Override 7188 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7189 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7190 "moveTaskToStack()"); 7191 if (stackId == HOME_STACK_ID) { 7192 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7193 new RuntimeException("here").fillInStackTrace()); 7194 } 7195 synchronized (this) { 7196 long ident = Binder.clearCallingIdentity(); 7197 try { 7198 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7199 + stackId + " toTop=" + toTop); 7200 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7201 } finally { 7202 Binder.restoreCallingIdentity(ident); 7203 } 7204 } 7205 } 7206 7207 @Override 7208 public void resizeStack(int stackBoxId, Rect bounds) { 7209 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7210 "resizeStackBox()"); 7211 long ident = Binder.clearCallingIdentity(); 7212 try { 7213 mWindowManager.resizeStack(stackBoxId, bounds); 7214 } finally { 7215 Binder.restoreCallingIdentity(ident); 7216 } 7217 } 7218 7219 @Override 7220 public List<StackInfo> getAllStackInfos() { 7221 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7222 "getAllStackInfos()"); 7223 long ident = Binder.clearCallingIdentity(); 7224 try { 7225 synchronized (this) { 7226 return mStackSupervisor.getAllStackInfosLocked(); 7227 } 7228 } finally { 7229 Binder.restoreCallingIdentity(ident); 7230 } 7231 } 7232 7233 @Override 7234 public StackInfo getStackInfo(int stackId) { 7235 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7236 "getStackInfo()"); 7237 long ident = Binder.clearCallingIdentity(); 7238 try { 7239 synchronized (this) { 7240 return mStackSupervisor.getStackInfoLocked(stackId); 7241 } 7242 } finally { 7243 Binder.restoreCallingIdentity(ident); 7244 } 7245 } 7246 7247 @Override 7248 public boolean isInHomeStack(int taskId) { 7249 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7250 "getStackInfo()"); 7251 long ident = Binder.clearCallingIdentity(); 7252 try { 7253 synchronized (this) { 7254 TaskRecord tr = recentTaskForIdLocked(taskId); 7255 if (tr != null) { 7256 return tr.stack.isHomeStack(); 7257 } 7258 } 7259 } finally { 7260 Binder.restoreCallingIdentity(ident); 7261 } 7262 return false; 7263 } 7264 7265 @Override 7266 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7267 synchronized(this) { 7268 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7269 } 7270 } 7271 7272 // ========================================================= 7273 // THUMBNAILS 7274 // ========================================================= 7275 7276 public void reportThumbnail(IBinder token, 7277 Bitmap thumbnail, CharSequence description) { 7278 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7279 final long origId = Binder.clearCallingIdentity(); 7280 sendPendingThumbnail(null, token, thumbnail, description, true); 7281 Binder.restoreCallingIdentity(origId); 7282 } 7283 7284 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7285 Bitmap thumbnail, CharSequence description, boolean always) { 7286 TaskRecord task; 7287 ArrayList<PendingThumbnailsRecord> receivers = null; 7288 7289 //System.out.println("Send pending thumbnail: " + r); 7290 7291 synchronized(this) { 7292 if (r == null) { 7293 r = ActivityRecord.isInStackLocked(token); 7294 if (r == null) { 7295 return; 7296 } 7297 } 7298 if (thumbnail == null && r.thumbHolder != null) { 7299 thumbnail = r.thumbHolder.lastThumbnail; 7300 description = r.thumbHolder.lastDescription; 7301 } 7302 if (thumbnail == null && !always) { 7303 // If there is no thumbnail, and this entry is not actually 7304 // going away, then abort for now and pick up the next 7305 // thumbnail we get. 7306 return; 7307 } 7308 task = r.task; 7309 7310 int N = mPendingThumbnails.size(); 7311 int i=0; 7312 while (i<N) { 7313 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7314 //System.out.println("Looking in " + pr.pendingRecords); 7315 if (pr.pendingRecords.remove(r)) { 7316 if (receivers == null) { 7317 receivers = new ArrayList<PendingThumbnailsRecord>(); 7318 } 7319 receivers.add(pr); 7320 if (pr.pendingRecords.size() == 0) { 7321 pr.finished = true; 7322 mPendingThumbnails.remove(i); 7323 N--; 7324 continue; 7325 } 7326 } 7327 i++; 7328 } 7329 } 7330 7331 if (receivers != null) { 7332 final int N = receivers.size(); 7333 for (int i=0; i<N; i++) { 7334 try { 7335 PendingThumbnailsRecord pr = receivers.get(i); 7336 pr.receiver.newThumbnail( 7337 task != null ? task.taskId : -1, thumbnail, description); 7338 if (pr.finished) { 7339 pr.receiver.finished(); 7340 } 7341 } catch (Exception e) { 7342 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7343 } 7344 } 7345 } 7346 } 7347 7348 // ========================================================= 7349 // CONTENT PROVIDERS 7350 // ========================================================= 7351 7352 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7353 List<ProviderInfo> providers = null; 7354 try { 7355 providers = AppGlobals.getPackageManager(). 7356 queryContentProviders(app.processName, app.uid, 7357 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7358 } catch (RemoteException ex) { 7359 } 7360 if (DEBUG_MU) 7361 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7362 int userId = app.userId; 7363 if (providers != null) { 7364 int N = providers.size(); 7365 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7366 for (int i=0; i<N; i++) { 7367 ProviderInfo cpi = 7368 (ProviderInfo)providers.get(i); 7369 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7370 cpi.name, cpi.flags); 7371 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7372 // This is a singleton provider, but a user besides the 7373 // default user is asking to initialize a process it runs 7374 // in... well, no, it doesn't actually run in this process, 7375 // it runs in the process of the default user. Get rid of it. 7376 providers.remove(i); 7377 N--; 7378 i--; 7379 continue; 7380 } 7381 7382 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7383 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7384 if (cpr == null) { 7385 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7386 mProviderMap.putProviderByClass(comp, cpr); 7387 } 7388 if (DEBUG_MU) 7389 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7390 app.pubProviders.put(cpi.name, cpr); 7391 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7392 // Don't add this if it is a platform component that is marked 7393 // to run in multiple processes, because this is actually 7394 // part of the framework so doesn't make sense to track as a 7395 // separate apk in the process. 7396 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7397 } 7398 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7399 } 7400 } 7401 return providers; 7402 } 7403 7404 /** 7405 * Check if {@link ProcessRecord} has a possible chance at accessing the 7406 * given {@link ProviderInfo}. Final permission checking is always done 7407 * in {@link ContentProvider}. 7408 */ 7409 private final String checkContentProviderPermissionLocked( 7410 ProviderInfo cpi, ProcessRecord r) { 7411 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7412 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7413 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7414 cpi.applicationInfo.uid, cpi.exported) 7415 == PackageManager.PERMISSION_GRANTED) { 7416 return null; 7417 } 7418 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7419 cpi.applicationInfo.uid, cpi.exported) 7420 == PackageManager.PERMISSION_GRANTED) { 7421 return null; 7422 } 7423 7424 PathPermission[] pps = cpi.pathPermissions; 7425 if (pps != null) { 7426 int i = pps.length; 7427 while (i > 0) { 7428 i--; 7429 PathPermission pp = pps[i]; 7430 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7431 cpi.applicationInfo.uid, cpi.exported) 7432 == PackageManager.PERMISSION_GRANTED) { 7433 return null; 7434 } 7435 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7436 cpi.applicationInfo.uid, cpi.exported) 7437 == PackageManager.PERMISSION_GRANTED) { 7438 return null; 7439 } 7440 } 7441 } 7442 7443 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7444 if (perms != null) { 7445 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7446 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7447 return null; 7448 } 7449 } 7450 } 7451 7452 String msg; 7453 if (!cpi.exported) { 7454 msg = "Permission Denial: opening provider " + cpi.name 7455 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7456 + ", uid=" + callingUid + ") that is not exported from uid " 7457 + cpi.applicationInfo.uid; 7458 } else { 7459 msg = "Permission Denial: opening provider " + cpi.name 7460 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7461 + ", uid=" + callingUid + ") requires " 7462 + cpi.readPermission + " or " + cpi.writePermission; 7463 } 7464 Slog.w(TAG, msg); 7465 return msg; 7466 } 7467 7468 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7469 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7470 if (r != null) { 7471 for (int i=0; i<r.conProviders.size(); i++) { 7472 ContentProviderConnection conn = r.conProviders.get(i); 7473 if (conn.provider == cpr) { 7474 if (DEBUG_PROVIDER) Slog.v(TAG, 7475 "Adding provider requested by " 7476 + r.processName + " from process " 7477 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7478 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7479 if (stable) { 7480 conn.stableCount++; 7481 conn.numStableIncs++; 7482 } else { 7483 conn.unstableCount++; 7484 conn.numUnstableIncs++; 7485 } 7486 return conn; 7487 } 7488 } 7489 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7490 if (stable) { 7491 conn.stableCount = 1; 7492 conn.numStableIncs = 1; 7493 } else { 7494 conn.unstableCount = 1; 7495 conn.numUnstableIncs = 1; 7496 } 7497 cpr.connections.add(conn); 7498 r.conProviders.add(conn); 7499 return conn; 7500 } 7501 cpr.addExternalProcessHandleLocked(externalProcessToken); 7502 return null; 7503 } 7504 7505 boolean decProviderCountLocked(ContentProviderConnection conn, 7506 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7507 if (conn != null) { 7508 cpr = conn.provider; 7509 if (DEBUG_PROVIDER) Slog.v(TAG, 7510 "Removing provider requested by " 7511 + conn.client.processName + " from process " 7512 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7513 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7514 if (stable) { 7515 conn.stableCount--; 7516 } else { 7517 conn.unstableCount--; 7518 } 7519 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7520 cpr.connections.remove(conn); 7521 conn.client.conProviders.remove(conn); 7522 return true; 7523 } 7524 return false; 7525 } 7526 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7527 return false; 7528 } 7529 7530 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7531 String name, IBinder token, boolean stable, int userId) { 7532 ContentProviderRecord cpr; 7533 ContentProviderConnection conn = null; 7534 ProviderInfo cpi = null; 7535 7536 synchronized(this) { 7537 ProcessRecord r = null; 7538 if (caller != null) { 7539 r = getRecordForAppLocked(caller); 7540 if (r == null) { 7541 throw new SecurityException( 7542 "Unable to find app for caller " + caller 7543 + " (pid=" + Binder.getCallingPid() 7544 + ") when getting content provider " + name); 7545 } 7546 } 7547 7548 // First check if this content provider has been published... 7549 cpr = mProviderMap.getProviderByName(name, userId); 7550 boolean providerRunning = cpr != null; 7551 if (providerRunning) { 7552 cpi = cpr.info; 7553 String msg; 7554 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7555 throw new SecurityException(msg); 7556 } 7557 7558 if (r != null && cpr.canRunHere(r)) { 7559 // This provider has been published or is in the process 7560 // of being published... but it is also allowed to run 7561 // in the caller's process, so don't make a connection 7562 // and just let the caller instantiate its own instance. 7563 ContentProviderHolder holder = cpr.newHolder(null); 7564 // don't give caller the provider object, it needs 7565 // to make its own. 7566 holder.provider = null; 7567 return holder; 7568 } 7569 7570 final long origId = Binder.clearCallingIdentity(); 7571 7572 // In this case the provider instance already exists, so we can 7573 // return it right away. 7574 conn = incProviderCountLocked(r, cpr, token, stable); 7575 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7576 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7577 // If this is a perceptible app accessing the provider, 7578 // make sure to count it as being accessed and thus 7579 // back up on the LRU list. This is good because 7580 // content providers are often expensive to start. 7581 updateLruProcessLocked(cpr.proc, false, null); 7582 } 7583 } 7584 7585 if (cpr.proc != null) { 7586 if (false) { 7587 if (cpr.name.flattenToShortString().equals( 7588 "com.android.providers.calendar/.CalendarProvider2")) { 7589 Slog.v(TAG, "****************** KILLING " 7590 + cpr.name.flattenToShortString()); 7591 Process.killProcess(cpr.proc.pid); 7592 } 7593 } 7594 boolean success = updateOomAdjLocked(cpr.proc); 7595 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7596 // NOTE: there is still a race here where a signal could be 7597 // pending on the process even though we managed to update its 7598 // adj level. Not sure what to do about this, but at least 7599 // the race is now smaller. 7600 if (!success) { 7601 // Uh oh... it looks like the provider's process 7602 // has been killed on us. We need to wait for a new 7603 // process to be started, and make sure its death 7604 // doesn't kill our process. 7605 Slog.i(TAG, 7606 "Existing provider " + cpr.name.flattenToShortString() 7607 + " is crashing; detaching " + r); 7608 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7609 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7610 if (!lastRef) { 7611 // This wasn't the last ref our process had on 7612 // the provider... we have now been killed, bail. 7613 return null; 7614 } 7615 providerRunning = false; 7616 conn = null; 7617 } 7618 } 7619 7620 Binder.restoreCallingIdentity(origId); 7621 } 7622 7623 boolean singleton; 7624 if (!providerRunning) { 7625 try { 7626 cpi = AppGlobals.getPackageManager(). 7627 resolveContentProvider(name, 7628 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7629 } catch (RemoteException ex) { 7630 } 7631 if (cpi == null) { 7632 return null; 7633 } 7634 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7635 cpi.name, cpi.flags); 7636 if (singleton) { 7637 userId = 0; 7638 } 7639 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7640 7641 String msg; 7642 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7643 throw new SecurityException(msg); 7644 } 7645 7646 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7647 && !cpi.processName.equals("system")) { 7648 // If this content provider does not run in the system 7649 // process, and the system is not yet ready to run other 7650 // processes, then fail fast instead of hanging. 7651 throw new IllegalArgumentException( 7652 "Attempt to launch content provider before system ready"); 7653 } 7654 7655 // Make sure that the user who owns this provider is started. If not, 7656 // we don't want to allow it to run. 7657 if (mStartedUsers.get(userId) == null) { 7658 Slog.w(TAG, "Unable to launch app " 7659 + cpi.applicationInfo.packageName + "/" 7660 + cpi.applicationInfo.uid + " for provider " 7661 + name + ": user " + userId + " is stopped"); 7662 return null; 7663 } 7664 7665 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7666 cpr = mProviderMap.getProviderByClass(comp, userId); 7667 final boolean firstClass = cpr == null; 7668 if (firstClass) { 7669 try { 7670 ApplicationInfo ai = 7671 AppGlobals.getPackageManager(). 7672 getApplicationInfo( 7673 cpi.applicationInfo.packageName, 7674 STOCK_PM_FLAGS, userId); 7675 if (ai == null) { 7676 Slog.w(TAG, "No package info for content provider " 7677 + cpi.name); 7678 return null; 7679 } 7680 ai = getAppInfoForUser(ai, userId); 7681 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7682 } catch (RemoteException ex) { 7683 // pm is in same process, this will never happen. 7684 } 7685 } 7686 7687 if (r != null && cpr.canRunHere(r)) { 7688 // If this is a multiprocess provider, then just return its 7689 // info and allow the caller to instantiate it. Only do 7690 // this if the provider is the same user as the caller's 7691 // process, or can run as root (so can be in any process). 7692 return cpr.newHolder(null); 7693 } 7694 7695 if (DEBUG_PROVIDER) { 7696 RuntimeException e = new RuntimeException("here"); 7697 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7698 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7699 } 7700 7701 // This is single process, and our app is now connecting to it. 7702 // See if we are already in the process of launching this 7703 // provider. 7704 final int N = mLaunchingProviders.size(); 7705 int i; 7706 for (i=0; i<N; i++) { 7707 if (mLaunchingProviders.get(i) == cpr) { 7708 break; 7709 } 7710 } 7711 7712 // If the provider is not already being launched, then get it 7713 // started. 7714 if (i >= N) { 7715 final long origId = Binder.clearCallingIdentity(); 7716 7717 try { 7718 // Content provider is now in use, its package can't be stopped. 7719 try { 7720 AppGlobals.getPackageManager().setPackageStoppedState( 7721 cpr.appInfo.packageName, false, userId); 7722 } catch (RemoteException e) { 7723 } catch (IllegalArgumentException e) { 7724 Slog.w(TAG, "Failed trying to unstop package " 7725 + cpr.appInfo.packageName + ": " + e); 7726 } 7727 7728 // Use existing process if already started 7729 ProcessRecord proc = getProcessRecordLocked( 7730 cpi.processName, cpr.appInfo.uid, false); 7731 if (proc != null && proc.thread != null) { 7732 if (DEBUG_PROVIDER) { 7733 Slog.d(TAG, "Installing in existing process " + proc); 7734 } 7735 proc.pubProviders.put(cpi.name, cpr); 7736 try { 7737 proc.thread.scheduleInstallProvider(cpi); 7738 } catch (RemoteException e) { 7739 } 7740 } else { 7741 proc = startProcessLocked(cpi.processName, 7742 cpr.appInfo, false, 0, "content provider", 7743 new ComponentName(cpi.applicationInfo.packageName, 7744 cpi.name), false, false, false); 7745 if (proc == null) { 7746 Slog.w(TAG, "Unable to launch app " 7747 + cpi.applicationInfo.packageName + "/" 7748 + cpi.applicationInfo.uid + " for provider " 7749 + name + ": process is bad"); 7750 return null; 7751 } 7752 } 7753 cpr.launchingApp = proc; 7754 mLaunchingProviders.add(cpr); 7755 } finally { 7756 Binder.restoreCallingIdentity(origId); 7757 } 7758 } 7759 7760 // Make sure the provider is published (the same provider class 7761 // may be published under multiple names). 7762 if (firstClass) { 7763 mProviderMap.putProviderByClass(comp, cpr); 7764 } 7765 7766 mProviderMap.putProviderByName(name, cpr); 7767 conn = incProviderCountLocked(r, cpr, token, stable); 7768 if (conn != null) { 7769 conn.waiting = true; 7770 } 7771 } 7772 } 7773 7774 // Wait for the provider to be published... 7775 synchronized (cpr) { 7776 while (cpr.provider == null) { 7777 if (cpr.launchingApp == null) { 7778 Slog.w(TAG, "Unable to launch app " 7779 + cpi.applicationInfo.packageName + "/" 7780 + cpi.applicationInfo.uid + " for provider " 7781 + name + ": launching app became null"); 7782 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7783 UserHandle.getUserId(cpi.applicationInfo.uid), 7784 cpi.applicationInfo.packageName, 7785 cpi.applicationInfo.uid, name); 7786 return null; 7787 } 7788 try { 7789 if (DEBUG_MU) { 7790 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7791 + cpr.launchingApp); 7792 } 7793 if (conn != null) { 7794 conn.waiting = true; 7795 } 7796 cpr.wait(); 7797 } catch (InterruptedException ex) { 7798 } finally { 7799 if (conn != null) { 7800 conn.waiting = false; 7801 } 7802 } 7803 } 7804 } 7805 return cpr != null ? cpr.newHolder(conn) : null; 7806 } 7807 7808 public final ContentProviderHolder getContentProvider( 7809 IApplicationThread caller, String name, int userId, boolean stable) { 7810 enforceNotIsolatedCaller("getContentProvider"); 7811 if (caller == null) { 7812 String msg = "null IApplicationThread when getting content provider " 7813 + name; 7814 Slog.w(TAG, msg); 7815 throw new SecurityException(msg); 7816 } 7817 7818 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7819 false, true, "getContentProvider", null); 7820 return getContentProviderImpl(caller, name, null, stable, userId); 7821 } 7822 7823 public ContentProviderHolder getContentProviderExternal( 7824 String name, int userId, IBinder token) { 7825 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7826 "Do not have permission in call getContentProviderExternal()"); 7827 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7828 false, true, "getContentProvider", null); 7829 return getContentProviderExternalUnchecked(name, token, userId); 7830 } 7831 7832 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7833 IBinder token, int userId) { 7834 return getContentProviderImpl(null, name, token, true, userId); 7835 } 7836 7837 /** 7838 * Drop a content provider from a ProcessRecord's bookkeeping 7839 */ 7840 public void removeContentProvider(IBinder connection, boolean stable) { 7841 enforceNotIsolatedCaller("removeContentProvider"); 7842 long ident = Binder.clearCallingIdentity(); 7843 try { 7844 synchronized (this) { 7845 ContentProviderConnection conn; 7846 try { 7847 conn = (ContentProviderConnection)connection; 7848 } catch (ClassCastException e) { 7849 String msg ="removeContentProvider: " + connection 7850 + " not a ContentProviderConnection"; 7851 Slog.w(TAG, msg); 7852 throw new IllegalArgumentException(msg); 7853 } 7854 if (conn == null) { 7855 throw new NullPointerException("connection is null"); 7856 } 7857 if (decProviderCountLocked(conn, null, null, stable)) { 7858 updateOomAdjLocked(); 7859 } 7860 } 7861 } finally { 7862 Binder.restoreCallingIdentity(ident); 7863 } 7864 } 7865 7866 public void removeContentProviderExternal(String name, IBinder token) { 7867 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7868 "Do not have permission in call removeContentProviderExternal()"); 7869 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7870 } 7871 7872 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7873 synchronized (this) { 7874 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7875 if(cpr == null) { 7876 //remove from mProvidersByClass 7877 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7878 return; 7879 } 7880 7881 //update content provider record entry info 7882 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7883 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7884 if (localCpr.hasExternalProcessHandles()) { 7885 if (localCpr.removeExternalProcessHandleLocked(token)) { 7886 updateOomAdjLocked(); 7887 } else { 7888 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7889 + " with no external reference for token: " 7890 + token + "."); 7891 } 7892 } else { 7893 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7894 + " with no external references."); 7895 } 7896 } 7897 } 7898 7899 public final void publishContentProviders(IApplicationThread caller, 7900 List<ContentProviderHolder> providers) { 7901 if (providers == null) { 7902 return; 7903 } 7904 7905 enforceNotIsolatedCaller("publishContentProviders"); 7906 synchronized (this) { 7907 final ProcessRecord r = getRecordForAppLocked(caller); 7908 if (DEBUG_MU) 7909 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 7910 if (r == null) { 7911 throw new SecurityException( 7912 "Unable to find app for caller " + caller 7913 + " (pid=" + Binder.getCallingPid() 7914 + ") when publishing content providers"); 7915 } 7916 7917 final long origId = Binder.clearCallingIdentity(); 7918 7919 final int N = providers.size(); 7920 for (int i=0; i<N; i++) { 7921 ContentProviderHolder src = providers.get(i); 7922 if (src == null || src.info == null || src.provider == null) { 7923 continue; 7924 } 7925 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 7926 if (DEBUG_MU) 7927 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 7928 if (dst != null) { 7929 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 7930 mProviderMap.putProviderByClass(comp, dst); 7931 String names[] = dst.info.authority.split(";"); 7932 for (int j = 0; j < names.length; j++) { 7933 mProviderMap.putProviderByName(names[j], dst); 7934 } 7935 7936 int NL = mLaunchingProviders.size(); 7937 int j; 7938 for (j=0; j<NL; j++) { 7939 if (mLaunchingProviders.get(j) == dst) { 7940 mLaunchingProviders.remove(j); 7941 j--; 7942 NL--; 7943 } 7944 } 7945 synchronized (dst) { 7946 dst.provider = src.provider; 7947 dst.proc = r; 7948 dst.notifyAll(); 7949 } 7950 updateOomAdjLocked(r); 7951 } 7952 } 7953 7954 Binder.restoreCallingIdentity(origId); 7955 } 7956 } 7957 7958 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 7959 ContentProviderConnection conn; 7960 try { 7961 conn = (ContentProviderConnection)connection; 7962 } catch (ClassCastException e) { 7963 String msg ="refContentProvider: " + connection 7964 + " not a ContentProviderConnection"; 7965 Slog.w(TAG, msg); 7966 throw new IllegalArgumentException(msg); 7967 } 7968 if (conn == null) { 7969 throw new NullPointerException("connection is null"); 7970 } 7971 7972 synchronized (this) { 7973 if (stable > 0) { 7974 conn.numStableIncs += stable; 7975 } 7976 stable = conn.stableCount + stable; 7977 if (stable < 0) { 7978 throw new IllegalStateException("stableCount < 0: " + stable); 7979 } 7980 7981 if (unstable > 0) { 7982 conn.numUnstableIncs += unstable; 7983 } 7984 unstable = conn.unstableCount + unstable; 7985 if (unstable < 0) { 7986 throw new IllegalStateException("unstableCount < 0: " + unstable); 7987 } 7988 7989 if ((stable+unstable) <= 0) { 7990 throw new IllegalStateException("ref counts can't go to zero here: stable=" 7991 + stable + " unstable=" + unstable); 7992 } 7993 conn.stableCount = stable; 7994 conn.unstableCount = unstable; 7995 return !conn.dead; 7996 } 7997 } 7998 7999 public void unstableProviderDied(IBinder connection) { 8000 ContentProviderConnection conn; 8001 try { 8002 conn = (ContentProviderConnection)connection; 8003 } catch (ClassCastException e) { 8004 String msg ="refContentProvider: " + connection 8005 + " not a ContentProviderConnection"; 8006 Slog.w(TAG, msg); 8007 throw new IllegalArgumentException(msg); 8008 } 8009 if (conn == null) { 8010 throw new NullPointerException("connection is null"); 8011 } 8012 8013 // Safely retrieve the content provider associated with the connection. 8014 IContentProvider provider; 8015 synchronized (this) { 8016 provider = conn.provider.provider; 8017 } 8018 8019 if (provider == null) { 8020 // Um, yeah, we're way ahead of you. 8021 return; 8022 } 8023 8024 // Make sure the caller is being honest with us. 8025 if (provider.asBinder().pingBinder()) { 8026 // Er, no, still looks good to us. 8027 synchronized (this) { 8028 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8029 + " says " + conn + " died, but we don't agree"); 8030 return; 8031 } 8032 } 8033 8034 // Well look at that! It's dead! 8035 synchronized (this) { 8036 if (conn.provider.provider != provider) { 8037 // But something changed... good enough. 8038 return; 8039 } 8040 8041 ProcessRecord proc = conn.provider.proc; 8042 if (proc == null || proc.thread == null) { 8043 // Seems like the process is already cleaned up. 8044 return; 8045 } 8046 8047 // As far as we're concerned, this is just like receiving a 8048 // death notification... just a bit prematurely. 8049 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8050 + ") early provider death"); 8051 final long ident = Binder.clearCallingIdentity(); 8052 try { 8053 appDiedLocked(proc, proc.pid, proc.thread); 8054 } finally { 8055 Binder.restoreCallingIdentity(ident); 8056 } 8057 } 8058 } 8059 8060 @Override 8061 public void appNotRespondingViaProvider(IBinder connection) { 8062 enforceCallingPermission( 8063 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8064 8065 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8066 if (conn == null) { 8067 Slog.w(TAG, "ContentProviderConnection is null"); 8068 return; 8069 } 8070 8071 final ProcessRecord host = conn.provider.proc; 8072 if (host == null) { 8073 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8074 return; 8075 } 8076 8077 final long token = Binder.clearCallingIdentity(); 8078 try { 8079 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8080 } finally { 8081 Binder.restoreCallingIdentity(token); 8082 } 8083 } 8084 8085 public final void installSystemProviders() { 8086 List<ProviderInfo> providers; 8087 synchronized (this) { 8088 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8089 providers = generateApplicationProvidersLocked(app); 8090 if (providers != null) { 8091 for (int i=providers.size()-1; i>=0; i--) { 8092 ProviderInfo pi = (ProviderInfo)providers.get(i); 8093 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8094 Slog.w(TAG, "Not installing system proc provider " + pi.name 8095 + ": not system .apk"); 8096 providers.remove(i); 8097 } 8098 } 8099 } 8100 } 8101 if (providers != null) { 8102 mSystemThread.installSystemProviders(providers); 8103 } 8104 8105 mCoreSettingsObserver = new CoreSettingsObserver(this); 8106 8107 mUsageStatsService.monitorPackages(); 8108 } 8109 8110 /** 8111 * Allows app to retrieve the MIME type of a URI without having permission 8112 * to access its content provider. 8113 * 8114 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8115 * 8116 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8117 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8118 */ 8119 public String getProviderMimeType(Uri uri, int userId) { 8120 enforceNotIsolatedCaller("getProviderMimeType"); 8121 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8122 userId, false, true, "getProviderMimeType", null); 8123 final String name = uri.getAuthority(); 8124 final long ident = Binder.clearCallingIdentity(); 8125 ContentProviderHolder holder = null; 8126 8127 try { 8128 holder = getContentProviderExternalUnchecked(name, null, userId); 8129 if (holder != null) { 8130 return holder.provider.getType(uri); 8131 } 8132 } catch (RemoteException e) { 8133 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8134 return null; 8135 } finally { 8136 if (holder != null) { 8137 removeContentProviderExternalUnchecked(name, null, userId); 8138 } 8139 Binder.restoreCallingIdentity(ident); 8140 } 8141 8142 return null; 8143 } 8144 8145 // ========================================================= 8146 // GLOBAL MANAGEMENT 8147 // ========================================================= 8148 8149 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8150 boolean isolated) { 8151 String proc = customProcess != null ? customProcess : info.processName; 8152 BatteryStatsImpl.Uid.Proc ps = null; 8153 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8154 int uid = info.uid; 8155 if (isolated) { 8156 int userId = UserHandle.getUserId(uid); 8157 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8158 while (true) { 8159 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8160 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8161 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8162 } 8163 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8164 mNextIsolatedProcessUid++; 8165 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8166 // No process for this uid, use it. 8167 break; 8168 } 8169 stepsLeft--; 8170 if (stepsLeft <= 0) { 8171 return null; 8172 } 8173 } 8174 } 8175 return new ProcessRecord(stats, info, proc, uid); 8176 } 8177 8178 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8179 ProcessRecord app; 8180 if (!isolated) { 8181 app = getProcessRecordLocked(info.processName, info.uid, true); 8182 } else { 8183 app = null; 8184 } 8185 8186 if (app == null) { 8187 app = newProcessRecordLocked(info, null, isolated); 8188 mProcessNames.put(info.processName, app.uid, app); 8189 if (isolated) { 8190 mIsolatedProcesses.put(app.uid, app); 8191 } 8192 updateLruProcessLocked(app, false, null); 8193 updateOomAdjLocked(); 8194 } 8195 8196 // This package really, really can not be stopped. 8197 try { 8198 AppGlobals.getPackageManager().setPackageStoppedState( 8199 info.packageName, false, UserHandle.getUserId(app.uid)); 8200 } catch (RemoteException e) { 8201 } catch (IllegalArgumentException e) { 8202 Slog.w(TAG, "Failed trying to unstop package " 8203 + info.packageName + ": " + e); 8204 } 8205 8206 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8207 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8208 app.persistent = true; 8209 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8210 } 8211 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8212 mPersistentStartingProcesses.add(app); 8213 startProcessLocked(app, "added application", app.processName); 8214 } 8215 8216 return app; 8217 } 8218 8219 public void unhandledBack() { 8220 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8221 "unhandledBack()"); 8222 8223 synchronized(this) { 8224 final long origId = Binder.clearCallingIdentity(); 8225 try { 8226 getFocusedStack().unhandledBackLocked(); 8227 } finally { 8228 Binder.restoreCallingIdentity(origId); 8229 } 8230 } 8231 } 8232 8233 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8234 enforceNotIsolatedCaller("openContentUri"); 8235 final int userId = UserHandle.getCallingUserId(); 8236 String name = uri.getAuthority(); 8237 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8238 ParcelFileDescriptor pfd = null; 8239 if (cph != null) { 8240 // We record the binder invoker's uid in thread-local storage before 8241 // going to the content provider to open the file. Later, in the code 8242 // that handles all permissions checks, we look for this uid and use 8243 // that rather than the Activity Manager's own uid. The effect is that 8244 // we do the check against the caller's permissions even though it looks 8245 // to the content provider like the Activity Manager itself is making 8246 // the request. 8247 sCallerIdentity.set(new Identity( 8248 Binder.getCallingPid(), Binder.getCallingUid())); 8249 try { 8250 pfd = cph.provider.openFile(null, uri, "r", null); 8251 } catch (FileNotFoundException e) { 8252 // do nothing; pfd will be returned null 8253 } finally { 8254 // Ensure that whatever happens, we clean up the identity state 8255 sCallerIdentity.remove(); 8256 } 8257 8258 // We've got the fd now, so we're done with the provider. 8259 removeContentProviderExternalUnchecked(name, null, userId); 8260 } else { 8261 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8262 } 8263 return pfd; 8264 } 8265 8266 // Actually is sleeping or shutting down or whatever else in the future 8267 // is an inactive state. 8268 public boolean isSleepingOrShuttingDown() { 8269 return mSleeping || mShuttingDown; 8270 } 8271 8272 public void goingToSleep() { 8273 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8274 != PackageManager.PERMISSION_GRANTED) { 8275 throw new SecurityException("Requires permission " 8276 + android.Manifest.permission.DEVICE_POWER); 8277 } 8278 8279 synchronized(this) { 8280 mWentToSleep = true; 8281 updateEventDispatchingLocked(); 8282 8283 if (!mSleeping) { 8284 mSleeping = true; 8285 mStackSupervisor.goingToSleepLocked(); 8286 8287 // Initialize the wake times of all processes. 8288 checkExcessivePowerUsageLocked(false); 8289 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8290 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8291 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8292 } 8293 } 8294 } 8295 8296 @Override 8297 public boolean shutdown(int timeout) { 8298 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8299 != PackageManager.PERMISSION_GRANTED) { 8300 throw new SecurityException("Requires permission " 8301 + android.Manifest.permission.SHUTDOWN); 8302 } 8303 8304 boolean timedout = false; 8305 8306 synchronized(this) { 8307 mShuttingDown = true; 8308 updateEventDispatchingLocked(); 8309 timedout = mStackSupervisor.shutdownLocked(timeout); 8310 } 8311 8312 mAppOpsService.shutdown(); 8313 mUsageStatsService.shutdown(); 8314 mBatteryStatsService.shutdown(); 8315 synchronized (this) { 8316 mProcessStats.shutdownLocked(); 8317 } 8318 8319 return timedout; 8320 } 8321 8322 public final void activitySlept(IBinder token) { 8323 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8324 8325 final long origId = Binder.clearCallingIdentity(); 8326 8327 synchronized (this) { 8328 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8329 if (r != null) { 8330 mStackSupervisor.activitySleptLocked(r); 8331 } 8332 } 8333 8334 Binder.restoreCallingIdentity(origId); 8335 } 8336 8337 void logLockScreen(String msg) { 8338 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8339 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8340 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8341 mStackSupervisor.mDismissKeyguardOnNextActivity); 8342 } 8343 8344 private void comeOutOfSleepIfNeededLocked() { 8345 if (!mWentToSleep && !mLockScreenShown) { 8346 if (mSleeping) { 8347 mSleeping = false; 8348 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8349 } 8350 } 8351 } 8352 8353 public void wakingUp() { 8354 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8355 != PackageManager.PERMISSION_GRANTED) { 8356 throw new SecurityException("Requires permission " 8357 + android.Manifest.permission.DEVICE_POWER); 8358 } 8359 8360 synchronized(this) { 8361 mWentToSleep = false; 8362 updateEventDispatchingLocked(); 8363 comeOutOfSleepIfNeededLocked(); 8364 } 8365 } 8366 8367 private void updateEventDispatchingLocked() { 8368 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8369 } 8370 8371 public void setLockScreenShown(boolean shown) { 8372 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8373 != PackageManager.PERMISSION_GRANTED) { 8374 throw new SecurityException("Requires permission " 8375 + android.Manifest.permission.DEVICE_POWER); 8376 } 8377 8378 synchronized(this) { 8379 long ident = Binder.clearCallingIdentity(); 8380 try { 8381 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8382 mLockScreenShown = shown; 8383 comeOutOfSleepIfNeededLocked(); 8384 } finally { 8385 Binder.restoreCallingIdentity(ident); 8386 } 8387 } 8388 } 8389 8390 public void stopAppSwitches() { 8391 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8392 != PackageManager.PERMISSION_GRANTED) { 8393 throw new SecurityException("Requires permission " 8394 + android.Manifest.permission.STOP_APP_SWITCHES); 8395 } 8396 8397 synchronized(this) { 8398 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8399 + APP_SWITCH_DELAY_TIME; 8400 mDidAppSwitch = false; 8401 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8402 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8403 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8404 } 8405 } 8406 8407 public void resumeAppSwitches() { 8408 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8409 != PackageManager.PERMISSION_GRANTED) { 8410 throw new SecurityException("Requires permission " 8411 + android.Manifest.permission.STOP_APP_SWITCHES); 8412 } 8413 8414 synchronized(this) { 8415 // Note that we don't execute any pending app switches... we will 8416 // let those wait until either the timeout, or the next start 8417 // activity request. 8418 mAppSwitchesAllowedTime = 0; 8419 } 8420 } 8421 8422 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8423 String name) { 8424 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8425 return true; 8426 } 8427 8428 final int perm = checkComponentPermission( 8429 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8430 callingUid, -1, true); 8431 if (perm == PackageManager.PERMISSION_GRANTED) { 8432 return true; 8433 } 8434 8435 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8436 return false; 8437 } 8438 8439 public void setDebugApp(String packageName, boolean waitForDebugger, 8440 boolean persistent) { 8441 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8442 "setDebugApp()"); 8443 8444 long ident = Binder.clearCallingIdentity(); 8445 try { 8446 // Note that this is not really thread safe if there are multiple 8447 // callers into it at the same time, but that's not a situation we 8448 // care about. 8449 if (persistent) { 8450 final ContentResolver resolver = mContext.getContentResolver(); 8451 Settings.Global.putString( 8452 resolver, Settings.Global.DEBUG_APP, 8453 packageName); 8454 Settings.Global.putInt( 8455 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8456 waitForDebugger ? 1 : 0); 8457 } 8458 8459 synchronized (this) { 8460 if (!persistent) { 8461 mOrigDebugApp = mDebugApp; 8462 mOrigWaitForDebugger = mWaitForDebugger; 8463 } 8464 mDebugApp = packageName; 8465 mWaitForDebugger = waitForDebugger; 8466 mDebugTransient = !persistent; 8467 if (packageName != null) { 8468 forceStopPackageLocked(packageName, -1, false, false, true, true, 8469 false, UserHandle.USER_ALL, "set debug app"); 8470 } 8471 } 8472 } finally { 8473 Binder.restoreCallingIdentity(ident); 8474 } 8475 } 8476 8477 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8478 synchronized (this) { 8479 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8480 if (!isDebuggable) { 8481 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8482 throw new SecurityException("Process not debuggable: " + app.packageName); 8483 } 8484 } 8485 8486 mOpenGlTraceApp = processName; 8487 } 8488 } 8489 8490 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8491 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8492 synchronized (this) { 8493 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8494 if (!isDebuggable) { 8495 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8496 throw new SecurityException("Process not debuggable: " + app.packageName); 8497 } 8498 } 8499 mProfileApp = processName; 8500 mProfileFile = profileFile; 8501 if (mProfileFd != null) { 8502 try { 8503 mProfileFd.close(); 8504 } catch (IOException e) { 8505 } 8506 mProfileFd = null; 8507 } 8508 mProfileFd = profileFd; 8509 mProfileType = 0; 8510 mAutoStopProfiler = autoStopProfiler; 8511 } 8512 } 8513 8514 @Override 8515 public void setAlwaysFinish(boolean enabled) { 8516 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8517 "setAlwaysFinish()"); 8518 8519 Settings.Global.putInt( 8520 mContext.getContentResolver(), 8521 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8522 8523 synchronized (this) { 8524 mAlwaysFinishActivities = enabled; 8525 } 8526 } 8527 8528 @Override 8529 public void setActivityController(IActivityController controller) { 8530 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8531 "setActivityController()"); 8532 synchronized (this) { 8533 mController = controller; 8534 Watchdog.getInstance().setActivityController(controller); 8535 } 8536 } 8537 8538 @Override 8539 public void setUserIsMonkey(boolean userIsMonkey) { 8540 synchronized (this) { 8541 synchronized (mPidsSelfLocked) { 8542 final int callingPid = Binder.getCallingPid(); 8543 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8544 if (precessRecord == null) { 8545 throw new SecurityException("Unknown process: " + callingPid); 8546 } 8547 if (precessRecord.instrumentationUiAutomationConnection == null) { 8548 throw new SecurityException("Only an instrumentation process " 8549 + "with a UiAutomation can call setUserIsMonkey"); 8550 } 8551 } 8552 mUserIsMonkey = userIsMonkey; 8553 } 8554 } 8555 8556 @Override 8557 public boolean isUserAMonkey() { 8558 synchronized (this) { 8559 // If there is a controller also implies the user is a monkey. 8560 return (mUserIsMonkey || mController != null); 8561 } 8562 } 8563 8564 public void requestBugReport() { 8565 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8566 SystemProperties.set("ctl.start", "bugreport"); 8567 } 8568 8569 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8570 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8571 } 8572 8573 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8574 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8575 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8576 } 8577 return KEY_DISPATCHING_TIMEOUT; 8578 } 8579 8580 @Override 8581 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8582 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8583 != PackageManager.PERMISSION_GRANTED) { 8584 throw new SecurityException("Requires permission " 8585 + android.Manifest.permission.FILTER_EVENTS); 8586 } 8587 ProcessRecord proc; 8588 long timeout; 8589 synchronized (this) { 8590 synchronized (mPidsSelfLocked) { 8591 proc = mPidsSelfLocked.get(pid); 8592 } 8593 timeout = getInputDispatchingTimeoutLocked(proc); 8594 } 8595 8596 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8597 return -1; 8598 } 8599 8600 return timeout; 8601 } 8602 8603 /** 8604 * Handle input dispatching timeouts. 8605 * Returns whether input dispatching should be aborted or not. 8606 */ 8607 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8608 final ActivityRecord activity, final ActivityRecord parent, 8609 final boolean aboveSystem, String reason) { 8610 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8611 != PackageManager.PERMISSION_GRANTED) { 8612 throw new SecurityException("Requires permission " 8613 + android.Manifest.permission.FILTER_EVENTS); 8614 } 8615 8616 final String annotation; 8617 if (reason == null) { 8618 annotation = "Input dispatching timed out"; 8619 } else { 8620 annotation = "Input dispatching timed out (" + reason + ")"; 8621 } 8622 8623 if (proc != null) { 8624 synchronized (this) { 8625 if (proc.debugging) { 8626 return false; 8627 } 8628 8629 if (mDidDexOpt) { 8630 // Give more time since we were dexopting. 8631 mDidDexOpt = false; 8632 return false; 8633 } 8634 8635 if (proc.instrumentationClass != null) { 8636 Bundle info = new Bundle(); 8637 info.putString("shortMsg", "keyDispatchingTimedOut"); 8638 info.putString("longMsg", annotation); 8639 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8640 return true; 8641 } 8642 } 8643 mHandler.post(new Runnable() { 8644 @Override 8645 public void run() { 8646 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8647 } 8648 }); 8649 } 8650 8651 return true; 8652 } 8653 8654 public Bundle getAssistContextExtras(int requestType) { 8655 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8656 "getAssistContextExtras()"); 8657 PendingAssistExtras pae; 8658 Bundle extras = new Bundle(); 8659 synchronized (this) { 8660 ActivityRecord activity = getFocusedStack().mResumedActivity; 8661 if (activity == null) { 8662 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8663 return null; 8664 } 8665 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8666 if (activity.app == null || activity.app.thread == null) { 8667 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8668 return extras; 8669 } 8670 if (activity.app.pid == Binder.getCallingPid()) { 8671 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8672 return extras; 8673 } 8674 pae = new PendingAssistExtras(activity); 8675 try { 8676 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8677 requestType); 8678 mPendingAssistExtras.add(pae); 8679 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8680 } catch (RemoteException e) { 8681 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8682 return extras; 8683 } 8684 } 8685 synchronized (pae) { 8686 while (!pae.haveResult) { 8687 try { 8688 pae.wait(); 8689 } catch (InterruptedException e) { 8690 } 8691 } 8692 if (pae.result != null) { 8693 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8694 } 8695 } 8696 synchronized (this) { 8697 mPendingAssistExtras.remove(pae); 8698 mHandler.removeCallbacks(pae); 8699 } 8700 return extras; 8701 } 8702 8703 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8704 PendingAssistExtras pae = (PendingAssistExtras)token; 8705 synchronized (pae) { 8706 pae.result = extras; 8707 pae.haveResult = true; 8708 pae.notifyAll(); 8709 } 8710 } 8711 8712 public void registerProcessObserver(IProcessObserver observer) { 8713 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8714 "registerProcessObserver()"); 8715 synchronized (this) { 8716 mProcessObservers.register(observer); 8717 } 8718 } 8719 8720 @Override 8721 public void unregisterProcessObserver(IProcessObserver observer) { 8722 synchronized (this) { 8723 mProcessObservers.unregister(observer); 8724 } 8725 } 8726 8727 @Override 8728 public boolean convertFromTranslucent(IBinder token) { 8729 final long origId = Binder.clearCallingIdentity(); 8730 try { 8731 synchronized (this) { 8732 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8733 if (r == null) { 8734 return false; 8735 } 8736 if (r.changeWindowTranslucency(true)) { 8737 mWindowManager.setAppFullscreen(token, true); 8738 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8739 return true; 8740 } 8741 return false; 8742 } 8743 } finally { 8744 Binder.restoreCallingIdentity(origId); 8745 } 8746 } 8747 8748 @Override 8749 public boolean convertToTranslucent(IBinder token) { 8750 final long origId = Binder.clearCallingIdentity(); 8751 try { 8752 synchronized (this) { 8753 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8754 if (r == null) { 8755 return false; 8756 } 8757 if (r.changeWindowTranslucency(false)) { 8758 r.task.stack.convertToTranslucent(r); 8759 mWindowManager.setAppFullscreen(token, false); 8760 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8761 return true; 8762 } 8763 return false; 8764 } 8765 } finally { 8766 Binder.restoreCallingIdentity(origId); 8767 } 8768 } 8769 8770 @Override 8771 public void setImmersive(IBinder token, boolean immersive) { 8772 synchronized(this) { 8773 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8774 if (r == null) { 8775 throw new IllegalArgumentException(); 8776 } 8777 r.immersive = immersive; 8778 8779 // update associated state if we're frontmost 8780 if (r == mFocusedActivity) { 8781 if (DEBUG_IMMERSIVE) { 8782 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8783 } 8784 applyUpdateLockStateLocked(r); 8785 } 8786 } 8787 } 8788 8789 @Override 8790 public boolean isImmersive(IBinder token) { 8791 synchronized (this) { 8792 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8793 if (r == null) { 8794 throw new IllegalArgumentException(); 8795 } 8796 return r.immersive; 8797 } 8798 } 8799 8800 public boolean isTopActivityImmersive() { 8801 enforceNotIsolatedCaller("startActivity"); 8802 synchronized (this) { 8803 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8804 return (r != null) ? r.immersive : false; 8805 } 8806 } 8807 8808 public final void enterSafeMode() { 8809 synchronized(this) { 8810 // It only makes sense to do this before the system is ready 8811 // and started launching other packages. 8812 if (!mSystemReady) { 8813 try { 8814 AppGlobals.getPackageManager().enterSafeMode(); 8815 } catch (RemoteException e) { 8816 } 8817 } 8818 } 8819 } 8820 8821 public final void showSafeModeOverlay() { 8822 View v = LayoutInflater.from(mContext).inflate( 8823 com.android.internal.R.layout.safe_mode, null); 8824 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8825 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8826 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8827 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8828 lp.gravity = Gravity.BOTTOM | Gravity.START; 8829 lp.format = v.getBackground().getOpacity(); 8830 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8831 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8832 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8833 ((WindowManager)mContext.getSystemService( 8834 Context.WINDOW_SERVICE)).addView(v, lp); 8835 } 8836 8837 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 8838 if (!(sender instanceof PendingIntentRecord)) { 8839 return; 8840 } 8841 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8842 synchronized (stats) { 8843 if (mBatteryStatsService.isOnBattery()) { 8844 mBatteryStatsService.enforceCallingPermission(); 8845 PendingIntentRecord rec = (PendingIntentRecord)sender; 8846 int MY_UID = Binder.getCallingUid(); 8847 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8848 BatteryStatsImpl.Uid.Pkg pkg = 8849 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 8850 sourcePkg != null ? sourcePkg : rec.key.packageName); 8851 pkg.incWakeupsLocked(); 8852 } 8853 } 8854 } 8855 8856 public boolean killPids(int[] pids, String pReason, boolean secure) { 8857 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8858 throw new SecurityException("killPids only available to the system"); 8859 } 8860 String reason = (pReason == null) ? "Unknown" : pReason; 8861 // XXX Note: don't acquire main activity lock here, because the window 8862 // manager calls in with its locks held. 8863 8864 boolean killed = false; 8865 synchronized (mPidsSelfLocked) { 8866 int[] types = new int[pids.length]; 8867 int worstType = 0; 8868 for (int i=0; i<pids.length; i++) { 8869 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8870 if (proc != null) { 8871 int type = proc.setAdj; 8872 types[i] = type; 8873 if (type > worstType) { 8874 worstType = type; 8875 } 8876 } 8877 } 8878 8879 // If the worst oom_adj is somewhere in the cached proc LRU range, 8880 // then constrain it so we will kill all cached procs. 8881 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8882 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8883 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8884 } 8885 8886 // If this is not a secure call, don't let it kill processes that 8887 // are important. 8888 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8889 worstType = ProcessList.SERVICE_ADJ; 8890 } 8891 8892 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8893 for (int i=0; i<pids.length; i++) { 8894 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8895 if (proc == null) { 8896 continue; 8897 } 8898 int adj = proc.setAdj; 8899 if (adj >= worstType && !proc.killedByAm) { 8900 killUnneededProcessLocked(proc, reason); 8901 killed = true; 8902 } 8903 } 8904 } 8905 return killed; 8906 } 8907 8908 @Override 8909 public void killUid(int uid, String reason) { 8910 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8911 throw new SecurityException("killUid only available to the system"); 8912 } 8913 synchronized (this) { 8914 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 8915 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 8916 reason != null ? reason : "kill uid"); 8917 } 8918 } 8919 8920 @Override 8921 public boolean killProcessesBelowForeground(String reason) { 8922 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8923 throw new SecurityException("killProcessesBelowForeground() only available to system"); 8924 } 8925 8926 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 8927 } 8928 8929 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 8930 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8931 throw new SecurityException("killProcessesBelowAdj() only available to system"); 8932 } 8933 8934 boolean killed = false; 8935 synchronized (mPidsSelfLocked) { 8936 final int size = mPidsSelfLocked.size(); 8937 for (int i = 0; i < size; i++) { 8938 final int pid = mPidsSelfLocked.keyAt(i); 8939 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8940 if (proc == null) continue; 8941 8942 final int adj = proc.setAdj; 8943 if (adj > belowAdj && !proc.killedByAm) { 8944 killUnneededProcessLocked(proc, reason); 8945 killed = true; 8946 } 8947 } 8948 } 8949 return killed; 8950 } 8951 8952 @Override 8953 public void hang(final IBinder who, boolean allowRestart) { 8954 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8955 != PackageManager.PERMISSION_GRANTED) { 8956 throw new SecurityException("Requires permission " 8957 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8958 } 8959 8960 final IBinder.DeathRecipient death = new DeathRecipient() { 8961 @Override 8962 public void binderDied() { 8963 synchronized (this) { 8964 notifyAll(); 8965 } 8966 } 8967 }; 8968 8969 try { 8970 who.linkToDeath(death, 0); 8971 } catch (RemoteException e) { 8972 Slog.w(TAG, "hang: given caller IBinder is already dead."); 8973 return; 8974 } 8975 8976 synchronized (this) { 8977 Watchdog.getInstance().setAllowRestart(allowRestart); 8978 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 8979 synchronized (death) { 8980 while (who.isBinderAlive()) { 8981 try { 8982 death.wait(); 8983 } catch (InterruptedException e) { 8984 } 8985 } 8986 } 8987 Watchdog.getInstance().setAllowRestart(true); 8988 } 8989 } 8990 8991 @Override 8992 public void restart() { 8993 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8994 != PackageManager.PERMISSION_GRANTED) { 8995 throw new SecurityException("Requires permission " 8996 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8997 } 8998 8999 Log.i(TAG, "Sending shutdown broadcast..."); 9000 9001 BroadcastReceiver br = new BroadcastReceiver() { 9002 @Override public void onReceive(Context context, Intent intent) { 9003 // Now the broadcast is done, finish up the low-level shutdown. 9004 Log.i(TAG, "Shutting down activity manager..."); 9005 shutdown(10000); 9006 Log.i(TAG, "Shutdown complete, restarting!"); 9007 Process.killProcess(Process.myPid()); 9008 System.exit(10); 9009 } 9010 }; 9011 9012 // First send the high-level shut down broadcast. 9013 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9014 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9015 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9016 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9017 mContext.sendOrderedBroadcastAsUser(intent, 9018 UserHandle.ALL, null, br, mHandler, 0, null, null); 9019 */ 9020 br.onReceive(mContext, intent); 9021 } 9022 9023 private long getLowRamTimeSinceIdle(long now) { 9024 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9025 } 9026 9027 @Override 9028 public void performIdleMaintenance() { 9029 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9030 != PackageManager.PERMISSION_GRANTED) { 9031 throw new SecurityException("Requires permission " 9032 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9033 } 9034 9035 synchronized (this) { 9036 final long now = SystemClock.uptimeMillis(); 9037 final long timeSinceLastIdle = now - mLastIdleTime; 9038 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9039 mLastIdleTime = now; 9040 mLowRamTimeSinceLastIdle = 0; 9041 if (mLowRamStartTime != 0) { 9042 mLowRamStartTime = now; 9043 } 9044 9045 StringBuilder sb = new StringBuilder(128); 9046 sb.append("Idle maintenance over "); 9047 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9048 sb.append(" low RAM for "); 9049 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9050 Slog.i(TAG, sb.toString()); 9051 9052 // If at least 1/3 of our time since the last idle period has been spent 9053 // with RAM low, then we want to kill processes. 9054 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9055 9056 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9057 ProcessRecord proc = mLruProcesses.get(i); 9058 if (proc.notCachedSinceIdle) { 9059 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9060 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9061 if (doKilling && proc.initialIdlePss != 0 9062 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9063 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9064 + " from " + proc.initialIdlePss + ")"); 9065 } 9066 } 9067 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9068 proc.notCachedSinceIdle = true; 9069 proc.initialIdlePss = 0; 9070 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9071 mSleeping, now); 9072 } 9073 } 9074 9075 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9076 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9077 } 9078 } 9079 9080 public final void startRunning(String pkg, String cls, String action, 9081 String data) { 9082 synchronized(this) { 9083 if (mStartRunning) { 9084 return; 9085 } 9086 mStartRunning = true; 9087 mTopComponent = pkg != null && cls != null 9088 ? new ComponentName(pkg, cls) : null; 9089 mTopAction = action != null ? action : Intent.ACTION_MAIN; 9090 mTopData = data; 9091 if (!mSystemReady) { 9092 return; 9093 } 9094 } 9095 9096 systemReady(null); 9097 } 9098 9099 private void retrieveSettings() { 9100 final ContentResolver resolver = mContext.getContentResolver(); 9101 String debugApp = Settings.Global.getString( 9102 resolver, Settings.Global.DEBUG_APP); 9103 boolean waitForDebugger = Settings.Global.getInt( 9104 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9105 boolean alwaysFinishActivities = Settings.Global.getInt( 9106 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9107 boolean forceRtl = Settings.Global.getInt( 9108 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9109 // Transfer any global setting for forcing RTL layout, into a System Property 9110 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9111 9112 Configuration configuration = new Configuration(); 9113 Settings.System.getConfiguration(resolver, configuration); 9114 if (forceRtl) { 9115 // This will take care of setting the correct layout direction flags 9116 configuration.setLayoutDirection(configuration.locale); 9117 } 9118 9119 synchronized (this) { 9120 mDebugApp = mOrigDebugApp = debugApp; 9121 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9122 mAlwaysFinishActivities = alwaysFinishActivities; 9123 // This happens before any activities are started, so we can 9124 // change mConfiguration in-place. 9125 updateConfigurationLocked(configuration, null, false, true); 9126 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9127 } 9128 } 9129 9130 public boolean testIsSystemReady() { 9131 // no need to synchronize(this) just to read & return the value 9132 return mSystemReady; 9133 } 9134 9135 private static File getCalledPreBootReceiversFile() { 9136 File dataDir = Environment.getDataDirectory(); 9137 File systemDir = new File(dataDir, "system"); 9138 File fname = new File(systemDir, "called_pre_boots.dat"); 9139 return fname; 9140 } 9141 9142 static final int LAST_DONE_VERSION = 10000; 9143 9144 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9145 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9146 File file = getCalledPreBootReceiversFile(); 9147 FileInputStream fis = null; 9148 try { 9149 fis = new FileInputStream(file); 9150 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9151 int fvers = dis.readInt(); 9152 if (fvers == LAST_DONE_VERSION) { 9153 String vers = dis.readUTF(); 9154 String codename = dis.readUTF(); 9155 String build = dis.readUTF(); 9156 if (android.os.Build.VERSION.RELEASE.equals(vers) 9157 && android.os.Build.VERSION.CODENAME.equals(codename) 9158 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9159 int num = dis.readInt(); 9160 while (num > 0) { 9161 num--; 9162 String pkg = dis.readUTF(); 9163 String cls = dis.readUTF(); 9164 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9165 } 9166 } 9167 } 9168 } catch (FileNotFoundException e) { 9169 } catch (IOException e) { 9170 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9171 } finally { 9172 if (fis != null) { 9173 try { 9174 fis.close(); 9175 } catch (IOException e) { 9176 } 9177 } 9178 } 9179 return lastDoneReceivers; 9180 } 9181 9182 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9183 File file = getCalledPreBootReceiversFile(); 9184 FileOutputStream fos = null; 9185 DataOutputStream dos = null; 9186 try { 9187 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9188 fos = new FileOutputStream(file); 9189 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9190 dos.writeInt(LAST_DONE_VERSION); 9191 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9192 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9193 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9194 dos.writeInt(list.size()); 9195 for (int i=0; i<list.size(); i++) { 9196 dos.writeUTF(list.get(i).getPackageName()); 9197 dos.writeUTF(list.get(i).getClassName()); 9198 } 9199 } catch (IOException e) { 9200 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9201 file.delete(); 9202 } finally { 9203 FileUtils.sync(fos); 9204 if (dos != null) { 9205 try { 9206 dos.close(); 9207 } catch (IOException e) { 9208 // TODO Auto-generated catch block 9209 e.printStackTrace(); 9210 } 9211 } 9212 } 9213 } 9214 9215 public void systemReady(final Runnable goingCallback) { 9216 synchronized(this) { 9217 if (mSystemReady) { 9218 if (goingCallback != null) goingCallback.run(); 9219 return; 9220 } 9221 9222 // Check to see if there are any update receivers to run. 9223 if (!mDidUpdate) { 9224 if (mWaitingUpdate) { 9225 return; 9226 } 9227 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9228 List<ResolveInfo> ris = null; 9229 try { 9230 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9231 intent, null, 0, 0); 9232 } catch (RemoteException e) { 9233 } 9234 if (ris != null) { 9235 for (int i=ris.size()-1; i>=0; i--) { 9236 if ((ris.get(i).activityInfo.applicationInfo.flags 9237 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9238 ris.remove(i); 9239 } 9240 } 9241 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9242 9243 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9244 9245 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9246 for (int i=0; i<ris.size(); i++) { 9247 ActivityInfo ai = ris.get(i).activityInfo; 9248 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9249 if (lastDoneReceivers.contains(comp)) { 9250 // We already did the pre boot receiver for this app with the current 9251 // platform version, so don't do it again... 9252 ris.remove(i); 9253 i--; 9254 // ...however, do keep it as one that has been done, so we don't 9255 // forget about it when rewriting the file of last done receivers. 9256 doneReceivers.add(comp); 9257 } 9258 } 9259 9260 final int[] users = getUsersLocked(); 9261 for (int i=0; i<ris.size(); i++) { 9262 ActivityInfo ai = ris.get(i).activityInfo; 9263 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9264 doneReceivers.add(comp); 9265 intent.setComponent(comp); 9266 for (int j=0; j<users.length; j++) { 9267 IIntentReceiver finisher = null; 9268 if (i == ris.size()-1 && j == users.length-1) { 9269 finisher = new IIntentReceiver.Stub() { 9270 public void performReceive(Intent intent, int resultCode, 9271 String data, Bundle extras, boolean ordered, 9272 boolean sticky, int sendingUser) { 9273 // The raw IIntentReceiver interface is called 9274 // with the AM lock held, so redispatch to 9275 // execute our code without the lock. 9276 mHandler.post(new Runnable() { 9277 public void run() { 9278 synchronized (ActivityManagerService.this) { 9279 mDidUpdate = true; 9280 } 9281 writeLastDonePreBootReceivers(doneReceivers); 9282 showBootMessage(mContext.getText( 9283 R.string.android_upgrading_complete), 9284 false); 9285 systemReady(goingCallback); 9286 } 9287 }); 9288 } 9289 }; 9290 } 9291 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9292 + " for user " + users[j]); 9293 broadcastIntentLocked(null, null, intent, null, finisher, 9294 0, null, null, null, AppOpsManager.OP_NONE, 9295 true, false, MY_PID, Process.SYSTEM_UID, 9296 users[j]); 9297 if (finisher != null) { 9298 mWaitingUpdate = true; 9299 } 9300 } 9301 } 9302 } 9303 if (mWaitingUpdate) { 9304 return; 9305 } 9306 mDidUpdate = true; 9307 } 9308 9309 mAppOpsService.systemReady(); 9310 mSystemReady = true; 9311 if (!mStartRunning) { 9312 return; 9313 } 9314 } 9315 9316 ArrayList<ProcessRecord> procsToKill = null; 9317 synchronized(mPidsSelfLocked) { 9318 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9319 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9320 if (!isAllowedWhileBooting(proc.info)){ 9321 if (procsToKill == null) { 9322 procsToKill = new ArrayList<ProcessRecord>(); 9323 } 9324 procsToKill.add(proc); 9325 } 9326 } 9327 } 9328 9329 synchronized(this) { 9330 if (procsToKill != null) { 9331 for (int i=procsToKill.size()-1; i>=0; i--) { 9332 ProcessRecord proc = procsToKill.get(i); 9333 Slog.i(TAG, "Removing system update proc: " + proc); 9334 removeProcessLocked(proc, true, false, "system update done"); 9335 } 9336 } 9337 9338 // Now that we have cleaned up any update processes, we 9339 // are ready to start launching real processes and know that 9340 // we won't trample on them any more. 9341 mProcessesReady = true; 9342 } 9343 9344 Slog.i(TAG, "System now ready"); 9345 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9346 SystemClock.uptimeMillis()); 9347 9348 synchronized(this) { 9349 // Make sure we have no pre-ready processes sitting around. 9350 9351 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9352 ResolveInfo ri = mContext.getPackageManager() 9353 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9354 STOCK_PM_FLAGS); 9355 CharSequence errorMsg = null; 9356 if (ri != null) { 9357 ActivityInfo ai = ri.activityInfo; 9358 ApplicationInfo app = ai.applicationInfo; 9359 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9360 mTopAction = Intent.ACTION_FACTORY_TEST; 9361 mTopData = null; 9362 mTopComponent = new ComponentName(app.packageName, 9363 ai.name); 9364 } else { 9365 errorMsg = mContext.getResources().getText( 9366 com.android.internal.R.string.factorytest_not_system); 9367 } 9368 } else { 9369 errorMsg = mContext.getResources().getText( 9370 com.android.internal.R.string.factorytest_no_action); 9371 } 9372 if (errorMsg != null) { 9373 mTopAction = null; 9374 mTopData = null; 9375 mTopComponent = null; 9376 Message msg = Message.obtain(); 9377 msg.what = SHOW_FACTORY_ERROR_MSG; 9378 msg.getData().putCharSequence("msg", errorMsg); 9379 mHandler.sendMessage(msg); 9380 } 9381 } 9382 } 9383 9384 retrieveSettings(); 9385 9386 synchronized (this) { 9387 readGrantedUriPermissionsLocked(); 9388 } 9389 9390 if (goingCallback != null) goingCallback.run(); 9391 9392 synchronized (this) { 9393 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9394 try { 9395 List apps = AppGlobals.getPackageManager(). 9396 getPersistentApplications(STOCK_PM_FLAGS); 9397 if (apps != null) { 9398 int N = apps.size(); 9399 int i; 9400 for (i=0; i<N; i++) { 9401 ApplicationInfo info 9402 = (ApplicationInfo)apps.get(i); 9403 if (info != null && 9404 !info.packageName.equals("android")) { 9405 addAppLocked(info, false); 9406 } 9407 } 9408 } 9409 } catch (RemoteException ex) { 9410 // pm is in same process, this will never happen. 9411 } 9412 } 9413 9414 // Start up initial activity. 9415 mBooting = true; 9416 9417 try { 9418 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9419 Message msg = Message.obtain(); 9420 msg.what = SHOW_UID_ERROR_MSG; 9421 mHandler.sendMessage(msg); 9422 } 9423 } catch (RemoteException e) { 9424 } 9425 9426 long ident = Binder.clearCallingIdentity(); 9427 try { 9428 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9429 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9430 | Intent.FLAG_RECEIVER_FOREGROUND); 9431 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9432 broadcastIntentLocked(null, null, intent, 9433 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9434 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9435 intent = new Intent(Intent.ACTION_USER_STARTING); 9436 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9437 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9438 broadcastIntentLocked(null, null, intent, 9439 null, new IIntentReceiver.Stub() { 9440 @Override 9441 public void performReceive(Intent intent, int resultCode, String data, 9442 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9443 throws RemoteException { 9444 } 9445 }, 0, null, null, 9446 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9447 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9448 } finally { 9449 Binder.restoreCallingIdentity(ident); 9450 } 9451 mStackSupervisor.resumeTopActivitiesLocked(); 9452 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9453 } 9454 } 9455 9456 private boolean makeAppCrashingLocked(ProcessRecord app, 9457 String shortMsg, String longMsg, String stackTrace) { 9458 app.crashing = true; 9459 app.crashingReport = generateProcessError(app, 9460 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9461 startAppProblemLocked(app); 9462 app.stopFreezingAllLocked(); 9463 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9464 } 9465 9466 private void makeAppNotRespondingLocked(ProcessRecord app, 9467 String activity, String shortMsg, String longMsg) { 9468 app.notResponding = true; 9469 app.notRespondingReport = generateProcessError(app, 9470 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9471 activity, shortMsg, longMsg, null); 9472 startAppProblemLocked(app); 9473 app.stopFreezingAllLocked(); 9474 } 9475 9476 /** 9477 * Generate a process error record, suitable for attachment to a ProcessRecord. 9478 * 9479 * @param app The ProcessRecord in which the error occurred. 9480 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9481 * ActivityManager.AppErrorStateInfo 9482 * @param activity The activity associated with the crash, if known. 9483 * @param shortMsg Short message describing the crash. 9484 * @param longMsg Long message describing the crash. 9485 * @param stackTrace Full crash stack trace, may be null. 9486 * 9487 * @return Returns a fully-formed AppErrorStateInfo record. 9488 */ 9489 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9490 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9491 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9492 9493 report.condition = condition; 9494 report.processName = app.processName; 9495 report.pid = app.pid; 9496 report.uid = app.info.uid; 9497 report.tag = activity; 9498 report.shortMsg = shortMsg; 9499 report.longMsg = longMsg; 9500 report.stackTrace = stackTrace; 9501 9502 return report; 9503 } 9504 9505 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9506 synchronized (this) { 9507 app.crashing = false; 9508 app.crashingReport = null; 9509 app.notResponding = false; 9510 app.notRespondingReport = null; 9511 if (app.anrDialog == fromDialog) { 9512 app.anrDialog = null; 9513 } 9514 if (app.waitDialog == fromDialog) { 9515 app.waitDialog = null; 9516 } 9517 if (app.pid > 0 && app.pid != MY_PID) { 9518 handleAppCrashLocked(app, null, null, null); 9519 killUnneededProcessLocked(app, "user request after error"); 9520 } 9521 } 9522 } 9523 9524 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9525 String stackTrace) { 9526 long now = SystemClock.uptimeMillis(); 9527 9528 Long crashTime; 9529 if (!app.isolated) { 9530 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9531 } else { 9532 crashTime = null; 9533 } 9534 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9535 // This process loses! 9536 Slog.w(TAG, "Process " + app.info.processName 9537 + " has crashed too many times: killing!"); 9538 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9539 app.userId, app.info.processName, app.uid); 9540 mStackSupervisor.handleAppCrashLocked(app); 9541 if (!app.persistent) { 9542 // We don't want to start this process again until the user 9543 // explicitly does so... but for persistent process, we really 9544 // need to keep it running. If a persistent process is actually 9545 // repeatedly crashing, then badness for everyone. 9546 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9547 app.info.processName); 9548 if (!app.isolated) { 9549 // XXX We don't have a way to mark isolated processes 9550 // as bad, since they don't have a peristent identity. 9551 mBadProcesses.put(app.info.processName, app.uid, 9552 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9553 mProcessCrashTimes.remove(app.info.processName, app.uid); 9554 } 9555 app.bad = true; 9556 app.removed = true; 9557 // Don't let services in this process be restarted and potentially 9558 // annoy the user repeatedly. Unless it is persistent, since those 9559 // processes run critical code. 9560 removeProcessLocked(app, false, false, "crash"); 9561 mStackSupervisor.resumeTopActivitiesLocked(); 9562 return false; 9563 } 9564 mStackSupervisor.resumeTopActivitiesLocked(); 9565 } else { 9566 mStackSupervisor.finishTopRunningActivityLocked(app); 9567 } 9568 9569 // Bump up the crash count of any services currently running in the proc. 9570 for (int i=app.services.size()-1; i>=0; i--) { 9571 // Any services running in the application need to be placed 9572 // back in the pending list. 9573 ServiceRecord sr = app.services.valueAt(i); 9574 sr.crashCount++; 9575 } 9576 9577 // If the crashing process is what we consider to be the "home process" and it has been 9578 // replaced by a third-party app, clear the package preferred activities from packages 9579 // with a home activity running in the process to prevent a repeatedly crashing app 9580 // from blocking the user to manually clear the list. 9581 final ArrayList<ActivityRecord> activities = app.activities; 9582 if (app == mHomeProcess && activities.size() > 0 9583 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9584 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9585 final ActivityRecord r = activities.get(activityNdx); 9586 if (r.isHomeActivity()) { 9587 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9588 try { 9589 ActivityThread.getPackageManager() 9590 .clearPackagePreferredActivities(r.packageName); 9591 } catch (RemoteException c) { 9592 // pm is in same process, this will never happen. 9593 } 9594 } 9595 } 9596 } 9597 9598 if (!app.isolated) { 9599 // XXX Can't keep track of crash times for isolated processes, 9600 // because they don't have a perisistent identity. 9601 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9602 } 9603 9604 return true; 9605 } 9606 9607 void startAppProblemLocked(ProcessRecord app) { 9608 if (app.userId == mCurrentUserId) { 9609 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9610 mContext, app.info.packageName, app.info.flags); 9611 } else { 9612 // If this app is not running under the current user, then we 9613 // can't give it a report button because that would require 9614 // launching the report UI under a different user. 9615 app.errorReportReceiver = null; 9616 } 9617 skipCurrentReceiverLocked(app); 9618 } 9619 9620 void skipCurrentReceiverLocked(ProcessRecord app) { 9621 for (BroadcastQueue queue : mBroadcastQueues) { 9622 queue.skipCurrentReceiverLocked(app); 9623 } 9624 } 9625 9626 /** 9627 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9628 * The application process will exit immediately after this call returns. 9629 * @param app object of the crashing app, null for the system server 9630 * @param crashInfo describing the exception 9631 */ 9632 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9633 ProcessRecord r = findAppProcess(app, "Crash"); 9634 final String processName = app == null ? "system_server" 9635 : (r == null ? "unknown" : r.processName); 9636 9637 handleApplicationCrashInner("crash", r, processName, crashInfo); 9638 } 9639 9640 /* Native crash reporting uses this inner version because it needs to be somewhat 9641 * decoupled from the AM-managed cleanup lifecycle 9642 */ 9643 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9644 ApplicationErrorReport.CrashInfo crashInfo) { 9645 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9646 UserHandle.getUserId(Binder.getCallingUid()), processName, 9647 r == null ? -1 : r.info.flags, 9648 crashInfo.exceptionClassName, 9649 crashInfo.exceptionMessage, 9650 crashInfo.throwFileName, 9651 crashInfo.throwLineNumber); 9652 9653 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9654 9655 crashApplication(r, crashInfo); 9656 } 9657 9658 public void handleApplicationStrictModeViolation( 9659 IBinder app, 9660 int violationMask, 9661 StrictMode.ViolationInfo info) { 9662 ProcessRecord r = findAppProcess(app, "StrictMode"); 9663 if (r == null) { 9664 return; 9665 } 9666 9667 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9668 Integer stackFingerprint = info.hashCode(); 9669 boolean logIt = true; 9670 synchronized (mAlreadyLoggedViolatedStacks) { 9671 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9672 logIt = false; 9673 // TODO: sub-sample into EventLog for these, with 9674 // the info.durationMillis? Then we'd get 9675 // the relative pain numbers, without logging all 9676 // the stack traces repeatedly. We'd want to do 9677 // likewise in the client code, which also does 9678 // dup suppression, before the Binder call. 9679 } else { 9680 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9681 mAlreadyLoggedViolatedStacks.clear(); 9682 } 9683 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9684 } 9685 } 9686 if (logIt) { 9687 logStrictModeViolationToDropBox(r, info); 9688 } 9689 } 9690 9691 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9692 AppErrorResult result = new AppErrorResult(); 9693 synchronized (this) { 9694 final long origId = Binder.clearCallingIdentity(); 9695 9696 Message msg = Message.obtain(); 9697 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9698 HashMap<String, Object> data = new HashMap<String, Object>(); 9699 data.put("result", result); 9700 data.put("app", r); 9701 data.put("violationMask", violationMask); 9702 data.put("info", info); 9703 msg.obj = data; 9704 mHandler.sendMessage(msg); 9705 9706 Binder.restoreCallingIdentity(origId); 9707 } 9708 int res = result.get(); 9709 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9710 } 9711 } 9712 9713 // Depending on the policy in effect, there could be a bunch of 9714 // these in quick succession so we try to batch these together to 9715 // minimize disk writes, number of dropbox entries, and maximize 9716 // compression, by having more fewer, larger records. 9717 private void logStrictModeViolationToDropBox( 9718 ProcessRecord process, 9719 StrictMode.ViolationInfo info) { 9720 if (info == null) { 9721 return; 9722 } 9723 final boolean isSystemApp = process == null || 9724 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9725 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9726 final String processName = process == null ? "unknown" : process.processName; 9727 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9728 final DropBoxManager dbox = (DropBoxManager) 9729 mContext.getSystemService(Context.DROPBOX_SERVICE); 9730 9731 // Exit early if the dropbox isn't configured to accept this report type. 9732 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9733 9734 boolean bufferWasEmpty; 9735 boolean needsFlush; 9736 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9737 synchronized (sb) { 9738 bufferWasEmpty = sb.length() == 0; 9739 appendDropBoxProcessHeaders(process, processName, sb); 9740 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9741 sb.append("System-App: ").append(isSystemApp).append("\n"); 9742 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9743 if (info.violationNumThisLoop != 0) { 9744 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9745 } 9746 if (info.numAnimationsRunning != 0) { 9747 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9748 } 9749 if (info.broadcastIntentAction != null) { 9750 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9751 } 9752 if (info.durationMillis != -1) { 9753 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9754 } 9755 if (info.numInstances != -1) { 9756 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9757 } 9758 if (info.tags != null) { 9759 for (String tag : info.tags) { 9760 sb.append("Span-Tag: ").append(tag).append("\n"); 9761 } 9762 } 9763 sb.append("\n"); 9764 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9765 sb.append(info.crashInfo.stackTrace); 9766 } 9767 sb.append("\n"); 9768 9769 // Only buffer up to ~64k. Various logging bits truncate 9770 // things at 128k. 9771 needsFlush = (sb.length() > 64 * 1024); 9772 } 9773 9774 // Flush immediately if the buffer's grown too large, or this 9775 // is a non-system app. Non-system apps are isolated with a 9776 // different tag & policy and not batched. 9777 // 9778 // Batching is useful during internal testing with 9779 // StrictMode settings turned up high. Without batching, 9780 // thousands of separate files could be created on boot. 9781 if (!isSystemApp || needsFlush) { 9782 new Thread("Error dump: " + dropboxTag) { 9783 @Override 9784 public void run() { 9785 String report; 9786 synchronized (sb) { 9787 report = sb.toString(); 9788 sb.delete(0, sb.length()); 9789 sb.trimToSize(); 9790 } 9791 if (report.length() != 0) { 9792 dbox.addText(dropboxTag, report); 9793 } 9794 } 9795 }.start(); 9796 return; 9797 } 9798 9799 // System app batching: 9800 if (!bufferWasEmpty) { 9801 // An existing dropbox-writing thread is outstanding, so 9802 // we don't need to start it up. The existing thread will 9803 // catch the buffer appends we just did. 9804 return; 9805 } 9806 9807 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9808 // (After this point, we shouldn't access AMS internal data structures.) 9809 new Thread("Error dump: " + dropboxTag) { 9810 @Override 9811 public void run() { 9812 // 5 second sleep to let stacks arrive and be batched together 9813 try { 9814 Thread.sleep(5000); // 5 seconds 9815 } catch (InterruptedException e) {} 9816 9817 String errorReport; 9818 synchronized (mStrictModeBuffer) { 9819 errorReport = mStrictModeBuffer.toString(); 9820 if (errorReport.length() == 0) { 9821 return; 9822 } 9823 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9824 mStrictModeBuffer.trimToSize(); 9825 } 9826 dbox.addText(dropboxTag, errorReport); 9827 } 9828 }.start(); 9829 } 9830 9831 /** 9832 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9833 * @param app object of the crashing app, null for the system server 9834 * @param tag reported by the caller 9835 * @param crashInfo describing the context of the error 9836 * @return true if the process should exit immediately (WTF is fatal) 9837 */ 9838 public boolean handleApplicationWtf(IBinder app, String tag, 9839 ApplicationErrorReport.CrashInfo crashInfo) { 9840 ProcessRecord r = findAppProcess(app, "WTF"); 9841 final String processName = app == null ? "system_server" 9842 : (r == null ? "unknown" : r.processName); 9843 9844 EventLog.writeEvent(EventLogTags.AM_WTF, 9845 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9846 processName, 9847 r == null ? -1 : r.info.flags, 9848 tag, crashInfo.exceptionMessage); 9849 9850 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9851 9852 if (r != null && r.pid != Process.myPid() && 9853 Settings.Global.getInt(mContext.getContentResolver(), 9854 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9855 crashApplication(r, crashInfo); 9856 return true; 9857 } else { 9858 return false; 9859 } 9860 } 9861 9862 /** 9863 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9864 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9865 */ 9866 private ProcessRecord findAppProcess(IBinder app, String reason) { 9867 if (app == null) { 9868 return null; 9869 } 9870 9871 synchronized (this) { 9872 final int NP = mProcessNames.getMap().size(); 9873 for (int ip=0; ip<NP; ip++) { 9874 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9875 final int NA = apps.size(); 9876 for (int ia=0; ia<NA; ia++) { 9877 ProcessRecord p = apps.valueAt(ia); 9878 if (p.thread != null && p.thread.asBinder() == app) { 9879 return p; 9880 } 9881 } 9882 } 9883 9884 Slog.w(TAG, "Can't find mystery application for " + reason 9885 + " from pid=" + Binder.getCallingPid() 9886 + " uid=" + Binder.getCallingUid() + ": " + app); 9887 return null; 9888 } 9889 } 9890 9891 /** 9892 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9893 * to append various headers to the dropbox log text. 9894 */ 9895 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9896 StringBuilder sb) { 9897 // Watchdog thread ends up invoking this function (with 9898 // a null ProcessRecord) to add the stack file to dropbox. 9899 // Do not acquire a lock on this (am) in such cases, as it 9900 // could cause a potential deadlock, if and when watchdog 9901 // is invoked due to unavailability of lock on am and it 9902 // would prevent watchdog from killing system_server. 9903 if (process == null) { 9904 sb.append("Process: ").append(processName).append("\n"); 9905 return; 9906 } 9907 // Note: ProcessRecord 'process' is guarded by the service 9908 // instance. (notably process.pkgList, which could otherwise change 9909 // concurrently during execution of this method) 9910 synchronized (this) { 9911 sb.append("Process: ").append(processName).append("\n"); 9912 int flags = process.info.flags; 9913 IPackageManager pm = AppGlobals.getPackageManager(); 9914 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 9915 for (int ip=0; ip<process.pkgList.size(); ip++) { 9916 String pkg = process.pkgList.keyAt(ip); 9917 sb.append("Package: ").append(pkg); 9918 try { 9919 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 9920 if (pi != null) { 9921 sb.append(" v").append(pi.versionCode); 9922 if (pi.versionName != null) { 9923 sb.append(" (").append(pi.versionName).append(")"); 9924 } 9925 } 9926 } catch (RemoteException e) { 9927 Slog.e(TAG, "Error getting package info: " + pkg, e); 9928 } 9929 sb.append("\n"); 9930 } 9931 } 9932 } 9933 9934 private static String processClass(ProcessRecord process) { 9935 if (process == null || process.pid == MY_PID) { 9936 return "system_server"; 9937 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9938 return "system_app"; 9939 } else { 9940 return "data_app"; 9941 } 9942 } 9943 9944 /** 9945 * Write a description of an error (crash, WTF, ANR) to the drop box. 9946 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 9947 * @param process which caused the error, null means the system server 9948 * @param activity which triggered the error, null if unknown 9949 * @param parent activity related to the error, null if unknown 9950 * @param subject line related to the error, null if absent 9951 * @param report in long form describing the error, null if absent 9952 * @param logFile to include in the report, null if none 9953 * @param crashInfo giving an application stack trace, null if absent 9954 */ 9955 public void addErrorToDropBox(String eventType, 9956 ProcessRecord process, String processName, ActivityRecord activity, 9957 ActivityRecord parent, String subject, 9958 final String report, final File logFile, 9959 final ApplicationErrorReport.CrashInfo crashInfo) { 9960 // NOTE -- this must never acquire the ActivityManagerService lock, 9961 // otherwise the watchdog may be prevented from resetting the system. 9962 9963 final String dropboxTag = processClass(process) + "_" + eventType; 9964 final DropBoxManager dbox = (DropBoxManager) 9965 mContext.getSystemService(Context.DROPBOX_SERVICE); 9966 9967 // Exit early if the dropbox isn't configured to accept this report type. 9968 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9969 9970 final StringBuilder sb = new StringBuilder(1024); 9971 appendDropBoxProcessHeaders(process, processName, sb); 9972 if (activity != null) { 9973 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 9974 } 9975 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 9976 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 9977 } 9978 if (parent != null && parent != activity) { 9979 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 9980 } 9981 if (subject != null) { 9982 sb.append("Subject: ").append(subject).append("\n"); 9983 } 9984 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9985 if (Debug.isDebuggerConnected()) { 9986 sb.append("Debugger: Connected\n"); 9987 } 9988 sb.append("\n"); 9989 9990 // Do the rest in a worker thread to avoid blocking the caller on I/O 9991 // (After this point, we shouldn't access AMS internal data structures.) 9992 Thread worker = new Thread("Error dump: " + dropboxTag) { 9993 @Override 9994 public void run() { 9995 if (report != null) { 9996 sb.append(report); 9997 } 9998 if (logFile != null) { 9999 try { 10000 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10001 "\n\n[[TRUNCATED]]")); 10002 } catch (IOException e) { 10003 Slog.e(TAG, "Error reading " + logFile, e); 10004 } 10005 } 10006 if (crashInfo != null && crashInfo.stackTrace != null) { 10007 sb.append(crashInfo.stackTrace); 10008 } 10009 10010 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10011 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10012 if (lines > 0) { 10013 sb.append("\n"); 10014 10015 // Merge several logcat streams, and take the last N lines 10016 InputStreamReader input = null; 10017 try { 10018 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10019 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10020 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10021 10022 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10023 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10024 input = new InputStreamReader(logcat.getInputStream()); 10025 10026 int num; 10027 char[] buf = new char[8192]; 10028 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10029 } catch (IOException e) { 10030 Slog.e(TAG, "Error running logcat", e); 10031 } finally { 10032 if (input != null) try { input.close(); } catch (IOException e) {} 10033 } 10034 } 10035 10036 dbox.addText(dropboxTag, sb.toString()); 10037 } 10038 }; 10039 10040 if (process == null) { 10041 // If process is null, we are being called from some internal code 10042 // and may be about to die -- run this synchronously. 10043 worker.run(); 10044 } else { 10045 worker.start(); 10046 } 10047 } 10048 10049 /** 10050 * Bring up the "unexpected error" dialog box for a crashing app. 10051 * Deal with edge cases (intercepts from instrumented applications, 10052 * ActivityController, error intent receivers, that sort of thing). 10053 * @param r the application crashing 10054 * @param crashInfo describing the failure 10055 */ 10056 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10057 long timeMillis = System.currentTimeMillis(); 10058 String shortMsg = crashInfo.exceptionClassName; 10059 String longMsg = crashInfo.exceptionMessage; 10060 String stackTrace = crashInfo.stackTrace; 10061 if (shortMsg != null && longMsg != null) { 10062 longMsg = shortMsg + ": " + longMsg; 10063 } else if (shortMsg != null) { 10064 longMsg = shortMsg; 10065 } 10066 10067 AppErrorResult result = new AppErrorResult(); 10068 synchronized (this) { 10069 if (mController != null) { 10070 try { 10071 String name = r != null ? r.processName : null; 10072 int pid = r != null ? r.pid : Binder.getCallingPid(); 10073 if (!mController.appCrashed(name, pid, 10074 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10075 Slog.w(TAG, "Force-killing crashed app " + name 10076 + " at watcher's request"); 10077 Process.killProcess(pid); 10078 return; 10079 } 10080 } catch (RemoteException e) { 10081 mController = null; 10082 Watchdog.getInstance().setActivityController(null); 10083 } 10084 } 10085 10086 final long origId = Binder.clearCallingIdentity(); 10087 10088 // If this process is running instrumentation, finish it. 10089 if (r != null && r.instrumentationClass != null) { 10090 Slog.w(TAG, "Error in app " + r.processName 10091 + " running instrumentation " + r.instrumentationClass + ":"); 10092 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10093 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10094 Bundle info = new Bundle(); 10095 info.putString("shortMsg", shortMsg); 10096 info.putString("longMsg", longMsg); 10097 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10098 Binder.restoreCallingIdentity(origId); 10099 return; 10100 } 10101 10102 // If we can't identify the process or it's already exceeded its crash quota, 10103 // quit right away without showing a crash dialog. 10104 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10105 Binder.restoreCallingIdentity(origId); 10106 return; 10107 } 10108 10109 Message msg = Message.obtain(); 10110 msg.what = SHOW_ERROR_MSG; 10111 HashMap data = new HashMap(); 10112 data.put("result", result); 10113 data.put("app", r); 10114 msg.obj = data; 10115 mHandler.sendMessage(msg); 10116 10117 Binder.restoreCallingIdentity(origId); 10118 } 10119 10120 int res = result.get(); 10121 10122 Intent appErrorIntent = null; 10123 synchronized (this) { 10124 if (r != null && !r.isolated) { 10125 // XXX Can't keep track of crash time for isolated processes, 10126 // since they don't have a persistent identity. 10127 mProcessCrashTimes.put(r.info.processName, r.uid, 10128 SystemClock.uptimeMillis()); 10129 } 10130 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10131 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10132 } 10133 } 10134 10135 if (appErrorIntent != null) { 10136 try { 10137 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10138 } catch (ActivityNotFoundException e) { 10139 Slog.w(TAG, "bug report receiver dissappeared", e); 10140 } 10141 } 10142 } 10143 10144 Intent createAppErrorIntentLocked(ProcessRecord r, 10145 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10146 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10147 if (report == null) { 10148 return null; 10149 } 10150 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10151 result.setComponent(r.errorReportReceiver); 10152 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10153 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10154 return result; 10155 } 10156 10157 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10158 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10159 if (r.errorReportReceiver == null) { 10160 return null; 10161 } 10162 10163 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10164 return null; 10165 } 10166 10167 ApplicationErrorReport report = new ApplicationErrorReport(); 10168 report.packageName = r.info.packageName; 10169 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10170 report.processName = r.processName; 10171 report.time = timeMillis; 10172 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10173 10174 if (r.crashing || r.forceCrashReport) { 10175 report.type = ApplicationErrorReport.TYPE_CRASH; 10176 report.crashInfo = crashInfo; 10177 } else if (r.notResponding) { 10178 report.type = ApplicationErrorReport.TYPE_ANR; 10179 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10180 10181 report.anrInfo.activity = r.notRespondingReport.tag; 10182 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10183 report.anrInfo.info = r.notRespondingReport.longMsg; 10184 } 10185 10186 return report; 10187 } 10188 10189 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10190 enforceNotIsolatedCaller("getProcessesInErrorState"); 10191 // assume our apps are happy - lazy create the list 10192 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10193 10194 final boolean allUsers = ActivityManager.checkUidPermission( 10195 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10196 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10197 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10198 10199 synchronized (this) { 10200 10201 // iterate across all processes 10202 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10203 ProcessRecord app = mLruProcesses.get(i); 10204 if (!allUsers && app.userId != userId) { 10205 continue; 10206 } 10207 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10208 // This one's in trouble, so we'll generate a report for it 10209 // crashes are higher priority (in case there's a crash *and* an anr) 10210 ActivityManager.ProcessErrorStateInfo report = null; 10211 if (app.crashing) { 10212 report = app.crashingReport; 10213 } else if (app.notResponding) { 10214 report = app.notRespondingReport; 10215 } 10216 10217 if (report != null) { 10218 if (errList == null) { 10219 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10220 } 10221 errList.add(report); 10222 } else { 10223 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10224 " crashing = " + app.crashing + 10225 " notResponding = " + app.notResponding); 10226 } 10227 } 10228 } 10229 } 10230 10231 return errList; 10232 } 10233 10234 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10235 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10236 if (currApp != null) { 10237 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10238 } 10239 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10240 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10241 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10242 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10243 if (currApp != null) { 10244 currApp.lru = 0; 10245 } 10246 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10247 } else if (adj >= ProcessList.SERVICE_ADJ) { 10248 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10249 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10250 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10251 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10252 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10253 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10254 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10255 } else { 10256 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10257 } 10258 } 10259 10260 private void fillInProcMemInfo(ProcessRecord app, 10261 ActivityManager.RunningAppProcessInfo outInfo) { 10262 outInfo.pid = app.pid; 10263 outInfo.uid = app.info.uid; 10264 if (mHeavyWeightProcess == app) { 10265 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10266 } 10267 if (app.persistent) { 10268 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10269 } 10270 if (app.activities.size() > 0) { 10271 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10272 } 10273 outInfo.lastTrimLevel = app.trimMemoryLevel; 10274 int adj = app.curAdj; 10275 outInfo.importance = oomAdjToImportance(adj, outInfo); 10276 outInfo.importanceReasonCode = app.adjTypeCode; 10277 } 10278 10279 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10280 enforceNotIsolatedCaller("getRunningAppProcesses"); 10281 // Lazy instantiation of list 10282 List<ActivityManager.RunningAppProcessInfo> runList = null; 10283 final boolean allUsers = ActivityManager.checkUidPermission( 10284 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10285 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10286 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10287 synchronized (this) { 10288 // Iterate across all processes 10289 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10290 ProcessRecord app = mLruProcesses.get(i); 10291 if (!allUsers && app.userId != userId) { 10292 continue; 10293 } 10294 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10295 // Generate process state info for running application 10296 ActivityManager.RunningAppProcessInfo currApp = 10297 new ActivityManager.RunningAppProcessInfo(app.processName, 10298 app.pid, app.getPackageList()); 10299 fillInProcMemInfo(app, currApp); 10300 if (app.adjSource instanceof ProcessRecord) { 10301 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10302 currApp.importanceReasonImportance = oomAdjToImportance( 10303 app.adjSourceOom, null); 10304 } else if (app.adjSource instanceof ActivityRecord) { 10305 ActivityRecord r = (ActivityRecord)app.adjSource; 10306 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10307 } 10308 if (app.adjTarget instanceof ComponentName) { 10309 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10310 } 10311 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10312 // + " lru=" + currApp.lru); 10313 if (runList == null) { 10314 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10315 } 10316 runList.add(currApp); 10317 } 10318 } 10319 } 10320 return runList; 10321 } 10322 10323 public List<ApplicationInfo> getRunningExternalApplications() { 10324 enforceNotIsolatedCaller("getRunningExternalApplications"); 10325 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10326 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10327 if (runningApps != null && runningApps.size() > 0) { 10328 Set<String> extList = new HashSet<String>(); 10329 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10330 if (app.pkgList != null) { 10331 for (String pkg : app.pkgList) { 10332 extList.add(pkg); 10333 } 10334 } 10335 } 10336 IPackageManager pm = AppGlobals.getPackageManager(); 10337 for (String pkg : extList) { 10338 try { 10339 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10340 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10341 retList.add(info); 10342 } 10343 } catch (RemoteException e) { 10344 } 10345 } 10346 } 10347 return retList; 10348 } 10349 10350 @Override 10351 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10352 enforceNotIsolatedCaller("getMyMemoryState"); 10353 synchronized (this) { 10354 ProcessRecord proc; 10355 synchronized (mPidsSelfLocked) { 10356 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10357 } 10358 fillInProcMemInfo(proc, outInfo); 10359 } 10360 } 10361 10362 @Override 10363 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10364 if (checkCallingPermission(android.Manifest.permission.DUMP) 10365 != PackageManager.PERMISSION_GRANTED) { 10366 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10367 + Binder.getCallingPid() 10368 + ", uid=" + Binder.getCallingUid() 10369 + " without permission " 10370 + android.Manifest.permission.DUMP); 10371 return; 10372 } 10373 10374 boolean dumpAll = false; 10375 boolean dumpClient = false; 10376 String dumpPackage = null; 10377 10378 int opti = 0; 10379 while (opti < args.length) { 10380 String opt = args[opti]; 10381 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10382 break; 10383 } 10384 opti++; 10385 if ("-a".equals(opt)) { 10386 dumpAll = true; 10387 } else if ("-c".equals(opt)) { 10388 dumpClient = true; 10389 } else if ("-h".equals(opt)) { 10390 pw.println("Activity manager dump options:"); 10391 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10392 pw.println(" cmd may be one of:"); 10393 pw.println(" a[ctivities]: activity stack state"); 10394 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10395 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10396 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10397 pw.println(" o[om]: out of memory management"); 10398 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10399 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10400 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10401 pw.println(" service [COMP_SPEC]: service client-side state"); 10402 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10403 pw.println(" all: dump all activities"); 10404 pw.println(" top: dump the top activity"); 10405 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10406 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10407 pw.println(" a partial substring in a component name, a"); 10408 pw.println(" hex object identifier."); 10409 pw.println(" -a: include all available server state."); 10410 pw.println(" -c: include client state."); 10411 return; 10412 } else { 10413 pw.println("Unknown argument: " + opt + "; use -h for help"); 10414 } 10415 } 10416 10417 long origId = Binder.clearCallingIdentity(); 10418 boolean more = false; 10419 // Is the caller requesting to dump a particular piece of data? 10420 if (opti < args.length) { 10421 String cmd = args[opti]; 10422 opti++; 10423 if ("activities".equals(cmd) || "a".equals(cmd)) { 10424 synchronized (this) { 10425 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10426 } 10427 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10428 String[] newArgs; 10429 String name; 10430 if (opti >= args.length) { 10431 name = null; 10432 newArgs = EMPTY_STRING_ARRAY; 10433 } else { 10434 name = args[opti]; 10435 opti++; 10436 newArgs = new String[args.length - opti]; 10437 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10438 args.length - opti); 10439 } 10440 synchronized (this) { 10441 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10442 } 10443 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10444 String[] newArgs; 10445 String name; 10446 if (opti >= args.length) { 10447 name = null; 10448 newArgs = EMPTY_STRING_ARRAY; 10449 } else { 10450 name = args[opti]; 10451 opti++; 10452 newArgs = new String[args.length - opti]; 10453 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10454 args.length - opti); 10455 } 10456 synchronized (this) { 10457 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10458 } 10459 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10460 String[] newArgs; 10461 String name; 10462 if (opti >= args.length) { 10463 name = null; 10464 newArgs = EMPTY_STRING_ARRAY; 10465 } else { 10466 name = args[opti]; 10467 opti++; 10468 newArgs = new String[args.length - opti]; 10469 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10470 args.length - opti); 10471 } 10472 synchronized (this) { 10473 dumpProcessesLocked(fd, pw, args, opti, true, name); 10474 } 10475 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10476 synchronized (this) { 10477 dumpOomLocked(fd, pw, args, opti, true); 10478 } 10479 } else if ("provider".equals(cmd)) { 10480 String[] newArgs; 10481 String name; 10482 if (opti >= args.length) { 10483 name = null; 10484 newArgs = EMPTY_STRING_ARRAY; 10485 } else { 10486 name = args[opti]; 10487 opti++; 10488 newArgs = new String[args.length - opti]; 10489 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10490 } 10491 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10492 pw.println("No providers match: " + name); 10493 pw.println("Use -h for help."); 10494 } 10495 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10496 synchronized (this) { 10497 dumpProvidersLocked(fd, pw, args, opti, true, null); 10498 } 10499 } else if ("service".equals(cmd)) { 10500 String[] newArgs; 10501 String name; 10502 if (opti >= args.length) { 10503 name = null; 10504 newArgs = EMPTY_STRING_ARRAY; 10505 } else { 10506 name = args[opti]; 10507 opti++; 10508 newArgs = new String[args.length - opti]; 10509 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10510 args.length - opti); 10511 } 10512 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10513 pw.println("No services match: " + name); 10514 pw.println("Use -h for help."); 10515 } 10516 } else if ("package".equals(cmd)) { 10517 String[] newArgs; 10518 if (opti >= args.length) { 10519 pw.println("package: no package name specified"); 10520 pw.println("Use -h for help."); 10521 } else { 10522 dumpPackage = args[opti]; 10523 opti++; 10524 newArgs = new String[args.length - opti]; 10525 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10526 args.length - opti); 10527 args = newArgs; 10528 opti = 0; 10529 more = true; 10530 } 10531 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10532 synchronized (this) { 10533 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10534 } 10535 } else { 10536 // Dumping a single activity? 10537 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10538 pw.println("Bad activity command, or no activities match: " + cmd); 10539 pw.println("Use -h for help."); 10540 } 10541 } 10542 if (!more) { 10543 Binder.restoreCallingIdentity(origId); 10544 return; 10545 } 10546 } 10547 10548 // No piece of data specified, dump everything. 10549 synchronized (this) { 10550 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10551 pw.println(); 10552 if (dumpAll) { 10553 pw.println("-------------------------------------------------------------------------------"); 10554 } 10555 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10556 pw.println(); 10557 if (dumpAll) { 10558 pw.println("-------------------------------------------------------------------------------"); 10559 } 10560 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10561 pw.println(); 10562 if (dumpAll) { 10563 pw.println("-------------------------------------------------------------------------------"); 10564 } 10565 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10566 pw.println(); 10567 if (dumpAll) { 10568 pw.println("-------------------------------------------------------------------------------"); 10569 } 10570 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10571 pw.println(); 10572 if (dumpAll) { 10573 pw.println("-------------------------------------------------------------------------------"); 10574 } 10575 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10576 } 10577 Binder.restoreCallingIdentity(origId); 10578 } 10579 10580 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10581 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10582 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10583 10584 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10585 dumpPackage); 10586 boolean needSep = printedAnything; 10587 10588 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10589 dumpPackage, needSep, " mFocusedActivity: "); 10590 if (printed) { 10591 printedAnything = true; 10592 needSep = false; 10593 } 10594 10595 if (dumpPackage == null) { 10596 if (needSep) { 10597 pw.println(); 10598 } 10599 needSep = true; 10600 printedAnything = true; 10601 mStackSupervisor.dump(pw, " "); 10602 } 10603 10604 if (mRecentTasks.size() > 0) { 10605 boolean printedHeader = false; 10606 10607 final int N = mRecentTasks.size(); 10608 for (int i=0; i<N; i++) { 10609 TaskRecord tr = mRecentTasks.get(i); 10610 if (dumpPackage != null) { 10611 if (tr.realActivity == null || 10612 !dumpPackage.equals(tr.realActivity)) { 10613 continue; 10614 } 10615 } 10616 if (!printedHeader) { 10617 if (needSep) { 10618 pw.println(); 10619 } 10620 pw.println(" Recent tasks:"); 10621 printedHeader = true; 10622 printedAnything = true; 10623 } 10624 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10625 pw.println(tr); 10626 if (dumpAll) { 10627 mRecentTasks.get(i).dump(pw, " "); 10628 } 10629 } 10630 } 10631 10632 if (!printedAnything) { 10633 pw.println(" (nothing)"); 10634 } 10635 } 10636 10637 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10638 int opti, boolean dumpAll, String dumpPackage) { 10639 boolean needSep = false; 10640 boolean printedAnything = false; 10641 int numPers = 0; 10642 10643 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10644 10645 if (dumpAll) { 10646 final int NP = mProcessNames.getMap().size(); 10647 for (int ip=0; ip<NP; ip++) { 10648 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10649 final int NA = procs.size(); 10650 for (int ia=0; ia<NA; ia++) { 10651 ProcessRecord r = procs.valueAt(ia); 10652 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10653 continue; 10654 } 10655 if (!needSep) { 10656 pw.println(" All known processes:"); 10657 needSep = true; 10658 printedAnything = true; 10659 } 10660 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10661 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10662 pw.print(" "); pw.println(r); 10663 r.dump(pw, " "); 10664 if (r.persistent) { 10665 numPers++; 10666 } 10667 } 10668 } 10669 } 10670 10671 if (mIsolatedProcesses.size() > 0) { 10672 boolean printed = false; 10673 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10674 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10675 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10676 continue; 10677 } 10678 if (!printed) { 10679 if (needSep) { 10680 pw.println(); 10681 } 10682 pw.println(" Isolated process list (sorted by uid):"); 10683 printedAnything = true; 10684 printed = true; 10685 needSep = true; 10686 } 10687 pw.println(String.format("%sIsolated #%2d: %s", 10688 " ", i, r.toString())); 10689 } 10690 } 10691 10692 if (mLruProcesses.size() > 0) { 10693 if (needSep) { 10694 pw.println(); 10695 } 10696 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10697 pw.print(" total, non-act at "); 10698 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10699 pw.print(", non-svc at "); 10700 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10701 pw.println("):"); 10702 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10703 needSep = true; 10704 printedAnything = true; 10705 } 10706 10707 if (dumpAll || dumpPackage != null) { 10708 synchronized (mPidsSelfLocked) { 10709 boolean printed = false; 10710 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10711 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10712 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10713 continue; 10714 } 10715 if (!printed) { 10716 if (needSep) pw.println(); 10717 needSep = true; 10718 pw.println(" PID mappings:"); 10719 printed = true; 10720 printedAnything = true; 10721 } 10722 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10723 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10724 } 10725 } 10726 } 10727 10728 if (mForegroundProcesses.size() > 0) { 10729 synchronized (mPidsSelfLocked) { 10730 boolean printed = false; 10731 for (int i=0; i<mForegroundProcesses.size(); i++) { 10732 ProcessRecord r = mPidsSelfLocked.get( 10733 mForegroundProcesses.valueAt(i).pid); 10734 if (dumpPackage != null && (r == null 10735 || !r.pkgList.containsKey(dumpPackage))) { 10736 continue; 10737 } 10738 if (!printed) { 10739 if (needSep) pw.println(); 10740 needSep = true; 10741 pw.println(" Foreground Processes:"); 10742 printed = true; 10743 printedAnything = true; 10744 } 10745 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10746 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10747 } 10748 } 10749 } 10750 10751 if (mPersistentStartingProcesses.size() > 0) { 10752 if (needSep) pw.println(); 10753 needSep = true; 10754 printedAnything = true; 10755 pw.println(" Persisent processes that are starting:"); 10756 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10757 "Starting Norm", "Restarting PERS", dumpPackage); 10758 } 10759 10760 if (mRemovedProcesses.size() > 0) { 10761 if (needSep) pw.println(); 10762 needSep = true; 10763 printedAnything = true; 10764 pw.println(" Processes that are being removed:"); 10765 dumpProcessList(pw, this, mRemovedProcesses, " ", 10766 "Removed Norm", "Removed PERS", dumpPackage); 10767 } 10768 10769 if (mProcessesOnHold.size() > 0) { 10770 if (needSep) pw.println(); 10771 needSep = true; 10772 printedAnything = true; 10773 pw.println(" Processes that are on old until the system is ready:"); 10774 dumpProcessList(pw, this, mProcessesOnHold, " ", 10775 "OnHold Norm", "OnHold PERS", dumpPackage); 10776 } 10777 10778 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10779 10780 if (mProcessCrashTimes.getMap().size() > 0) { 10781 boolean printed = false; 10782 long now = SystemClock.uptimeMillis(); 10783 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10784 final int NP = pmap.size(); 10785 for (int ip=0; ip<NP; ip++) { 10786 String pname = pmap.keyAt(ip); 10787 SparseArray<Long> uids = pmap.valueAt(ip); 10788 final int N = uids.size(); 10789 for (int i=0; i<N; i++) { 10790 int puid = uids.keyAt(i); 10791 ProcessRecord r = mProcessNames.get(pname, puid); 10792 if (dumpPackage != null && (r == null 10793 || !r.pkgList.containsKey(dumpPackage))) { 10794 continue; 10795 } 10796 if (!printed) { 10797 if (needSep) pw.println(); 10798 needSep = true; 10799 pw.println(" Time since processes crashed:"); 10800 printed = true; 10801 printedAnything = true; 10802 } 10803 pw.print(" Process "); pw.print(pname); 10804 pw.print(" uid "); pw.print(puid); 10805 pw.print(": last crashed "); 10806 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10807 pw.println(" ago"); 10808 } 10809 } 10810 } 10811 10812 if (mBadProcesses.getMap().size() > 0) { 10813 boolean printed = false; 10814 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10815 final int NP = pmap.size(); 10816 for (int ip=0; ip<NP; ip++) { 10817 String pname = pmap.keyAt(ip); 10818 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10819 final int N = uids.size(); 10820 for (int i=0; i<N; i++) { 10821 int puid = uids.keyAt(i); 10822 ProcessRecord r = mProcessNames.get(pname, puid); 10823 if (dumpPackage != null && (r == null 10824 || !r.pkgList.containsKey(dumpPackage))) { 10825 continue; 10826 } 10827 if (!printed) { 10828 if (needSep) pw.println(); 10829 needSep = true; 10830 pw.println(" Bad processes:"); 10831 printedAnything = true; 10832 } 10833 BadProcessInfo info = uids.valueAt(i); 10834 pw.print(" Bad process "); pw.print(pname); 10835 pw.print(" uid "); pw.print(puid); 10836 pw.print(": crashed at time "); pw.println(info.time); 10837 if (info.shortMsg != null) { 10838 pw.print(" Short msg: "); pw.println(info.shortMsg); 10839 } 10840 if (info.longMsg != null) { 10841 pw.print(" Long msg: "); pw.println(info.longMsg); 10842 } 10843 if (info.stack != null) { 10844 pw.println(" Stack:"); 10845 int lastPos = 0; 10846 for (int pos=0; pos<info.stack.length(); pos++) { 10847 if (info.stack.charAt(pos) == '\n') { 10848 pw.print(" "); 10849 pw.write(info.stack, lastPos, pos-lastPos); 10850 pw.println(); 10851 lastPos = pos+1; 10852 } 10853 } 10854 if (lastPos < info.stack.length()) { 10855 pw.print(" "); 10856 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10857 pw.println(); 10858 } 10859 } 10860 } 10861 } 10862 } 10863 10864 if (dumpPackage == null) { 10865 pw.println(); 10866 needSep = false; 10867 pw.println(" mStartedUsers:"); 10868 for (int i=0; i<mStartedUsers.size(); i++) { 10869 UserStartedState uss = mStartedUsers.valueAt(i); 10870 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10871 pw.print(": "); uss.dump("", pw); 10872 } 10873 pw.print(" mStartedUserArray: ["); 10874 for (int i=0; i<mStartedUserArray.length; i++) { 10875 if (i > 0) pw.print(", "); 10876 pw.print(mStartedUserArray[i]); 10877 } 10878 pw.println("]"); 10879 pw.print(" mUserLru: ["); 10880 for (int i=0; i<mUserLru.size(); i++) { 10881 if (i > 0) pw.print(", "); 10882 pw.print(mUserLru.get(i)); 10883 } 10884 pw.println("]"); 10885 if (dumpAll) { 10886 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10887 } 10888 } 10889 if (mHomeProcess != null && (dumpPackage == null 10890 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10891 if (needSep) { 10892 pw.println(); 10893 needSep = false; 10894 } 10895 pw.println(" mHomeProcess: " + mHomeProcess); 10896 } 10897 if (mPreviousProcess != null && (dumpPackage == null 10898 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 10899 if (needSep) { 10900 pw.println(); 10901 needSep = false; 10902 } 10903 pw.println(" mPreviousProcess: " + mPreviousProcess); 10904 } 10905 if (dumpAll) { 10906 StringBuilder sb = new StringBuilder(128); 10907 sb.append(" mPreviousProcessVisibleTime: "); 10908 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 10909 pw.println(sb); 10910 } 10911 if (mHeavyWeightProcess != null && (dumpPackage == null 10912 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 10913 if (needSep) { 10914 pw.println(); 10915 needSep = false; 10916 } 10917 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10918 } 10919 if (dumpPackage == null) { 10920 pw.println(" mConfiguration: " + mConfiguration); 10921 } 10922 if (dumpAll) { 10923 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 10924 if (mCompatModePackages.getPackages().size() > 0) { 10925 boolean printed = false; 10926 for (Map.Entry<String, Integer> entry 10927 : mCompatModePackages.getPackages().entrySet()) { 10928 String pkg = entry.getKey(); 10929 int mode = entry.getValue(); 10930 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 10931 continue; 10932 } 10933 if (!printed) { 10934 pw.println(" mScreenCompatPackages:"); 10935 printed = true; 10936 } 10937 pw.print(" "); pw.print(pkg); pw.print(": "); 10938 pw.print(mode); pw.println(); 10939 } 10940 } 10941 } 10942 if (dumpPackage == null) { 10943 if (mSleeping || mWentToSleep || mLockScreenShown) { 10944 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 10945 + " mLockScreenShown " + mLockScreenShown); 10946 } 10947 if (mShuttingDown) { 10948 pw.println(" mShuttingDown=" + mShuttingDown); 10949 } 10950 } 10951 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 10952 || mOrigWaitForDebugger) { 10953 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 10954 || dumpPackage.equals(mOrigDebugApp)) { 10955 if (needSep) { 10956 pw.println(); 10957 needSep = false; 10958 } 10959 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 10960 + " mDebugTransient=" + mDebugTransient 10961 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 10962 } 10963 } 10964 if (mOpenGlTraceApp != null) { 10965 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 10966 if (needSep) { 10967 pw.println(); 10968 needSep = false; 10969 } 10970 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 10971 } 10972 } 10973 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 10974 || mProfileFd != null) { 10975 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 10976 if (needSep) { 10977 pw.println(); 10978 needSep = false; 10979 } 10980 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 10981 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 10982 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 10983 + mAutoStopProfiler); 10984 } 10985 } 10986 if (dumpPackage == null) { 10987 if (mAlwaysFinishActivities || mController != null) { 10988 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 10989 + " mController=" + mController); 10990 } 10991 if (dumpAll) { 10992 pw.println(" Total persistent processes: " + numPers); 10993 pw.println(" mStartRunning=" + mStartRunning 10994 + " mProcessesReady=" + mProcessesReady 10995 + " mSystemReady=" + mSystemReady); 10996 pw.println(" mBooting=" + mBooting 10997 + " mBooted=" + mBooted 10998 + " mFactoryTest=" + mFactoryTest); 10999 pw.print(" mLastPowerCheckRealtime="); 11000 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11001 pw.println(""); 11002 pw.print(" mLastPowerCheckUptime="); 11003 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11004 pw.println(""); 11005 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11006 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11007 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11008 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11009 + " (" + mLruProcesses.size() + " total)" 11010 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11011 + " mNumServiceProcs=" + mNumServiceProcs 11012 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11013 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11014 + " mLastMemoryLevel" + mLastMemoryLevel 11015 + " mLastNumProcesses" + mLastNumProcesses); 11016 long now = SystemClock.uptimeMillis(); 11017 pw.print(" mLastIdleTime="); 11018 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11019 pw.print(" mLowRamSinceLastIdle="); 11020 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11021 pw.println(); 11022 } 11023 } 11024 11025 if (!printedAnything) { 11026 pw.println(" (nothing)"); 11027 } 11028 } 11029 11030 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11031 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11032 if (mProcessesToGc.size() > 0) { 11033 boolean printed = false; 11034 long now = SystemClock.uptimeMillis(); 11035 for (int i=0; i<mProcessesToGc.size(); i++) { 11036 ProcessRecord proc = mProcessesToGc.get(i); 11037 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11038 continue; 11039 } 11040 if (!printed) { 11041 if (needSep) pw.println(); 11042 needSep = true; 11043 pw.println(" Processes that are waiting to GC:"); 11044 printed = true; 11045 } 11046 pw.print(" Process "); pw.println(proc); 11047 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11048 pw.print(", last gced="); 11049 pw.print(now-proc.lastRequestedGc); 11050 pw.print(" ms ago, last lowMem="); 11051 pw.print(now-proc.lastLowMemory); 11052 pw.println(" ms ago"); 11053 11054 } 11055 } 11056 return needSep; 11057 } 11058 11059 void printOomLevel(PrintWriter pw, String name, int adj) { 11060 pw.print(" "); 11061 if (adj >= 0) { 11062 pw.print(' '); 11063 if (adj < 10) pw.print(' '); 11064 } else { 11065 if (adj > -10) pw.print(' '); 11066 } 11067 pw.print(adj); 11068 pw.print(": "); 11069 pw.print(name); 11070 pw.print(" ("); 11071 pw.print(mProcessList.getMemLevel(adj)/1024); 11072 pw.println(" kB)"); 11073 } 11074 11075 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11076 int opti, boolean dumpAll) { 11077 boolean needSep = false; 11078 11079 if (mLruProcesses.size() > 0) { 11080 if (needSep) pw.println(); 11081 needSep = true; 11082 pw.println(" OOM levels:"); 11083 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11084 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11085 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11086 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11087 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11088 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11089 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11090 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11091 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11092 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11093 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11094 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11095 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11096 11097 if (needSep) pw.println(); 11098 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11099 pw.print(" total, non-act at "); 11100 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11101 pw.print(", non-svc at "); 11102 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11103 pw.println("):"); 11104 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11105 needSep = true; 11106 } 11107 11108 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11109 11110 pw.println(); 11111 pw.println(" mHomeProcess: " + mHomeProcess); 11112 pw.println(" mPreviousProcess: " + mPreviousProcess); 11113 if (mHeavyWeightProcess != null) { 11114 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11115 } 11116 11117 return true; 11118 } 11119 11120 /** 11121 * There are three ways to call this: 11122 * - no provider specified: dump all the providers 11123 * - a flattened component name that matched an existing provider was specified as the 11124 * first arg: dump that one provider 11125 * - the first arg isn't the flattened component name of an existing provider: 11126 * dump all providers whose component contains the first arg as a substring 11127 */ 11128 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11129 int opti, boolean dumpAll) { 11130 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11131 } 11132 11133 static class ItemMatcher { 11134 ArrayList<ComponentName> components; 11135 ArrayList<String> strings; 11136 ArrayList<Integer> objects; 11137 boolean all; 11138 11139 ItemMatcher() { 11140 all = true; 11141 } 11142 11143 void build(String name) { 11144 ComponentName componentName = ComponentName.unflattenFromString(name); 11145 if (componentName != null) { 11146 if (components == null) { 11147 components = new ArrayList<ComponentName>(); 11148 } 11149 components.add(componentName); 11150 all = false; 11151 } else { 11152 int objectId = 0; 11153 // Not a '/' separated full component name; maybe an object ID? 11154 try { 11155 objectId = Integer.parseInt(name, 16); 11156 if (objects == null) { 11157 objects = new ArrayList<Integer>(); 11158 } 11159 objects.add(objectId); 11160 all = false; 11161 } catch (RuntimeException e) { 11162 // Not an integer; just do string match. 11163 if (strings == null) { 11164 strings = new ArrayList<String>(); 11165 } 11166 strings.add(name); 11167 all = false; 11168 } 11169 } 11170 } 11171 11172 int build(String[] args, int opti) { 11173 for (; opti<args.length; opti++) { 11174 String name = args[opti]; 11175 if ("--".equals(name)) { 11176 return opti+1; 11177 } 11178 build(name); 11179 } 11180 return opti; 11181 } 11182 11183 boolean match(Object object, ComponentName comp) { 11184 if (all) { 11185 return true; 11186 } 11187 if (components != null) { 11188 for (int i=0; i<components.size(); i++) { 11189 if (components.get(i).equals(comp)) { 11190 return true; 11191 } 11192 } 11193 } 11194 if (objects != null) { 11195 for (int i=0; i<objects.size(); i++) { 11196 if (System.identityHashCode(object) == objects.get(i)) { 11197 return true; 11198 } 11199 } 11200 } 11201 if (strings != null) { 11202 String flat = comp.flattenToString(); 11203 for (int i=0; i<strings.size(); i++) { 11204 if (flat.contains(strings.get(i))) { 11205 return true; 11206 } 11207 } 11208 } 11209 return false; 11210 } 11211 } 11212 11213 /** 11214 * There are three things that cmd can be: 11215 * - a flattened component name that matches an existing activity 11216 * - the cmd arg isn't the flattened component name of an existing activity: 11217 * dump all activity whose component contains the cmd as a substring 11218 * - A hex number of the ActivityRecord object instance. 11219 */ 11220 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11221 int opti, boolean dumpAll) { 11222 ArrayList<ActivityRecord> activities; 11223 11224 synchronized (this) { 11225 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11226 } 11227 11228 if (activities.size() <= 0) { 11229 return false; 11230 } 11231 11232 String[] newArgs = new String[args.length - opti]; 11233 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11234 11235 TaskRecord lastTask = null; 11236 boolean needSep = false; 11237 for (int i=activities.size()-1; i>=0; i--) { 11238 ActivityRecord r = activities.get(i); 11239 if (needSep) { 11240 pw.println(); 11241 } 11242 needSep = true; 11243 synchronized (this) { 11244 if (lastTask != r.task) { 11245 lastTask = r.task; 11246 pw.print("TASK "); pw.print(lastTask.affinity); 11247 pw.print(" id="); pw.println(lastTask.taskId); 11248 if (dumpAll) { 11249 lastTask.dump(pw, " "); 11250 } 11251 } 11252 } 11253 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11254 } 11255 return true; 11256 } 11257 11258 /** 11259 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11260 * there is a thread associated with the activity. 11261 */ 11262 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11263 final ActivityRecord r, String[] args, boolean dumpAll) { 11264 String innerPrefix = prefix + " "; 11265 synchronized (this) { 11266 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11267 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11268 pw.print(" pid="); 11269 if (r.app != null) pw.println(r.app.pid); 11270 else pw.println("(not running)"); 11271 if (dumpAll) { 11272 r.dump(pw, innerPrefix); 11273 } 11274 } 11275 if (r.app != null && r.app.thread != null) { 11276 // flush anything that is already in the PrintWriter since the thread is going 11277 // to write to the file descriptor directly 11278 pw.flush(); 11279 try { 11280 TransferPipe tp = new TransferPipe(); 11281 try { 11282 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11283 r.appToken, innerPrefix, args); 11284 tp.go(fd); 11285 } finally { 11286 tp.kill(); 11287 } 11288 } catch (IOException e) { 11289 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11290 } catch (RemoteException e) { 11291 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11292 } 11293 } 11294 } 11295 11296 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11297 int opti, boolean dumpAll, String dumpPackage) { 11298 boolean needSep = false; 11299 boolean onlyHistory = false; 11300 boolean printedAnything = false; 11301 11302 if ("history".equals(dumpPackage)) { 11303 if (opti < args.length && "-s".equals(args[opti])) { 11304 dumpAll = false; 11305 } 11306 onlyHistory = true; 11307 dumpPackage = null; 11308 } 11309 11310 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11311 if (!onlyHistory && dumpAll) { 11312 if (mRegisteredReceivers.size() > 0) { 11313 boolean printed = false; 11314 Iterator it = mRegisteredReceivers.values().iterator(); 11315 while (it.hasNext()) { 11316 ReceiverList r = (ReceiverList)it.next(); 11317 if (dumpPackage != null && (r.app == null || 11318 !dumpPackage.equals(r.app.info.packageName))) { 11319 continue; 11320 } 11321 if (!printed) { 11322 pw.println(" Registered Receivers:"); 11323 needSep = true; 11324 printed = true; 11325 printedAnything = true; 11326 } 11327 pw.print(" * "); pw.println(r); 11328 r.dump(pw, " "); 11329 } 11330 } 11331 11332 if (mReceiverResolver.dump(pw, needSep ? 11333 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11334 " ", dumpPackage, false)) { 11335 needSep = true; 11336 printedAnything = true; 11337 } 11338 } 11339 11340 for (BroadcastQueue q : mBroadcastQueues) { 11341 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11342 printedAnything |= needSep; 11343 } 11344 11345 needSep = true; 11346 11347 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11348 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11349 if (needSep) { 11350 pw.println(); 11351 } 11352 needSep = true; 11353 printedAnything = true; 11354 pw.print(" Sticky broadcasts for user "); 11355 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11356 StringBuilder sb = new StringBuilder(128); 11357 for (Map.Entry<String, ArrayList<Intent>> ent 11358 : mStickyBroadcasts.valueAt(user).entrySet()) { 11359 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11360 if (dumpAll) { 11361 pw.println(":"); 11362 ArrayList<Intent> intents = ent.getValue(); 11363 final int N = intents.size(); 11364 for (int i=0; i<N; i++) { 11365 sb.setLength(0); 11366 sb.append(" Intent: "); 11367 intents.get(i).toShortString(sb, false, true, false, false); 11368 pw.println(sb.toString()); 11369 Bundle bundle = intents.get(i).getExtras(); 11370 if (bundle != null) { 11371 pw.print(" "); 11372 pw.println(bundle.toString()); 11373 } 11374 } 11375 } else { 11376 pw.println(""); 11377 } 11378 } 11379 } 11380 } 11381 11382 if (!onlyHistory && dumpAll) { 11383 pw.println(); 11384 for (BroadcastQueue queue : mBroadcastQueues) { 11385 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11386 + queue.mBroadcastsScheduled); 11387 } 11388 pw.println(" mHandler:"); 11389 mHandler.dump(new PrintWriterPrinter(pw), " "); 11390 needSep = true; 11391 printedAnything = true; 11392 } 11393 11394 if (!printedAnything) { 11395 pw.println(" (nothing)"); 11396 } 11397 } 11398 11399 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11400 int opti, boolean dumpAll, String dumpPackage) { 11401 boolean needSep; 11402 boolean printedAnything = false; 11403 11404 ItemMatcher matcher = new ItemMatcher(); 11405 matcher.build(args, opti); 11406 11407 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11408 11409 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11410 printedAnything |= needSep; 11411 11412 if (mLaunchingProviders.size() > 0) { 11413 boolean printed = false; 11414 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11415 ContentProviderRecord r = mLaunchingProviders.get(i); 11416 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11417 continue; 11418 } 11419 if (!printed) { 11420 if (needSep) pw.println(); 11421 needSep = true; 11422 pw.println(" Launching content providers:"); 11423 printed = true; 11424 printedAnything = true; 11425 } 11426 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11427 pw.println(r); 11428 } 11429 } 11430 11431 if (mGrantedUriPermissions.size() > 0) { 11432 boolean printed = false; 11433 int dumpUid = -2; 11434 if (dumpPackage != null) { 11435 try { 11436 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11437 } catch (NameNotFoundException e) { 11438 dumpUid = -1; 11439 } 11440 } 11441 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11442 int uid = mGrantedUriPermissions.keyAt(i); 11443 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11444 continue; 11445 } 11446 ArrayMap<Uri, UriPermission> perms 11447 = mGrantedUriPermissions.valueAt(i); 11448 if (!printed) { 11449 if (needSep) pw.println(); 11450 needSep = true; 11451 pw.println(" Granted Uri Permissions:"); 11452 printed = true; 11453 printedAnything = true; 11454 } 11455 pw.print(" * UID "); pw.print(uid); 11456 pw.println(" holds:"); 11457 for (UriPermission perm : perms.values()) { 11458 pw.print(" "); pw.println(perm); 11459 if (dumpAll) { 11460 perm.dump(pw, " "); 11461 } 11462 } 11463 } 11464 } 11465 11466 if (!printedAnything) { 11467 pw.println(" (nothing)"); 11468 } 11469 } 11470 11471 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11472 int opti, boolean dumpAll, String dumpPackage) { 11473 boolean printed = false; 11474 11475 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11476 11477 if (mIntentSenderRecords.size() > 0) { 11478 Iterator<WeakReference<PendingIntentRecord>> it 11479 = mIntentSenderRecords.values().iterator(); 11480 while (it.hasNext()) { 11481 WeakReference<PendingIntentRecord> ref = it.next(); 11482 PendingIntentRecord rec = ref != null ? ref.get(): null; 11483 if (dumpPackage != null && (rec == null 11484 || !dumpPackage.equals(rec.key.packageName))) { 11485 continue; 11486 } 11487 printed = true; 11488 if (rec != null) { 11489 pw.print(" * "); pw.println(rec); 11490 if (dumpAll) { 11491 rec.dump(pw, " "); 11492 } 11493 } else { 11494 pw.print(" * "); pw.println(ref); 11495 } 11496 } 11497 } 11498 11499 if (!printed) { 11500 pw.println(" (nothing)"); 11501 } 11502 } 11503 11504 private static final int dumpProcessList(PrintWriter pw, 11505 ActivityManagerService service, List list, 11506 String prefix, String normalLabel, String persistentLabel, 11507 String dumpPackage) { 11508 int numPers = 0; 11509 final int N = list.size()-1; 11510 for (int i=N; i>=0; i--) { 11511 ProcessRecord r = (ProcessRecord)list.get(i); 11512 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11513 continue; 11514 } 11515 pw.println(String.format("%s%s #%2d: %s", 11516 prefix, (r.persistent ? persistentLabel : normalLabel), 11517 i, r.toString())); 11518 if (r.persistent) { 11519 numPers++; 11520 } 11521 } 11522 return numPers; 11523 } 11524 11525 private static final boolean dumpProcessOomList(PrintWriter pw, 11526 ActivityManagerService service, List<ProcessRecord> origList, 11527 String prefix, String normalLabel, String persistentLabel, 11528 boolean inclDetails, String dumpPackage) { 11529 11530 ArrayList<Pair<ProcessRecord, Integer>> list 11531 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11532 for (int i=0; i<origList.size(); i++) { 11533 ProcessRecord r = origList.get(i); 11534 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11535 continue; 11536 } 11537 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11538 } 11539 11540 if (list.size() <= 0) { 11541 return false; 11542 } 11543 11544 Comparator<Pair<ProcessRecord, Integer>> comparator 11545 = new Comparator<Pair<ProcessRecord, Integer>>() { 11546 @Override 11547 public int compare(Pair<ProcessRecord, Integer> object1, 11548 Pair<ProcessRecord, Integer> object2) { 11549 if (object1.first.setAdj != object2.first.setAdj) { 11550 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11551 } 11552 if (object1.second.intValue() != object2.second.intValue()) { 11553 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11554 } 11555 return 0; 11556 } 11557 }; 11558 11559 Collections.sort(list, comparator); 11560 11561 final long curRealtime = SystemClock.elapsedRealtime(); 11562 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11563 final long curUptime = SystemClock.uptimeMillis(); 11564 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11565 11566 for (int i=list.size()-1; i>=0; i--) { 11567 ProcessRecord r = list.get(i).first; 11568 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11569 char schedGroup; 11570 switch (r.setSchedGroup) { 11571 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11572 schedGroup = 'B'; 11573 break; 11574 case Process.THREAD_GROUP_DEFAULT: 11575 schedGroup = 'F'; 11576 break; 11577 default: 11578 schedGroup = '?'; 11579 break; 11580 } 11581 char foreground; 11582 if (r.foregroundActivities) { 11583 foreground = 'A'; 11584 } else if (r.foregroundServices) { 11585 foreground = 'S'; 11586 } else { 11587 foreground = ' '; 11588 } 11589 String procState = ProcessList.makeProcStateString(r.curProcState); 11590 pw.print(prefix); 11591 pw.print(r.persistent ? persistentLabel : normalLabel); 11592 pw.print(" #"); 11593 int num = (origList.size()-1)-list.get(i).second; 11594 if (num < 10) pw.print(' '); 11595 pw.print(num); 11596 pw.print(": "); 11597 pw.print(oomAdj); 11598 pw.print(' '); 11599 pw.print(schedGroup); 11600 pw.print('/'); 11601 pw.print(foreground); 11602 pw.print('/'); 11603 pw.print(procState); 11604 pw.print(" trm:"); 11605 if (r.trimMemoryLevel < 10) pw.print(' '); 11606 pw.print(r.trimMemoryLevel); 11607 pw.print(' '); 11608 pw.print(r.toShortString()); 11609 pw.print(" ("); 11610 pw.print(r.adjType); 11611 pw.println(')'); 11612 if (r.adjSource != null || r.adjTarget != null) { 11613 pw.print(prefix); 11614 pw.print(" "); 11615 if (r.adjTarget instanceof ComponentName) { 11616 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11617 } else if (r.adjTarget != null) { 11618 pw.print(r.adjTarget.toString()); 11619 } else { 11620 pw.print("{null}"); 11621 } 11622 pw.print("<="); 11623 if (r.adjSource instanceof ProcessRecord) { 11624 pw.print("Proc{"); 11625 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11626 pw.println("}"); 11627 } else if (r.adjSource != null) { 11628 pw.println(r.adjSource.toString()); 11629 } else { 11630 pw.println("{null}"); 11631 } 11632 } 11633 if (inclDetails) { 11634 pw.print(prefix); 11635 pw.print(" "); 11636 pw.print("oom: max="); pw.print(r.maxAdj); 11637 pw.print(" curRaw="); pw.print(r.curRawAdj); 11638 pw.print(" setRaw="); pw.print(r.setRawAdj); 11639 pw.print(" cur="); pw.print(r.curAdj); 11640 pw.print(" set="); pw.println(r.setAdj); 11641 pw.print(prefix); 11642 pw.print(" "); 11643 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11644 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11645 pw.print(" lastPss="); pw.print(r.lastPss); 11646 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11647 pw.print(prefix); 11648 pw.print(" "); 11649 pw.print("keeping="); pw.print(r.keeping); 11650 pw.print(" cached="); pw.print(r.cached); 11651 pw.print(" empty="); pw.print(r.empty); 11652 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11653 11654 if (!r.keeping) { 11655 if (r.lastWakeTime != 0) { 11656 long wtime; 11657 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11658 synchronized (stats) { 11659 wtime = stats.getProcessWakeTime(r.info.uid, 11660 r.pid, curRealtime); 11661 } 11662 long timeUsed = wtime - r.lastWakeTime; 11663 pw.print(prefix); 11664 pw.print(" "); 11665 pw.print("keep awake over "); 11666 TimeUtils.formatDuration(realtimeSince, pw); 11667 pw.print(" used "); 11668 TimeUtils.formatDuration(timeUsed, pw); 11669 pw.print(" ("); 11670 pw.print((timeUsed*100)/realtimeSince); 11671 pw.println("%)"); 11672 } 11673 if (r.lastCpuTime != 0) { 11674 long timeUsed = r.curCpuTime - r.lastCpuTime; 11675 pw.print(prefix); 11676 pw.print(" "); 11677 pw.print("run cpu over "); 11678 TimeUtils.formatDuration(uptimeSince, pw); 11679 pw.print(" used "); 11680 TimeUtils.formatDuration(timeUsed, pw); 11681 pw.print(" ("); 11682 pw.print((timeUsed*100)/uptimeSince); 11683 pw.println("%)"); 11684 } 11685 } 11686 } 11687 } 11688 return true; 11689 } 11690 11691 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11692 ArrayList<ProcessRecord> procs; 11693 synchronized (this) { 11694 if (args != null && args.length > start 11695 && args[start].charAt(0) != '-') { 11696 procs = new ArrayList<ProcessRecord>(); 11697 int pid = -1; 11698 try { 11699 pid = Integer.parseInt(args[start]); 11700 } catch (NumberFormatException e) { 11701 } 11702 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11703 ProcessRecord proc = mLruProcesses.get(i); 11704 if (proc.pid == pid) { 11705 procs.add(proc); 11706 } else if (proc.processName.equals(args[start])) { 11707 procs.add(proc); 11708 } 11709 } 11710 if (procs.size() <= 0) { 11711 return null; 11712 } 11713 } else { 11714 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11715 } 11716 } 11717 return procs; 11718 } 11719 11720 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11721 PrintWriter pw, String[] args) { 11722 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11723 if (procs == null) { 11724 pw.println("No process found for: " + args[0]); 11725 return; 11726 } 11727 11728 long uptime = SystemClock.uptimeMillis(); 11729 long realtime = SystemClock.elapsedRealtime(); 11730 pw.println("Applications Graphics Acceleration Info:"); 11731 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11732 11733 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11734 ProcessRecord r = procs.get(i); 11735 if (r.thread != null) { 11736 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11737 pw.flush(); 11738 try { 11739 TransferPipe tp = new TransferPipe(); 11740 try { 11741 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11742 tp.go(fd); 11743 } finally { 11744 tp.kill(); 11745 } 11746 } catch (IOException e) { 11747 pw.println("Failure while dumping the app: " + r); 11748 pw.flush(); 11749 } catch (RemoteException e) { 11750 pw.println("Got a RemoteException while dumping the app " + r); 11751 pw.flush(); 11752 } 11753 } 11754 } 11755 } 11756 11757 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11758 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11759 if (procs == null) { 11760 pw.println("No process found for: " + args[0]); 11761 return; 11762 } 11763 11764 pw.println("Applications Database Info:"); 11765 11766 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11767 ProcessRecord r = procs.get(i); 11768 if (r.thread != null) { 11769 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11770 pw.flush(); 11771 try { 11772 TransferPipe tp = new TransferPipe(); 11773 try { 11774 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11775 tp.go(fd); 11776 } finally { 11777 tp.kill(); 11778 } 11779 } catch (IOException e) { 11780 pw.println("Failure while dumping the app: " + r); 11781 pw.flush(); 11782 } catch (RemoteException e) { 11783 pw.println("Got a RemoteException while dumping the app " + r); 11784 pw.flush(); 11785 } 11786 } 11787 } 11788 } 11789 11790 final static class MemItem { 11791 final boolean isProc; 11792 final String label; 11793 final String shortLabel; 11794 final long pss; 11795 final int id; 11796 final boolean hasActivities; 11797 ArrayList<MemItem> subitems; 11798 11799 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11800 boolean _hasActivities) { 11801 isProc = true; 11802 label = _label; 11803 shortLabel = _shortLabel; 11804 pss = _pss; 11805 id = _id; 11806 hasActivities = _hasActivities; 11807 } 11808 11809 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11810 isProc = false; 11811 label = _label; 11812 shortLabel = _shortLabel; 11813 pss = _pss; 11814 id = _id; 11815 hasActivities = false; 11816 } 11817 } 11818 11819 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11820 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11821 if (sort && !isCompact) { 11822 Collections.sort(items, new Comparator<MemItem>() { 11823 @Override 11824 public int compare(MemItem lhs, MemItem rhs) { 11825 if (lhs.pss < rhs.pss) { 11826 return 1; 11827 } else if (lhs.pss > rhs.pss) { 11828 return -1; 11829 } 11830 return 0; 11831 } 11832 }); 11833 } 11834 11835 for (int i=0; i<items.size(); i++) { 11836 MemItem mi = items.get(i); 11837 if (!isCompact) { 11838 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11839 } else if (mi.isProc) { 11840 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11841 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11842 pw.println(mi.hasActivities ? ",a" : ",e"); 11843 } else { 11844 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11845 pw.println(mi.pss); 11846 } 11847 if (mi.subitems != null) { 11848 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11849 true, isCompact); 11850 } 11851 } 11852 } 11853 11854 // These are in KB. 11855 static final long[] DUMP_MEM_BUCKETS = new long[] { 11856 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11857 120*1024, 160*1024, 200*1024, 11858 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11859 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11860 }; 11861 11862 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11863 boolean stackLike) { 11864 int start = label.lastIndexOf('.'); 11865 if (start >= 0) start++; 11866 else start = 0; 11867 int end = label.length(); 11868 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11869 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11870 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11871 out.append(bucket); 11872 out.append(stackLike ? "MB." : "MB "); 11873 out.append(label, start, end); 11874 return; 11875 } 11876 } 11877 out.append(memKB/1024); 11878 out.append(stackLike ? "MB." : "MB "); 11879 out.append(label, start, end); 11880 } 11881 11882 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11883 ProcessList.NATIVE_ADJ, 11884 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11885 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11886 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11887 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11888 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11889 }; 11890 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11891 "Native", 11892 "System", "Persistent", "Foreground", 11893 "Visible", "Perceptible", 11894 "Heavy Weight", "Backup", 11895 "A Services", "Home", 11896 "Previous", "B Services", "Cached" 11897 }; 11898 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 11899 "native", 11900 "sys", "pers", "fore", 11901 "vis", "percept", 11902 "heavy", "backup", 11903 "servicea", "home", 11904 "prev", "serviceb", "cached" 11905 }; 11906 11907 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 11908 long realtime, boolean isCheckinRequest, boolean isCompact) { 11909 if (isCheckinRequest || isCompact) { 11910 // short checkin version 11911 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 11912 } else { 11913 pw.println("Applications Memory Usage (kB):"); 11914 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11915 } 11916 } 11917 11918 final void dumpApplicationMemoryUsage(FileDescriptor fd, 11919 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 11920 boolean dumpDetails = false; 11921 boolean dumpFullDetails = false; 11922 boolean dumpDalvik = false; 11923 boolean oomOnly = false; 11924 boolean isCompact = false; 11925 boolean localOnly = false; 11926 11927 int opti = 0; 11928 while (opti < args.length) { 11929 String opt = args[opti]; 11930 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11931 break; 11932 } 11933 opti++; 11934 if ("-a".equals(opt)) { 11935 dumpDetails = true; 11936 dumpFullDetails = true; 11937 dumpDalvik = true; 11938 } else if ("-d".equals(opt)) { 11939 dumpDalvik = true; 11940 } else if ("-c".equals(opt)) { 11941 isCompact = true; 11942 } else if ("--oom".equals(opt)) { 11943 oomOnly = true; 11944 } else if ("--local".equals(opt)) { 11945 localOnly = true; 11946 } else if ("-h".equals(opt)) { 11947 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 11948 pw.println(" -a: include all available information for each process."); 11949 pw.println(" -d: include dalvik details when dumping process details."); 11950 pw.println(" -c: dump in a compact machine-parseable representation."); 11951 pw.println(" --oom: only show processes organized by oom adj."); 11952 pw.println(" --local: only collect details locally, don't call process."); 11953 pw.println("If [process] is specified it can be the name or "); 11954 pw.println("pid of a specific process to dump."); 11955 return; 11956 } else { 11957 pw.println("Unknown argument: " + opt + "; use -h for help"); 11958 } 11959 } 11960 11961 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 11962 long uptime = SystemClock.uptimeMillis(); 11963 long realtime = SystemClock.elapsedRealtime(); 11964 final long[] tmpLong = new long[1]; 11965 11966 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 11967 if (procs == null) { 11968 // No Java processes. Maybe they want to print a native process. 11969 if (args != null && args.length > opti 11970 && args[opti].charAt(0) != '-') { 11971 ArrayList<ProcessCpuTracker.Stats> nativeProcs 11972 = new ArrayList<ProcessCpuTracker.Stats>(); 11973 updateCpuStatsNow(); 11974 int findPid = -1; 11975 try { 11976 findPid = Integer.parseInt(args[opti]); 11977 } catch (NumberFormatException e) { 11978 } 11979 synchronized (mProcessCpuThread) { 11980 final int N = mProcessCpuTracker.countStats(); 11981 for (int i=0; i<N; i++) { 11982 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 11983 if (st.pid == findPid || (st.baseName != null 11984 && st.baseName.equals(args[opti]))) { 11985 nativeProcs.add(st); 11986 } 11987 } 11988 } 11989 if (nativeProcs.size() > 0) { 11990 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 11991 isCompact); 11992 Debug.MemoryInfo mi = null; 11993 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 11994 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 11995 final int pid = r.pid; 11996 if (!isCheckinRequest && dumpDetails) { 11997 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 11998 } 11999 if (mi == null) { 12000 mi = new Debug.MemoryInfo(); 12001 } 12002 if (dumpDetails || (!brief && !oomOnly)) { 12003 Debug.getMemoryInfo(pid, mi); 12004 } else { 12005 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12006 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12007 } 12008 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12009 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12010 if (isCheckinRequest) { 12011 pw.println(); 12012 } 12013 } 12014 return; 12015 } 12016 } 12017 pw.println("No process found for: " + args[opti]); 12018 return; 12019 } 12020 12021 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12022 dumpDetails = true; 12023 } 12024 12025 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12026 12027 String[] innerArgs = new String[args.length-opti]; 12028 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12029 12030 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12031 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12032 long nativePss=0, dalvikPss=0, otherPss=0; 12033 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12034 12035 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12036 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12037 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12038 12039 long totalPss = 0; 12040 long cachedPss = 0; 12041 12042 Debug.MemoryInfo mi = null; 12043 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12044 final ProcessRecord r = procs.get(i); 12045 final IApplicationThread thread; 12046 final int pid; 12047 final int oomAdj; 12048 final boolean hasActivities; 12049 synchronized (this) { 12050 thread = r.thread; 12051 pid = r.pid; 12052 oomAdj = r.getSetAdjWithServices(); 12053 hasActivities = r.activities.size() > 0; 12054 } 12055 if (thread != null) { 12056 if (!isCheckinRequest && dumpDetails) { 12057 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12058 } 12059 if (mi == null) { 12060 mi = new Debug.MemoryInfo(); 12061 } 12062 if (dumpDetails || (!brief && !oomOnly)) { 12063 Debug.getMemoryInfo(pid, mi); 12064 } else { 12065 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12066 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12067 } 12068 if (dumpDetails) { 12069 if (localOnly) { 12070 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12071 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12072 if (isCheckinRequest) { 12073 pw.println(); 12074 } 12075 } else { 12076 try { 12077 pw.flush(); 12078 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12079 dumpDalvik, innerArgs); 12080 } catch (RemoteException e) { 12081 if (!isCheckinRequest) { 12082 pw.println("Got RemoteException!"); 12083 pw.flush(); 12084 } 12085 } 12086 } 12087 } 12088 12089 final long myTotalPss = mi.getTotalPss(); 12090 final long myTotalUss = mi.getTotalUss(); 12091 12092 synchronized (this) { 12093 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12094 // Record this for posterity if the process has been stable. 12095 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12096 } 12097 } 12098 12099 if (!isCheckinRequest && mi != null) { 12100 totalPss += myTotalPss; 12101 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12102 (hasActivities ? " / activities)" : ")"), 12103 r.processName, myTotalPss, pid, hasActivities); 12104 procMems.add(pssItem); 12105 procMemsMap.put(pid, pssItem); 12106 12107 nativePss += mi.nativePss; 12108 dalvikPss += mi.dalvikPss; 12109 otherPss += mi.otherPss; 12110 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12111 long mem = mi.getOtherPss(j); 12112 miscPss[j] += mem; 12113 otherPss -= mem; 12114 } 12115 12116 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12117 cachedPss += myTotalPss; 12118 } 12119 12120 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12121 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12122 || oomIndex == (oomPss.length-1)) { 12123 oomPss[oomIndex] += myTotalPss; 12124 if (oomProcs[oomIndex] == null) { 12125 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12126 } 12127 oomProcs[oomIndex].add(pssItem); 12128 break; 12129 } 12130 } 12131 } 12132 } 12133 } 12134 12135 if (!isCheckinRequest && procs.size() > 1) { 12136 // If we are showing aggregations, also look for native processes to 12137 // include so that our aggregations are more accurate. 12138 updateCpuStatsNow(); 12139 synchronized (mProcessCpuThread) { 12140 final int N = mProcessCpuTracker.countStats(); 12141 for (int i=0; i<N; i++) { 12142 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12143 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12144 if (mi == null) { 12145 mi = new Debug.MemoryInfo(); 12146 } 12147 if (!brief && !oomOnly) { 12148 Debug.getMemoryInfo(st.pid, mi); 12149 } else { 12150 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12151 mi.nativePrivateDirty = (int)tmpLong[0]; 12152 } 12153 12154 final long myTotalPss = mi.getTotalPss(); 12155 totalPss += myTotalPss; 12156 12157 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12158 st.name, myTotalPss, st.pid, false); 12159 procMems.add(pssItem); 12160 12161 nativePss += mi.nativePss; 12162 dalvikPss += mi.dalvikPss; 12163 otherPss += mi.otherPss; 12164 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12165 long mem = mi.getOtherPss(j); 12166 miscPss[j] += mem; 12167 otherPss -= mem; 12168 } 12169 oomPss[0] += myTotalPss; 12170 if (oomProcs[0] == null) { 12171 oomProcs[0] = new ArrayList<MemItem>(); 12172 } 12173 oomProcs[0].add(pssItem); 12174 } 12175 } 12176 } 12177 12178 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12179 12180 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12181 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12182 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12183 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12184 String label = Debug.MemoryInfo.getOtherLabel(j); 12185 catMems.add(new MemItem(label, label, miscPss[j], j)); 12186 } 12187 12188 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12189 for (int j=0; j<oomPss.length; j++) { 12190 if (oomPss[j] != 0) { 12191 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12192 : DUMP_MEM_OOM_LABEL[j]; 12193 MemItem item = new MemItem(label, label, oomPss[j], 12194 DUMP_MEM_OOM_ADJ[j]); 12195 item.subitems = oomProcs[j]; 12196 oomMems.add(item); 12197 } 12198 } 12199 12200 if (!brief && !oomOnly && !isCompact) { 12201 pw.println(); 12202 pw.println("Total PSS by process:"); 12203 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12204 pw.println(); 12205 } 12206 if (!isCompact) { 12207 pw.println("Total PSS by OOM adjustment:"); 12208 } 12209 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12210 if (!brief && !oomOnly) { 12211 PrintWriter out = categoryPw != null ? categoryPw : pw; 12212 if (!isCompact) { 12213 out.println(); 12214 out.println("Total PSS by category:"); 12215 } 12216 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12217 } 12218 if (!isCompact) { 12219 pw.println(); 12220 } 12221 MemInfoReader memInfo = new MemInfoReader(); 12222 memInfo.readMemInfo(); 12223 if (!brief) { 12224 if (!isCompact) { 12225 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12226 pw.print(" kB (status "); 12227 switch (mLastMemoryLevel) { 12228 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12229 pw.println("normal)"); 12230 break; 12231 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12232 pw.println("moderate)"); 12233 break; 12234 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12235 pw.println("low)"); 12236 break; 12237 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12238 pw.println("critical)"); 12239 break; 12240 default: 12241 pw.print(mLastMemoryLevel); 12242 pw.println(")"); 12243 break; 12244 } 12245 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12246 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12247 pw.print(cachedPss); pw.print(" cached pss + "); 12248 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12249 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12250 } else { 12251 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12252 pw.print(cachedPss + memInfo.getCachedSizeKb() 12253 + memInfo.getFreeSizeKb()); pw.print(","); 12254 pw.println(totalPss - cachedPss); 12255 } 12256 } 12257 if (!isCompact) { 12258 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12259 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12260 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12261 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12262 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12263 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12264 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12265 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12266 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12267 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12268 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12269 } 12270 if (!brief) { 12271 if (memInfo.getZramTotalSizeKb() != 0) { 12272 if (!isCompact) { 12273 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12274 pw.print(" kB physical used for "); 12275 pw.print(memInfo.getSwapTotalSizeKb() 12276 - memInfo.getSwapFreeSizeKb()); 12277 pw.print(" kB in swap ("); 12278 pw.print(memInfo.getSwapTotalSizeKb()); 12279 pw.println(" kB total swap)"); 12280 } else { 12281 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12282 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12283 pw.println(memInfo.getSwapFreeSizeKb()); 12284 } 12285 } 12286 final int[] SINGLE_LONG_FORMAT = new int[] { 12287 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12288 }; 12289 long[] longOut = new long[1]; 12290 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12291 SINGLE_LONG_FORMAT, null, longOut, null); 12292 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12293 longOut[0] = 0; 12294 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12295 SINGLE_LONG_FORMAT, null, longOut, null); 12296 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12297 longOut[0] = 0; 12298 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12299 SINGLE_LONG_FORMAT, null, longOut, null); 12300 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12301 longOut[0] = 0; 12302 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12303 SINGLE_LONG_FORMAT, null, longOut, null); 12304 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12305 if (!isCompact) { 12306 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12307 pw.print(" KSM: "); pw.print(sharing); 12308 pw.print(" kB saved from shared "); 12309 pw.print(shared); pw.println(" kB"); 12310 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12311 pw.print(voltile); pw.println(" kB volatile"); 12312 } 12313 pw.print(" Tuning: "); 12314 pw.print(ActivityManager.staticGetMemoryClass()); 12315 pw.print(" (large "); 12316 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12317 pw.print("), oom "); 12318 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12319 pw.print(" kB"); 12320 pw.print(", restore limit "); 12321 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12322 pw.print(" kB"); 12323 if (ActivityManager.isLowRamDeviceStatic()) { 12324 pw.print(" (low-ram)"); 12325 } 12326 if (ActivityManager.isHighEndGfx()) { 12327 pw.print(" (high-end-gfx)"); 12328 } 12329 pw.println(); 12330 } else { 12331 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12332 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12333 pw.println(voltile); 12334 pw.print("tuning,"); 12335 pw.print(ActivityManager.staticGetMemoryClass()); 12336 pw.print(','); 12337 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12338 pw.print(','); 12339 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12340 if (ActivityManager.isLowRamDeviceStatic()) { 12341 pw.print(",low-ram"); 12342 } 12343 if (ActivityManager.isHighEndGfx()) { 12344 pw.print(",high-end-gfx"); 12345 } 12346 pw.println(); 12347 } 12348 } 12349 } 12350 } 12351 12352 /** 12353 * Searches array of arguments for the specified string 12354 * @param args array of argument strings 12355 * @param value value to search for 12356 * @return true if the value is contained in the array 12357 */ 12358 private static boolean scanArgs(String[] args, String value) { 12359 if (args != null) { 12360 for (String arg : args) { 12361 if (value.equals(arg)) { 12362 return true; 12363 } 12364 } 12365 } 12366 return false; 12367 } 12368 12369 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12370 ContentProviderRecord cpr, boolean always) { 12371 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12372 12373 if (!inLaunching || always) { 12374 synchronized (cpr) { 12375 cpr.launchingApp = null; 12376 cpr.notifyAll(); 12377 } 12378 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12379 String names[] = cpr.info.authority.split(";"); 12380 for (int j = 0; j < names.length; j++) { 12381 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12382 } 12383 } 12384 12385 for (int i=0; i<cpr.connections.size(); i++) { 12386 ContentProviderConnection conn = cpr.connections.get(i); 12387 if (conn.waiting) { 12388 // If this connection is waiting for the provider, then we don't 12389 // need to mess with its process unless we are always removing 12390 // or for some reason the provider is not currently launching. 12391 if (inLaunching && !always) { 12392 continue; 12393 } 12394 } 12395 ProcessRecord capp = conn.client; 12396 conn.dead = true; 12397 if (conn.stableCount > 0) { 12398 if (!capp.persistent && capp.thread != null 12399 && capp.pid != 0 12400 && capp.pid != MY_PID) { 12401 killUnneededProcessLocked(capp, "depends on provider " 12402 + cpr.name.flattenToShortString() 12403 + " in dying proc " + (proc != null ? proc.processName : "??")); 12404 } 12405 } else if (capp.thread != null && conn.provider.provider != null) { 12406 try { 12407 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12408 } catch (RemoteException e) { 12409 } 12410 // In the protocol here, we don't expect the client to correctly 12411 // clean up this connection, we'll just remove it. 12412 cpr.connections.remove(i); 12413 conn.client.conProviders.remove(conn); 12414 } 12415 } 12416 12417 if (inLaunching && always) { 12418 mLaunchingProviders.remove(cpr); 12419 } 12420 return inLaunching; 12421 } 12422 12423 /** 12424 * Main code for cleaning up a process when it has gone away. This is 12425 * called both as a result of the process dying, or directly when stopping 12426 * a process when running in single process mode. 12427 */ 12428 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12429 boolean restarting, boolean allowRestart, int index) { 12430 if (index >= 0) { 12431 removeLruProcessLocked(app); 12432 ProcessList.remove(app.pid); 12433 } 12434 12435 mProcessesToGc.remove(app); 12436 mPendingPssProcesses.remove(app); 12437 12438 // Dismiss any open dialogs. 12439 if (app.crashDialog != null && !app.forceCrashReport) { 12440 app.crashDialog.dismiss(); 12441 app.crashDialog = null; 12442 } 12443 if (app.anrDialog != null) { 12444 app.anrDialog.dismiss(); 12445 app.anrDialog = null; 12446 } 12447 if (app.waitDialog != null) { 12448 app.waitDialog.dismiss(); 12449 app.waitDialog = null; 12450 } 12451 12452 app.crashing = false; 12453 app.notResponding = false; 12454 12455 app.resetPackageList(mProcessStats); 12456 app.unlinkDeathRecipient(); 12457 app.makeInactive(mProcessStats); 12458 app.forcingToForeground = null; 12459 updateProcessForegroundLocked(app, false, false); 12460 app.foregroundActivities = false; 12461 app.hasShownUi = false; 12462 app.hasAboveClient = false; 12463 12464 mServices.killServicesLocked(app, allowRestart); 12465 12466 boolean restart = false; 12467 12468 // Remove published content providers. 12469 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12470 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12471 final boolean always = app.bad || !allowRestart; 12472 if (removeDyingProviderLocked(app, cpr, always) || always) { 12473 // We left the provider in the launching list, need to 12474 // restart it. 12475 restart = true; 12476 } 12477 12478 cpr.provider = null; 12479 cpr.proc = null; 12480 } 12481 app.pubProviders.clear(); 12482 12483 // Take care of any launching providers waiting for this process. 12484 if (checkAppInLaunchingProvidersLocked(app, false)) { 12485 restart = true; 12486 } 12487 12488 // Unregister from connected content providers. 12489 if (!app.conProviders.isEmpty()) { 12490 for (int i=0; i<app.conProviders.size(); i++) { 12491 ContentProviderConnection conn = app.conProviders.get(i); 12492 conn.provider.connections.remove(conn); 12493 } 12494 app.conProviders.clear(); 12495 } 12496 12497 // At this point there may be remaining entries in mLaunchingProviders 12498 // where we were the only one waiting, so they are no longer of use. 12499 // Look for these and clean up if found. 12500 // XXX Commented out for now. Trying to figure out a way to reproduce 12501 // the actual situation to identify what is actually going on. 12502 if (false) { 12503 for (int i=0; i<mLaunchingProviders.size(); i++) { 12504 ContentProviderRecord cpr = (ContentProviderRecord) 12505 mLaunchingProviders.get(i); 12506 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12507 synchronized (cpr) { 12508 cpr.launchingApp = null; 12509 cpr.notifyAll(); 12510 } 12511 } 12512 } 12513 } 12514 12515 skipCurrentReceiverLocked(app); 12516 12517 // Unregister any receivers. 12518 for (int i=app.receivers.size()-1; i>=0; i--) { 12519 removeReceiverLocked(app.receivers.valueAt(i)); 12520 } 12521 app.receivers.clear(); 12522 12523 // If the app is undergoing backup, tell the backup manager about it 12524 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12525 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12526 + mBackupTarget.appInfo + " died during backup"); 12527 try { 12528 IBackupManager bm = IBackupManager.Stub.asInterface( 12529 ServiceManager.getService(Context.BACKUP_SERVICE)); 12530 bm.agentDisconnected(app.info.packageName); 12531 } catch (RemoteException e) { 12532 // can't happen; backup manager is local 12533 } 12534 } 12535 12536 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12537 ProcessChangeItem item = mPendingProcessChanges.get(i); 12538 if (item.pid == app.pid) { 12539 mPendingProcessChanges.remove(i); 12540 mAvailProcessChanges.add(item); 12541 } 12542 } 12543 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12544 12545 // If the caller is restarting this app, then leave it in its 12546 // current lists and let the caller take care of it. 12547 if (restarting) { 12548 return; 12549 } 12550 12551 if (!app.persistent || app.isolated) { 12552 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12553 "Removing non-persistent process during cleanup: " + app); 12554 mProcessNames.remove(app.processName, app.uid); 12555 mIsolatedProcesses.remove(app.uid); 12556 if (mHeavyWeightProcess == app) { 12557 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12558 mHeavyWeightProcess.userId, 0)); 12559 mHeavyWeightProcess = null; 12560 } 12561 } else if (!app.removed) { 12562 // This app is persistent, so we need to keep its record around. 12563 // If it is not already on the pending app list, add it there 12564 // and start a new process for it. 12565 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12566 mPersistentStartingProcesses.add(app); 12567 restart = true; 12568 } 12569 } 12570 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12571 "Clean-up removing on hold: " + app); 12572 mProcessesOnHold.remove(app); 12573 12574 if (app == mHomeProcess) { 12575 mHomeProcess = null; 12576 } 12577 if (app == mPreviousProcess) { 12578 mPreviousProcess = null; 12579 } 12580 12581 if (restart && !app.isolated) { 12582 // We have components that still need to be running in the 12583 // process, so re-launch it. 12584 mProcessNames.put(app.processName, app.uid, app); 12585 startProcessLocked(app, "restart", app.processName); 12586 } else if (app.pid > 0 && app.pid != MY_PID) { 12587 // Goodbye! 12588 boolean removed; 12589 synchronized (mPidsSelfLocked) { 12590 mPidsSelfLocked.remove(app.pid); 12591 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12592 } 12593 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12594 app.processName, app.info.uid); 12595 if (app.isolated) { 12596 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12597 } 12598 app.setPid(0); 12599 } 12600 } 12601 12602 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12603 // Look through the content providers we are waiting to have launched, 12604 // and if any run in this process then either schedule a restart of 12605 // the process or kill the client waiting for it if this process has 12606 // gone bad. 12607 int NL = mLaunchingProviders.size(); 12608 boolean restart = false; 12609 for (int i=0; i<NL; i++) { 12610 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12611 if (cpr.launchingApp == app) { 12612 if (!alwaysBad && !app.bad) { 12613 restart = true; 12614 } else { 12615 removeDyingProviderLocked(app, cpr, true); 12616 // cpr should have been removed from mLaunchingProviders 12617 NL = mLaunchingProviders.size(); 12618 i--; 12619 } 12620 } 12621 } 12622 return restart; 12623 } 12624 12625 // ========================================================= 12626 // SERVICES 12627 // ========================================================= 12628 12629 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12630 int flags) { 12631 enforceNotIsolatedCaller("getServices"); 12632 synchronized (this) { 12633 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12634 } 12635 } 12636 12637 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12638 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12639 synchronized (this) { 12640 return mServices.getRunningServiceControlPanelLocked(name); 12641 } 12642 } 12643 12644 public ComponentName startService(IApplicationThread caller, Intent service, 12645 String resolvedType, int userId) { 12646 enforceNotIsolatedCaller("startService"); 12647 // Refuse possible leaked file descriptors 12648 if (service != null && service.hasFileDescriptors() == true) { 12649 throw new IllegalArgumentException("File descriptors passed in Intent"); 12650 } 12651 12652 if (DEBUG_SERVICE) 12653 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12654 synchronized(this) { 12655 final int callingPid = Binder.getCallingPid(); 12656 final int callingUid = Binder.getCallingUid(); 12657 final long origId = Binder.clearCallingIdentity(); 12658 ComponentName res = mServices.startServiceLocked(caller, service, 12659 resolvedType, callingPid, callingUid, userId); 12660 Binder.restoreCallingIdentity(origId); 12661 return res; 12662 } 12663 } 12664 12665 ComponentName startServiceInPackage(int uid, 12666 Intent service, String resolvedType, int userId) { 12667 synchronized(this) { 12668 if (DEBUG_SERVICE) 12669 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12670 final long origId = Binder.clearCallingIdentity(); 12671 ComponentName res = mServices.startServiceLocked(null, service, 12672 resolvedType, -1, uid, userId); 12673 Binder.restoreCallingIdentity(origId); 12674 return res; 12675 } 12676 } 12677 12678 public int stopService(IApplicationThread caller, Intent service, 12679 String resolvedType, int userId) { 12680 enforceNotIsolatedCaller("stopService"); 12681 // Refuse possible leaked file descriptors 12682 if (service != null && service.hasFileDescriptors() == true) { 12683 throw new IllegalArgumentException("File descriptors passed in Intent"); 12684 } 12685 12686 synchronized(this) { 12687 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12688 } 12689 } 12690 12691 public IBinder peekService(Intent service, String resolvedType) { 12692 enforceNotIsolatedCaller("peekService"); 12693 // Refuse possible leaked file descriptors 12694 if (service != null && service.hasFileDescriptors() == true) { 12695 throw new IllegalArgumentException("File descriptors passed in Intent"); 12696 } 12697 synchronized(this) { 12698 return mServices.peekServiceLocked(service, resolvedType); 12699 } 12700 } 12701 12702 public boolean stopServiceToken(ComponentName className, IBinder token, 12703 int startId) { 12704 synchronized(this) { 12705 return mServices.stopServiceTokenLocked(className, token, startId); 12706 } 12707 } 12708 12709 public void setServiceForeground(ComponentName className, IBinder token, 12710 int id, Notification notification, boolean removeNotification) { 12711 synchronized(this) { 12712 mServices.setServiceForegroundLocked(className, token, id, notification, 12713 removeNotification); 12714 } 12715 } 12716 12717 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12718 boolean requireFull, String name, String callerPackage) { 12719 final int callingUserId = UserHandle.getUserId(callingUid); 12720 if (callingUserId != userId) { 12721 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12722 if ((requireFull || checkComponentPermission( 12723 android.Manifest.permission.INTERACT_ACROSS_USERS, 12724 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12725 && checkComponentPermission( 12726 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12727 callingPid, callingUid, -1, true) 12728 != PackageManager.PERMISSION_GRANTED) { 12729 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12730 // In this case, they would like to just execute as their 12731 // owner user instead of failing. 12732 userId = callingUserId; 12733 } else { 12734 StringBuilder builder = new StringBuilder(128); 12735 builder.append("Permission Denial: "); 12736 builder.append(name); 12737 if (callerPackage != null) { 12738 builder.append(" from "); 12739 builder.append(callerPackage); 12740 } 12741 builder.append(" asks to run as user "); 12742 builder.append(userId); 12743 builder.append(" but is calling from user "); 12744 builder.append(UserHandle.getUserId(callingUid)); 12745 builder.append("; this requires "); 12746 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12747 if (!requireFull) { 12748 builder.append(" or "); 12749 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12750 } 12751 String msg = builder.toString(); 12752 Slog.w(TAG, msg); 12753 throw new SecurityException(msg); 12754 } 12755 } 12756 } 12757 if (userId == UserHandle.USER_CURRENT 12758 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12759 // Note that we may be accessing this outside of a lock... 12760 // shouldn't be a big deal, if this is being called outside 12761 // of a locked context there is intrinsically a race with 12762 // the value the caller will receive and someone else changing it. 12763 userId = mCurrentUserId; 12764 } 12765 if (!allowAll && userId < 0) { 12766 throw new IllegalArgumentException( 12767 "Call does not support special user #" + userId); 12768 } 12769 } 12770 return userId; 12771 } 12772 12773 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12774 String className, int flags) { 12775 boolean result = false; 12776 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12777 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12778 if (ActivityManager.checkUidPermission( 12779 android.Manifest.permission.INTERACT_ACROSS_USERS, 12780 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12781 ComponentName comp = new ComponentName(aInfo.packageName, className); 12782 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12783 + " requests FLAG_SINGLE_USER, but app does not hold " 12784 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12785 Slog.w(TAG, msg); 12786 throw new SecurityException(msg); 12787 } 12788 result = true; 12789 } 12790 } else if (componentProcessName == aInfo.packageName) { 12791 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12792 } else if ("system".equals(componentProcessName)) { 12793 result = true; 12794 } 12795 if (DEBUG_MU) { 12796 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12797 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12798 } 12799 return result; 12800 } 12801 12802 public int bindService(IApplicationThread caller, IBinder token, 12803 Intent service, String resolvedType, 12804 IServiceConnection connection, int flags, int userId) { 12805 enforceNotIsolatedCaller("bindService"); 12806 // Refuse possible leaked file descriptors 12807 if (service != null && service.hasFileDescriptors() == true) { 12808 throw new IllegalArgumentException("File descriptors passed in Intent"); 12809 } 12810 12811 synchronized(this) { 12812 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12813 connection, flags, userId); 12814 } 12815 } 12816 12817 public boolean unbindService(IServiceConnection connection) { 12818 synchronized (this) { 12819 return mServices.unbindServiceLocked(connection); 12820 } 12821 } 12822 12823 public void publishService(IBinder token, Intent intent, IBinder service) { 12824 // Refuse possible leaked file descriptors 12825 if (intent != null && intent.hasFileDescriptors() == true) { 12826 throw new IllegalArgumentException("File descriptors passed in Intent"); 12827 } 12828 12829 synchronized(this) { 12830 if (!(token instanceof ServiceRecord)) { 12831 throw new IllegalArgumentException("Invalid service token"); 12832 } 12833 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12834 } 12835 } 12836 12837 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12838 // Refuse possible leaked file descriptors 12839 if (intent != null && intent.hasFileDescriptors() == true) { 12840 throw new IllegalArgumentException("File descriptors passed in Intent"); 12841 } 12842 12843 synchronized(this) { 12844 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12845 } 12846 } 12847 12848 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12849 synchronized(this) { 12850 if (!(token instanceof ServiceRecord)) { 12851 throw new IllegalArgumentException("Invalid service token"); 12852 } 12853 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12854 } 12855 } 12856 12857 // ========================================================= 12858 // BACKUP AND RESTORE 12859 // ========================================================= 12860 12861 // Cause the target app to be launched if necessary and its backup agent 12862 // instantiated. The backup agent will invoke backupAgentCreated() on the 12863 // activity manager to announce its creation. 12864 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12865 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12866 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12867 12868 synchronized(this) { 12869 // !!! TODO: currently no check here that we're already bound 12870 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12871 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12872 synchronized (stats) { 12873 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12874 } 12875 12876 // Backup agent is now in use, its package can't be stopped. 12877 try { 12878 AppGlobals.getPackageManager().setPackageStoppedState( 12879 app.packageName, false, UserHandle.getUserId(app.uid)); 12880 } catch (RemoteException e) { 12881 } catch (IllegalArgumentException e) { 12882 Slog.w(TAG, "Failed trying to unstop package " 12883 + app.packageName + ": " + e); 12884 } 12885 12886 BackupRecord r = new BackupRecord(ss, app, backupMode); 12887 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12888 ? new ComponentName(app.packageName, app.backupAgentName) 12889 : new ComponentName("android", "FullBackupAgent"); 12890 // startProcessLocked() returns existing proc's record if it's already running 12891 ProcessRecord proc = startProcessLocked(app.processName, app, 12892 false, 0, "backup", hostingName, false, false, false); 12893 if (proc == null) { 12894 Slog.e(TAG, "Unable to start backup agent process " + r); 12895 return false; 12896 } 12897 12898 r.app = proc; 12899 mBackupTarget = r; 12900 mBackupAppName = app.packageName; 12901 12902 // Try not to kill the process during backup 12903 updateOomAdjLocked(proc); 12904 12905 // If the process is already attached, schedule the creation of the backup agent now. 12906 // If it is not yet live, this will be done when it attaches to the framework. 12907 if (proc.thread != null) { 12908 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12909 try { 12910 proc.thread.scheduleCreateBackupAgent(app, 12911 compatibilityInfoForPackageLocked(app), backupMode); 12912 } catch (RemoteException e) { 12913 // Will time out on the backup manager side 12914 } 12915 } else { 12916 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12917 } 12918 // Invariants: at this point, the target app process exists and the application 12919 // is either already running or in the process of coming up. mBackupTarget and 12920 // mBackupAppName describe the app, so that when it binds back to the AM we 12921 // know that it's scheduled for a backup-agent operation. 12922 } 12923 12924 return true; 12925 } 12926 12927 @Override 12928 public void clearPendingBackup() { 12929 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 12930 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 12931 12932 synchronized (this) { 12933 mBackupTarget = null; 12934 mBackupAppName = null; 12935 } 12936 } 12937 12938 // A backup agent has just come up 12939 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12940 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12941 + " = " + agent); 12942 12943 synchronized(this) { 12944 if (!agentPackageName.equals(mBackupAppName)) { 12945 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12946 return; 12947 } 12948 } 12949 12950 long oldIdent = Binder.clearCallingIdentity(); 12951 try { 12952 IBackupManager bm = IBackupManager.Stub.asInterface( 12953 ServiceManager.getService(Context.BACKUP_SERVICE)); 12954 bm.agentConnected(agentPackageName, agent); 12955 } catch (RemoteException e) { 12956 // can't happen; the backup manager service is local 12957 } catch (Exception e) { 12958 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12959 e.printStackTrace(); 12960 } finally { 12961 Binder.restoreCallingIdentity(oldIdent); 12962 } 12963 } 12964 12965 // done with this agent 12966 public void unbindBackupAgent(ApplicationInfo appInfo) { 12967 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12968 if (appInfo == null) { 12969 Slog.w(TAG, "unbind backup agent for null app"); 12970 return; 12971 } 12972 12973 synchronized(this) { 12974 try { 12975 if (mBackupAppName == null) { 12976 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12977 return; 12978 } 12979 12980 if (!mBackupAppName.equals(appInfo.packageName)) { 12981 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12982 return; 12983 } 12984 12985 // Not backing this app up any more; reset its OOM adjustment 12986 final ProcessRecord proc = mBackupTarget.app; 12987 updateOomAdjLocked(proc); 12988 12989 // If the app crashed during backup, 'thread' will be null here 12990 if (proc.thread != null) { 12991 try { 12992 proc.thread.scheduleDestroyBackupAgent(appInfo, 12993 compatibilityInfoForPackageLocked(appInfo)); 12994 } catch (Exception e) { 12995 Slog.e(TAG, "Exception when unbinding backup agent:"); 12996 e.printStackTrace(); 12997 } 12998 } 12999 } finally { 13000 mBackupTarget = null; 13001 mBackupAppName = null; 13002 } 13003 } 13004 } 13005 // ========================================================= 13006 // BROADCASTS 13007 // ========================================================= 13008 13009 private final List getStickiesLocked(String action, IntentFilter filter, 13010 List cur, int userId) { 13011 final ContentResolver resolver = mContext.getContentResolver(); 13012 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13013 if (stickies == null) { 13014 return cur; 13015 } 13016 final ArrayList<Intent> list = stickies.get(action); 13017 if (list == null) { 13018 return cur; 13019 } 13020 int N = list.size(); 13021 for (int i=0; i<N; i++) { 13022 Intent intent = list.get(i); 13023 if (filter.match(resolver, intent, true, TAG) >= 0) { 13024 if (cur == null) { 13025 cur = new ArrayList<Intent>(); 13026 } 13027 cur.add(intent); 13028 } 13029 } 13030 return cur; 13031 } 13032 13033 boolean isPendingBroadcastProcessLocked(int pid) { 13034 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13035 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13036 } 13037 13038 void skipPendingBroadcastLocked(int pid) { 13039 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13040 for (BroadcastQueue queue : mBroadcastQueues) { 13041 queue.skipPendingBroadcastLocked(pid); 13042 } 13043 } 13044 13045 // The app just attached; send any pending broadcasts that it should receive 13046 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13047 boolean didSomething = false; 13048 for (BroadcastQueue queue : mBroadcastQueues) { 13049 didSomething |= queue.sendPendingBroadcastsLocked(app); 13050 } 13051 return didSomething; 13052 } 13053 13054 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13055 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13056 enforceNotIsolatedCaller("registerReceiver"); 13057 int callingUid; 13058 int callingPid; 13059 synchronized(this) { 13060 ProcessRecord callerApp = null; 13061 if (caller != null) { 13062 callerApp = getRecordForAppLocked(caller); 13063 if (callerApp == null) { 13064 throw new SecurityException( 13065 "Unable to find app for caller " + caller 13066 + " (pid=" + Binder.getCallingPid() 13067 + ") when registering receiver " + receiver); 13068 } 13069 if (callerApp.info.uid != Process.SYSTEM_UID && 13070 !callerApp.pkgList.containsKey(callerPackage) && 13071 !"android".equals(callerPackage)) { 13072 throw new SecurityException("Given caller package " + callerPackage 13073 + " is not running in process " + callerApp); 13074 } 13075 callingUid = callerApp.info.uid; 13076 callingPid = callerApp.pid; 13077 } else { 13078 callerPackage = null; 13079 callingUid = Binder.getCallingUid(); 13080 callingPid = Binder.getCallingPid(); 13081 } 13082 13083 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13084 true, true, "registerReceiver", callerPackage); 13085 13086 List allSticky = null; 13087 13088 // Look for any matching sticky broadcasts... 13089 Iterator actions = filter.actionsIterator(); 13090 if (actions != null) { 13091 while (actions.hasNext()) { 13092 String action = (String)actions.next(); 13093 allSticky = getStickiesLocked(action, filter, allSticky, 13094 UserHandle.USER_ALL); 13095 allSticky = getStickiesLocked(action, filter, allSticky, 13096 UserHandle.getUserId(callingUid)); 13097 } 13098 } else { 13099 allSticky = getStickiesLocked(null, filter, allSticky, 13100 UserHandle.USER_ALL); 13101 allSticky = getStickiesLocked(null, filter, allSticky, 13102 UserHandle.getUserId(callingUid)); 13103 } 13104 13105 // The first sticky in the list is returned directly back to 13106 // the client. 13107 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13108 13109 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13110 + ": " + sticky); 13111 13112 if (receiver == null) { 13113 return sticky; 13114 } 13115 13116 ReceiverList rl 13117 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13118 if (rl == null) { 13119 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13120 userId, receiver); 13121 if (rl.app != null) { 13122 rl.app.receivers.add(rl); 13123 } else { 13124 try { 13125 receiver.asBinder().linkToDeath(rl, 0); 13126 } catch (RemoteException e) { 13127 return sticky; 13128 } 13129 rl.linkedToDeath = true; 13130 } 13131 mRegisteredReceivers.put(receiver.asBinder(), rl); 13132 } else if (rl.uid != callingUid) { 13133 throw new IllegalArgumentException( 13134 "Receiver requested to register for uid " + callingUid 13135 + " was previously registered for uid " + rl.uid); 13136 } else if (rl.pid != callingPid) { 13137 throw new IllegalArgumentException( 13138 "Receiver requested to register for pid " + callingPid 13139 + " was previously registered for pid " + rl.pid); 13140 } else if (rl.userId != userId) { 13141 throw new IllegalArgumentException( 13142 "Receiver requested to register for user " + userId 13143 + " was previously registered for user " + rl.userId); 13144 } 13145 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13146 permission, callingUid, userId); 13147 rl.add(bf); 13148 if (!bf.debugCheck()) { 13149 Slog.w(TAG, "==> For Dynamic broadast"); 13150 } 13151 mReceiverResolver.addFilter(bf); 13152 13153 // Enqueue broadcasts for all existing stickies that match 13154 // this filter. 13155 if (allSticky != null) { 13156 ArrayList receivers = new ArrayList(); 13157 receivers.add(bf); 13158 13159 int N = allSticky.size(); 13160 for (int i=0; i<N; i++) { 13161 Intent intent = (Intent)allSticky.get(i); 13162 BroadcastQueue queue = broadcastQueueForIntent(intent); 13163 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13164 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13165 null, null, false, true, true, -1); 13166 queue.enqueueParallelBroadcastLocked(r); 13167 queue.scheduleBroadcastsLocked(); 13168 } 13169 } 13170 13171 return sticky; 13172 } 13173 } 13174 13175 public void unregisterReceiver(IIntentReceiver receiver) { 13176 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13177 13178 final long origId = Binder.clearCallingIdentity(); 13179 try { 13180 boolean doTrim = false; 13181 13182 synchronized(this) { 13183 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13184 if (rl != null) { 13185 if (rl.curBroadcast != null) { 13186 BroadcastRecord r = rl.curBroadcast; 13187 final boolean doNext = finishReceiverLocked( 13188 receiver.asBinder(), r.resultCode, r.resultData, 13189 r.resultExtras, r.resultAbort); 13190 if (doNext) { 13191 doTrim = true; 13192 r.queue.processNextBroadcast(false); 13193 } 13194 } 13195 13196 if (rl.app != null) { 13197 rl.app.receivers.remove(rl); 13198 } 13199 removeReceiverLocked(rl); 13200 if (rl.linkedToDeath) { 13201 rl.linkedToDeath = false; 13202 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13203 } 13204 } 13205 } 13206 13207 // If we actually concluded any broadcasts, we might now be able 13208 // to trim the recipients' apps from our working set 13209 if (doTrim) { 13210 trimApplications(); 13211 return; 13212 } 13213 13214 } finally { 13215 Binder.restoreCallingIdentity(origId); 13216 } 13217 } 13218 13219 void removeReceiverLocked(ReceiverList rl) { 13220 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13221 int N = rl.size(); 13222 for (int i=0; i<N; i++) { 13223 mReceiverResolver.removeFilter(rl.get(i)); 13224 } 13225 } 13226 13227 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13228 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13229 ProcessRecord r = mLruProcesses.get(i); 13230 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13231 try { 13232 r.thread.dispatchPackageBroadcast(cmd, packages); 13233 } catch (RemoteException ex) { 13234 } 13235 } 13236 } 13237 } 13238 13239 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13240 int[] users) { 13241 List<ResolveInfo> receivers = null; 13242 try { 13243 HashSet<ComponentName> singleUserReceivers = null; 13244 boolean scannedFirstReceivers = false; 13245 for (int user : users) { 13246 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13247 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13248 if (user != 0 && newReceivers != null) { 13249 // If this is not the primary user, we need to check for 13250 // any receivers that should be filtered out. 13251 for (int i=0; i<newReceivers.size(); i++) { 13252 ResolveInfo ri = newReceivers.get(i); 13253 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13254 newReceivers.remove(i); 13255 i--; 13256 } 13257 } 13258 } 13259 if (newReceivers != null && newReceivers.size() == 0) { 13260 newReceivers = null; 13261 } 13262 if (receivers == null) { 13263 receivers = newReceivers; 13264 } else if (newReceivers != null) { 13265 // We need to concatenate the additional receivers 13266 // found with what we have do far. This would be easy, 13267 // but we also need to de-dup any receivers that are 13268 // singleUser. 13269 if (!scannedFirstReceivers) { 13270 // Collect any single user receivers we had already retrieved. 13271 scannedFirstReceivers = true; 13272 for (int i=0; i<receivers.size(); i++) { 13273 ResolveInfo ri = receivers.get(i); 13274 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13275 ComponentName cn = new ComponentName( 13276 ri.activityInfo.packageName, ri.activityInfo.name); 13277 if (singleUserReceivers == null) { 13278 singleUserReceivers = new HashSet<ComponentName>(); 13279 } 13280 singleUserReceivers.add(cn); 13281 } 13282 } 13283 } 13284 // Add the new results to the existing results, tracking 13285 // and de-dupping single user receivers. 13286 for (int i=0; i<newReceivers.size(); i++) { 13287 ResolveInfo ri = newReceivers.get(i); 13288 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13289 ComponentName cn = new ComponentName( 13290 ri.activityInfo.packageName, ri.activityInfo.name); 13291 if (singleUserReceivers == null) { 13292 singleUserReceivers = new HashSet<ComponentName>(); 13293 } 13294 if (!singleUserReceivers.contains(cn)) { 13295 singleUserReceivers.add(cn); 13296 receivers.add(ri); 13297 } 13298 } else { 13299 receivers.add(ri); 13300 } 13301 } 13302 } 13303 } 13304 } catch (RemoteException ex) { 13305 // pm is in same process, this will never happen. 13306 } 13307 return receivers; 13308 } 13309 13310 private final int broadcastIntentLocked(ProcessRecord callerApp, 13311 String callerPackage, Intent intent, String resolvedType, 13312 IIntentReceiver resultTo, int resultCode, String resultData, 13313 Bundle map, String requiredPermission, int appOp, 13314 boolean ordered, boolean sticky, int callingPid, int callingUid, 13315 int userId) { 13316 intent = new Intent(intent); 13317 13318 // By default broadcasts do not go to stopped apps. 13319 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13320 13321 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13322 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13323 + " ordered=" + ordered + " userid=" + userId); 13324 if ((resultTo != null) && !ordered) { 13325 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13326 } 13327 13328 userId = handleIncomingUser(callingPid, callingUid, userId, 13329 true, false, "broadcast", callerPackage); 13330 13331 // Make sure that the user who is receiving this broadcast is started. 13332 // If not, we will just skip it. 13333 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13334 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13335 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13336 Slog.w(TAG, "Skipping broadcast of " + intent 13337 + ": user " + userId + " is stopped"); 13338 return ActivityManager.BROADCAST_SUCCESS; 13339 } 13340 } 13341 13342 /* 13343 * Prevent non-system code (defined here to be non-persistent 13344 * processes) from sending protected broadcasts. 13345 */ 13346 int callingAppId = UserHandle.getAppId(callingUid); 13347 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13348 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13349 callingUid == 0) { 13350 // Always okay. 13351 } else if (callerApp == null || !callerApp.persistent) { 13352 try { 13353 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13354 intent.getAction())) { 13355 String msg = "Permission Denial: not allowed to send broadcast " 13356 + intent.getAction() + " from pid=" 13357 + callingPid + ", uid=" + callingUid; 13358 Slog.w(TAG, msg); 13359 throw new SecurityException(msg); 13360 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13361 // Special case for compatibility: we don't want apps to send this, 13362 // but historically it has not been protected and apps may be using it 13363 // to poke their own app widget. So, instead of making it protected, 13364 // just limit it to the caller. 13365 if (callerApp == null) { 13366 String msg = "Permission Denial: not allowed to send broadcast " 13367 + intent.getAction() + " from unknown caller."; 13368 Slog.w(TAG, msg); 13369 throw new SecurityException(msg); 13370 } else if (intent.getComponent() != null) { 13371 // They are good enough to send to an explicit component... verify 13372 // it is being sent to the calling app. 13373 if (!intent.getComponent().getPackageName().equals( 13374 callerApp.info.packageName)) { 13375 String msg = "Permission Denial: not allowed to send broadcast " 13376 + intent.getAction() + " to " 13377 + intent.getComponent().getPackageName() + " from " 13378 + callerApp.info.packageName; 13379 Slog.w(TAG, msg); 13380 throw new SecurityException(msg); 13381 } 13382 } else { 13383 // Limit broadcast to their own package. 13384 intent.setPackage(callerApp.info.packageName); 13385 } 13386 } 13387 } catch (RemoteException e) { 13388 Slog.w(TAG, "Remote exception", e); 13389 return ActivityManager.BROADCAST_SUCCESS; 13390 } 13391 } 13392 13393 // Handle special intents: if this broadcast is from the package 13394 // manager about a package being removed, we need to remove all of 13395 // its activities from the history stack. 13396 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13397 intent.getAction()); 13398 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13399 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13400 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13401 || uidRemoved) { 13402 if (checkComponentPermission( 13403 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13404 callingPid, callingUid, -1, true) 13405 == PackageManager.PERMISSION_GRANTED) { 13406 if (uidRemoved) { 13407 final Bundle intentExtras = intent.getExtras(); 13408 final int uid = intentExtras != null 13409 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13410 if (uid >= 0) { 13411 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13412 synchronized (bs) { 13413 bs.removeUidStatsLocked(uid); 13414 } 13415 mAppOpsService.uidRemoved(uid); 13416 } 13417 } else { 13418 // If resources are unavailable just force stop all 13419 // those packages and flush the attribute cache as well. 13420 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13421 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13422 if (list != null && (list.length > 0)) { 13423 for (String pkg : list) { 13424 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13425 "storage unmount"); 13426 } 13427 sendPackageBroadcastLocked( 13428 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13429 } 13430 } else { 13431 Uri data = intent.getData(); 13432 String ssp; 13433 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13434 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13435 intent.getAction()); 13436 boolean fullUninstall = removed && 13437 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13438 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13439 forceStopPackageLocked(ssp, UserHandle.getAppId( 13440 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13441 false, fullUninstall, userId, 13442 removed ? "pkg removed" : "pkg changed"); 13443 } 13444 if (removed) { 13445 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13446 new String[] {ssp}, userId); 13447 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13448 mAppOpsService.packageRemoved( 13449 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13450 13451 // Remove all permissions granted from/to this package 13452 removeUriPermissionsForPackageLocked(ssp, userId, true); 13453 } 13454 } 13455 } 13456 } 13457 } 13458 } else { 13459 String msg = "Permission Denial: " + intent.getAction() 13460 + " broadcast from " + callerPackage + " (pid=" + callingPid 13461 + ", uid=" + callingUid + ")" 13462 + " requires " 13463 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13464 Slog.w(TAG, msg); 13465 throw new SecurityException(msg); 13466 } 13467 13468 // Special case for adding a package: by default turn on compatibility 13469 // mode. 13470 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13471 Uri data = intent.getData(); 13472 String ssp; 13473 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13474 mCompatModePackages.handlePackageAddedLocked(ssp, 13475 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13476 } 13477 } 13478 13479 /* 13480 * If this is the time zone changed action, queue up a message that will reset the timezone 13481 * of all currently running processes. This message will get queued up before the broadcast 13482 * happens. 13483 */ 13484 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13485 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13486 } 13487 13488 /* 13489 * If the user set the time, let all running processes know. 13490 */ 13491 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13492 final int is24Hour = intent.getBooleanExtra( 13493 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13494 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13495 } 13496 13497 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13498 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13499 } 13500 13501 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13502 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13503 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13504 } 13505 13506 // Add to the sticky list if requested. 13507 if (sticky) { 13508 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13509 callingPid, callingUid) 13510 != PackageManager.PERMISSION_GRANTED) { 13511 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13512 + callingPid + ", uid=" + callingUid 13513 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13514 Slog.w(TAG, msg); 13515 throw new SecurityException(msg); 13516 } 13517 if (requiredPermission != null) { 13518 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13519 + " and enforce permission " + requiredPermission); 13520 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13521 } 13522 if (intent.getComponent() != null) { 13523 throw new SecurityException( 13524 "Sticky broadcasts can't target a specific component"); 13525 } 13526 // We use userId directly here, since the "all" target is maintained 13527 // as a separate set of sticky broadcasts. 13528 if (userId != UserHandle.USER_ALL) { 13529 // But first, if this is not a broadcast to all users, then 13530 // make sure it doesn't conflict with an existing broadcast to 13531 // all users. 13532 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13533 UserHandle.USER_ALL); 13534 if (stickies != null) { 13535 ArrayList<Intent> list = stickies.get(intent.getAction()); 13536 if (list != null) { 13537 int N = list.size(); 13538 int i; 13539 for (i=0; i<N; i++) { 13540 if (intent.filterEquals(list.get(i))) { 13541 throw new IllegalArgumentException( 13542 "Sticky broadcast " + intent + " for user " 13543 + userId + " conflicts with existing global broadcast"); 13544 } 13545 } 13546 } 13547 } 13548 } 13549 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13550 if (stickies == null) { 13551 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13552 mStickyBroadcasts.put(userId, stickies); 13553 } 13554 ArrayList<Intent> list = stickies.get(intent.getAction()); 13555 if (list == null) { 13556 list = new ArrayList<Intent>(); 13557 stickies.put(intent.getAction(), list); 13558 } 13559 int N = list.size(); 13560 int i; 13561 for (i=0; i<N; i++) { 13562 if (intent.filterEquals(list.get(i))) { 13563 // This sticky already exists, replace it. 13564 list.set(i, new Intent(intent)); 13565 break; 13566 } 13567 } 13568 if (i >= N) { 13569 list.add(new Intent(intent)); 13570 } 13571 } 13572 13573 int[] users; 13574 if (userId == UserHandle.USER_ALL) { 13575 // Caller wants broadcast to go to all started users. 13576 users = mStartedUserArray; 13577 } else { 13578 // Caller wants broadcast to go to one specific user. 13579 users = new int[] {userId}; 13580 } 13581 13582 // Figure out who all will receive this broadcast. 13583 List receivers = null; 13584 List<BroadcastFilter> registeredReceivers = null; 13585 // Need to resolve the intent to interested receivers... 13586 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13587 == 0) { 13588 receivers = collectReceiverComponents(intent, resolvedType, users); 13589 } 13590 if (intent.getComponent() == null) { 13591 registeredReceivers = mReceiverResolver.queryIntent(intent, 13592 resolvedType, false, userId); 13593 } 13594 13595 final boolean replacePending = 13596 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13597 13598 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13599 + " replacePending=" + replacePending); 13600 13601 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13602 if (!ordered && NR > 0) { 13603 // If we are not serializing this broadcast, then send the 13604 // registered receivers separately so they don't wait for the 13605 // components to be launched. 13606 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13607 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13608 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13609 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13610 ordered, sticky, false, userId); 13611 if (DEBUG_BROADCAST) Slog.v( 13612 TAG, "Enqueueing parallel broadcast " + r); 13613 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13614 if (!replaced) { 13615 queue.enqueueParallelBroadcastLocked(r); 13616 queue.scheduleBroadcastsLocked(); 13617 } 13618 registeredReceivers = null; 13619 NR = 0; 13620 } 13621 13622 // Merge into one list. 13623 int ir = 0; 13624 if (receivers != null) { 13625 // A special case for PACKAGE_ADDED: do not allow the package 13626 // being added to see this broadcast. This prevents them from 13627 // using this as a back door to get run as soon as they are 13628 // installed. Maybe in the future we want to have a special install 13629 // broadcast or such for apps, but we'd like to deliberately make 13630 // this decision. 13631 String skipPackages[] = null; 13632 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13633 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13634 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13635 Uri data = intent.getData(); 13636 if (data != null) { 13637 String pkgName = data.getSchemeSpecificPart(); 13638 if (pkgName != null) { 13639 skipPackages = new String[] { pkgName }; 13640 } 13641 } 13642 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13643 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13644 } 13645 if (skipPackages != null && (skipPackages.length > 0)) { 13646 for (String skipPackage : skipPackages) { 13647 if (skipPackage != null) { 13648 int NT = receivers.size(); 13649 for (int it=0; it<NT; it++) { 13650 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13651 if (curt.activityInfo.packageName.equals(skipPackage)) { 13652 receivers.remove(it); 13653 it--; 13654 NT--; 13655 } 13656 } 13657 } 13658 } 13659 } 13660 13661 int NT = receivers != null ? receivers.size() : 0; 13662 int it = 0; 13663 ResolveInfo curt = null; 13664 BroadcastFilter curr = null; 13665 while (it < NT && ir < NR) { 13666 if (curt == null) { 13667 curt = (ResolveInfo)receivers.get(it); 13668 } 13669 if (curr == null) { 13670 curr = registeredReceivers.get(ir); 13671 } 13672 if (curr.getPriority() >= curt.priority) { 13673 // Insert this broadcast record into the final list. 13674 receivers.add(it, curr); 13675 ir++; 13676 curr = null; 13677 it++; 13678 NT++; 13679 } else { 13680 // Skip to the next ResolveInfo in the final list. 13681 it++; 13682 curt = null; 13683 } 13684 } 13685 } 13686 while (ir < NR) { 13687 if (receivers == null) { 13688 receivers = new ArrayList(); 13689 } 13690 receivers.add(registeredReceivers.get(ir)); 13691 ir++; 13692 } 13693 13694 if ((receivers != null && receivers.size() > 0) 13695 || resultTo != null) { 13696 BroadcastQueue queue = broadcastQueueForIntent(intent); 13697 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13698 callerPackage, callingPid, callingUid, resolvedType, 13699 requiredPermission, appOp, receivers, resultTo, resultCode, 13700 resultData, map, ordered, sticky, false, userId); 13701 if (DEBUG_BROADCAST) Slog.v( 13702 TAG, "Enqueueing ordered broadcast " + r 13703 + ": prev had " + queue.mOrderedBroadcasts.size()); 13704 if (DEBUG_BROADCAST) { 13705 int seq = r.intent.getIntExtra("seq", -1); 13706 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13707 } 13708 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13709 if (!replaced) { 13710 queue.enqueueOrderedBroadcastLocked(r); 13711 queue.scheduleBroadcastsLocked(); 13712 } 13713 } 13714 13715 return ActivityManager.BROADCAST_SUCCESS; 13716 } 13717 13718 final Intent verifyBroadcastLocked(Intent intent) { 13719 // Refuse possible leaked file descriptors 13720 if (intent != null && intent.hasFileDescriptors() == true) { 13721 throw new IllegalArgumentException("File descriptors passed in Intent"); 13722 } 13723 13724 int flags = intent.getFlags(); 13725 13726 if (!mProcessesReady) { 13727 // if the caller really truly claims to know what they're doing, go 13728 // ahead and allow the broadcast without launching any receivers 13729 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13730 intent = new Intent(intent); 13731 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13732 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13733 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13734 + " before boot completion"); 13735 throw new IllegalStateException("Cannot broadcast before boot completed"); 13736 } 13737 } 13738 13739 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13740 throw new IllegalArgumentException( 13741 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13742 } 13743 13744 return intent; 13745 } 13746 13747 public final int broadcastIntent(IApplicationThread caller, 13748 Intent intent, String resolvedType, IIntentReceiver resultTo, 13749 int resultCode, String resultData, Bundle map, 13750 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13751 enforceNotIsolatedCaller("broadcastIntent"); 13752 synchronized(this) { 13753 intent = verifyBroadcastLocked(intent); 13754 13755 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13756 final int callingPid = Binder.getCallingPid(); 13757 final int callingUid = Binder.getCallingUid(); 13758 final long origId = Binder.clearCallingIdentity(); 13759 int res = broadcastIntentLocked(callerApp, 13760 callerApp != null ? callerApp.info.packageName : null, 13761 intent, resolvedType, resultTo, 13762 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13763 callingPid, callingUid, userId); 13764 Binder.restoreCallingIdentity(origId); 13765 return res; 13766 } 13767 } 13768 13769 int broadcastIntentInPackage(String packageName, int uid, 13770 Intent intent, String resolvedType, IIntentReceiver resultTo, 13771 int resultCode, String resultData, Bundle map, 13772 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13773 synchronized(this) { 13774 intent = verifyBroadcastLocked(intent); 13775 13776 final long origId = Binder.clearCallingIdentity(); 13777 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13778 resultTo, resultCode, resultData, map, requiredPermission, 13779 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13780 Binder.restoreCallingIdentity(origId); 13781 return res; 13782 } 13783 } 13784 13785 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13786 // Refuse possible leaked file descriptors 13787 if (intent != null && intent.hasFileDescriptors() == true) { 13788 throw new IllegalArgumentException("File descriptors passed in Intent"); 13789 } 13790 13791 userId = handleIncomingUser(Binder.getCallingPid(), 13792 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13793 13794 synchronized(this) { 13795 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13796 != PackageManager.PERMISSION_GRANTED) { 13797 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13798 + Binder.getCallingPid() 13799 + ", uid=" + Binder.getCallingUid() 13800 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13801 Slog.w(TAG, msg); 13802 throw new SecurityException(msg); 13803 } 13804 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13805 if (stickies != null) { 13806 ArrayList<Intent> list = stickies.get(intent.getAction()); 13807 if (list != null) { 13808 int N = list.size(); 13809 int i; 13810 for (i=0; i<N; i++) { 13811 if (intent.filterEquals(list.get(i))) { 13812 list.remove(i); 13813 break; 13814 } 13815 } 13816 if (list.size() <= 0) { 13817 stickies.remove(intent.getAction()); 13818 } 13819 } 13820 if (stickies.size() <= 0) { 13821 mStickyBroadcasts.remove(userId); 13822 } 13823 } 13824 } 13825 } 13826 13827 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13828 String resultData, Bundle resultExtras, boolean resultAbort) { 13829 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13830 if (r == null) { 13831 Slog.w(TAG, "finishReceiver called but not found on queue"); 13832 return false; 13833 } 13834 13835 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13836 } 13837 13838 void backgroundServicesFinishedLocked(int userId) { 13839 for (BroadcastQueue queue : mBroadcastQueues) { 13840 queue.backgroundServicesFinishedLocked(userId); 13841 } 13842 } 13843 13844 public void finishReceiver(IBinder who, int resultCode, String resultData, 13845 Bundle resultExtras, boolean resultAbort) { 13846 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13847 13848 // Refuse possible leaked file descriptors 13849 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13850 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13851 } 13852 13853 final long origId = Binder.clearCallingIdentity(); 13854 try { 13855 boolean doNext = false; 13856 BroadcastRecord r; 13857 13858 synchronized(this) { 13859 r = broadcastRecordForReceiverLocked(who); 13860 if (r != null) { 13861 doNext = r.queue.finishReceiverLocked(r, resultCode, 13862 resultData, resultExtras, resultAbort, true); 13863 } 13864 } 13865 13866 if (doNext) { 13867 r.queue.processNextBroadcast(false); 13868 } 13869 trimApplications(); 13870 } finally { 13871 Binder.restoreCallingIdentity(origId); 13872 } 13873 } 13874 13875 // ========================================================= 13876 // INSTRUMENTATION 13877 // ========================================================= 13878 13879 public boolean startInstrumentation(ComponentName className, 13880 String profileFile, int flags, Bundle arguments, 13881 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13882 int userId) { 13883 enforceNotIsolatedCaller("startInstrumentation"); 13884 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13885 userId, false, true, "startInstrumentation", null); 13886 // Refuse possible leaked file descriptors 13887 if (arguments != null && arguments.hasFileDescriptors()) { 13888 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13889 } 13890 13891 synchronized(this) { 13892 InstrumentationInfo ii = null; 13893 ApplicationInfo ai = null; 13894 try { 13895 ii = mContext.getPackageManager().getInstrumentationInfo( 13896 className, STOCK_PM_FLAGS); 13897 ai = AppGlobals.getPackageManager().getApplicationInfo( 13898 ii.targetPackage, STOCK_PM_FLAGS, userId); 13899 } catch (PackageManager.NameNotFoundException e) { 13900 } catch (RemoteException e) { 13901 } 13902 if (ii == null) { 13903 reportStartInstrumentationFailure(watcher, className, 13904 "Unable to find instrumentation info for: " + className); 13905 return false; 13906 } 13907 if (ai == null) { 13908 reportStartInstrumentationFailure(watcher, className, 13909 "Unable to find instrumentation target package: " + ii.targetPackage); 13910 return false; 13911 } 13912 13913 int match = mContext.getPackageManager().checkSignatures( 13914 ii.targetPackage, ii.packageName); 13915 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13916 String msg = "Permission Denial: starting instrumentation " 13917 + className + " from pid=" 13918 + Binder.getCallingPid() 13919 + ", uid=" + Binder.getCallingPid() 13920 + " not allowed because package " + ii.packageName 13921 + " does not have a signature matching the target " 13922 + ii.targetPackage; 13923 reportStartInstrumentationFailure(watcher, className, msg); 13924 throw new SecurityException(msg); 13925 } 13926 13927 final long origId = Binder.clearCallingIdentity(); 13928 // Instrumentation can kill and relaunch even persistent processes 13929 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 13930 "start instr"); 13931 ProcessRecord app = addAppLocked(ai, false); 13932 app.instrumentationClass = className; 13933 app.instrumentationInfo = ai; 13934 app.instrumentationProfileFile = profileFile; 13935 app.instrumentationArguments = arguments; 13936 app.instrumentationWatcher = watcher; 13937 app.instrumentationUiAutomationConnection = uiAutomationConnection; 13938 app.instrumentationResultClass = className; 13939 Binder.restoreCallingIdentity(origId); 13940 } 13941 13942 return true; 13943 } 13944 13945 /** 13946 * Report errors that occur while attempting to start Instrumentation. Always writes the 13947 * error to the logs, but if somebody is watching, send the report there too. This enables 13948 * the "am" command to report errors with more information. 13949 * 13950 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13951 * @param cn The component name of the instrumentation. 13952 * @param report The error report. 13953 */ 13954 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13955 ComponentName cn, String report) { 13956 Slog.w(TAG, report); 13957 try { 13958 if (watcher != null) { 13959 Bundle results = new Bundle(); 13960 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13961 results.putString("Error", report); 13962 watcher.instrumentationStatus(cn, -1, results); 13963 } 13964 } catch (RemoteException e) { 13965 Slog.w(TAG, e); 13966 } 13967 } 13968 13969 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13970 if (app.instrumentationWatcher != null) { 13971 try { 13972 // NOTE: IInstrumentationWatcher *must* be oneway here 13973 app.instrumentationWatcher.instrumentationFinished( 13974 app.instrumentationClass, 13975 resultCode, 13976 results); 13977 } catch (RemoteException e) { 13978 } 13979 } 13980 if (app.instrumentationUiAutomationConnection != null) { 13981 try { 13982 app.instrumentationUiAutomationConnection.shutdown(); 13983 } catch (RemoteException re) { 13984 /* ignore */ 13985 } 13986 // Only a UiAutomation can set this flag and now that 13987 // it is finished we make sure it is reset to its default. 13988 mUserIsMonkey = false; 13989 } 13990 app.instrumentationWatcher = null; 13991 app.instrumentationUiAutomationConnection = null; 13992 app.instrumentationClass = null; 13993 app.instrumentationInfo = null; 13994 app.instrumentationProfileFile = null; 13995 app.instrumentationArguments = null; 13996 13997 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 13998 "finished inst"); 13999 } 14000 14001 public void finishInstrumentation(IApplicationThread target, 14002 int resultCode, Bundle results) { 14003 int userId = UserHandle.getCallingUserId(); 14004 // Refuse possible leaked file descriptors 14005 if (results != null && results.hasFileDescriptors()) { 14006 throw new IllegalArgumentException("File descriptors passed in Intent"); 14007 } 14008 14009 synchronized(this) { 14010 ProcessRecord app = getRecordForAppLocked(target); 14011 if (app == null) { 14012 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14013 return; 14014 } 14015 final long origId = Binder.clearCallingIdentity(); 14016 finishInstrumentationLocked(app, resultCode, results); 14017 Binder.restoreCallingIdentity(origId); 14018 } 14019 } 14020 14021 // ========================================================= 14022 // CONFIGURATION 14023 // ========================================================= 14024 14025 public ConfigurationInfo getDeviceConfigurationInfo() { 14026 ConfigurationInfo config = new ConfigurationInfo(); 14027 synchronized (this) { 14028 config.reqTouchScreen = mConfiguration.touchscreen; 14029 config.reqKeyboardType = mConfiguration.keyboard; 14030 config.reqNavigation = mConfiguration.navigation; 14031 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14032 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14033 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14034 } 14035 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14036 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14037 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14038 } 14039 config.reqGlEsVersion = GL_ES_VERSION; 14040 } 14041 return config; 14042 } 14043 14044 ActivityStack getFocusedStack() { 14045 return mStackSupervisor.getFocusedStack(); 14046 } 14047 14048 public Configuration getConfiguration() { 14049 Configuration ci; 14050 synchronized(this) { 14051 ci = new Configuration(mConfiguration); 14052 } 14053 return ci; 14054 } 14055 14056 public void updatePersistentConfiguration(Configuration values) { 14057 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14058 "updateConfiguration()"); 14059 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14060 "updateConfiguration()"); 14061 if (values == null) { 14062 throw new NullPointerException("Configuration must not be null"); 14063 } 14064 14065 synchronized(this) { 14066 final long origId = Binder.clearCallingIdentity(); 14067 updateConfigurationLocked(values, null, true, false); 14068 Binder.restoreCallingIdentity(origId); 14069 } 14070 } 14071 14072 public void updateConfiguration(Configuration values) { 14073 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14074 "updateConfiguration()"); 14075 14076 synchronized(this) { 14077 if (values == null && mWindowManager != null) { 14078 // sentinel: fetch the current configuration from the window manager 14079 values = mWindowManager.computeNewConfiguration(); 14080 } 14081 14082 if (mWindowManager != null) { 14083 mProcessList.applyDisplaySize(mWindowManager); 14084 } 14085 14086 final long origId = Binder.clearCallingIdentity(); 14087 if (values != null) { 14088 Settings.System.clearConfiguration(values); 14089 } 14090 updateConfigurationLocked(values, null, false, false); 14091 Binder.restoreCallingIdentity(origId); 14092 } 14093 } 14094 14095 /** 14096 * Do either or both things: (1) change the current configuration, and (2) 14097 * make sure the given activity is running with the (now) current 14098 * configuration. Returns true if the activity has been left running, or 14099 * false if <var>starting</var> is being destroyed to match the new 14100 * configuration. 14101 * @param persistent TODO 14102 */ 14103 boolean updateConfigurationLocked(Configuration values, 14104 ActivityRecord starting, boolean persistent, boolean initLocale) { 14105 int changes = 0; 14106 14107 if (values != null) { 14108 Configuration newConfig = new Configuration(mConfiguration); 14109 changes = newConfig.updateFrom(values); 14110 if (changes != 0) { 14111 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14112 Slog.i(TAG, "Updating configuration to: " + values); 14113 } 14114 14115 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14116 14117 if (values.locale != null && !initLocale) { 14118 saveLocaleLocked(values.locale, 14119 !values.locale.equals(mConfiguration.locale), 14120 values.userSetLocale); 14121 } 14122 14123 mConfigurationSeq++; 14124 if (mConfigurationSeq <= 0) { 14125 mConfigurationSeq = 1; 14126 } 14127 newConfig.seq = mConfigurationSeq; 14128 mConfiguration = newConfig; 14129 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14130 14131 final Configuration configCopy = new Configuration(mConfiguration); 14132 14133 // TODO: If our config changes, should we auto dismiss any currently 14134 // showing dialogs? 14135 mShowDialogs = shouldShowDialogs(newConfig); 14136 14137 AttributeCache ac = AttributeCache.instance(); 14138 if (ac != null) { 14139 ac.updateConfiguration(configCopy); 14140 } 14141 14142 // Make sure all resources in our process are updated 14143 // right now, so that anyone who is going to retrieve 14144 // resource values after we return will be sure to get 14145 // the new ones. This is especially important during 14146 // boot, where the first config change needs to guarantee 14147 // all resources have that config before following boot 14148 // code is executed. 14149 mSystemThread.applyConfigurationToResources(configCopy); 14150 14151 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14152 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14153 msg.obj = new Configuration(configCopy); 14154 mHandler.sendMessage(msg); 14155 } 14156 14157 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14158 ProcessRecord app = mLruProcesses.get(i); 14159 try { 14160 if (app.thread != null) { 14161 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14162 + app.processName + " new config " + mConfiguration); 14163 app.thread.scheduleConfigurationChanged(configCopy); 14164 } 14165 } catch (Exception e) { 14166 } 14167 } 14168 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14169 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14170 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14171 | Intent.FLAG_RECEIVER_FOREGROUND); 14172 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14173 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14174 Process.SYSTEM_UID, UserHandle.USER_ALL); 14175 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14176 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14177 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14178 broadcastIntentLocked(null, null, intent, 14179 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14180 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14181 } 14182 } 14183 } 14184 14185 boolean kept = true; 14186 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14187 // mainStack is null during startup. 14188 if (mainStack != null) { 14189 if (changes != 0 && starting == null) { 14190 // If the configuration changed, and the caller is not already 14191 // in the process of starting an activity, then find the top 14192 // activity to check if its configuration needs to change. 14193 starting = mainStack.topRunningActivityLocked(null); 14194 } 14195 14196 if (starting != null) { 14197 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14198 // And we need to make sure at this point that all other activities 14199 // are made visible with the correct configuration. 14200 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14201 } 14202 } 14203 14204 if (values != null && mWindowManager != null) { 14205 mWindowManager.setNewConfiguration(mConfiguration); 14206 } 14207 14208 return kept; 14209 } 14210 14211 /** 14212 * Decide based on the configuration whether we should shouw the ANR, 14213 * crash, etc dialogs. The idea is that if there is no affordnace to 14214 * press the on-screen buttons, we shouldn't show the dialog. 14215 * 14216 * A thought: SystemUI might also want to get told about this, the Power 14217 * dialog / global actions also might want different behaviors. 14218 */ 14219 private static final boolean shouldShowDialogs(Configuration config) { 14220 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14221 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14222 } 14223 14224 /** 14225 * Save the locale. You must be inside a synchronized (this) block. 14226 */ 14227 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14228 if(isDiff) { 14229 SystemProperties.set("user.language", l.getLanguage()); 14230 SystemProperties.set("user.region", l.getCountry()); 14231 } 14232 14233 if(isPersist) { 14234 SystemProperties.set("persist.sys.language", l.getLanguage()); 14235 SystemProperties.set("persist.sys.country", l.getCountry()); 14236 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14237 } 14238 } 14239 14240 @Override 14241 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14242 ActivityRecord srec = ActivityRecord.forToken(token); 14243 return srec != null && srec.task.affinity != null && 14244 srec.task.affinity.equals(destAffinity); 14245 } 14246 14247 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14248 Intent resultData) { 14249 14250 synchronized (this) { 14251 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14252 if (stack != null) { 14253 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14254 } 14255 return false; 14256 } 14257 } 14258 14259 public int getLaunchedFromUid(IBinder activityToken) { 14260 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14261 if (srec == null) { 14262 return -1; 14263 } 14264 return srec.launchedFromUid; 14265 } 14266 14267 public String getLaunchedFromPackage(IBinder activityToken) { 14268 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14269 if (srec == null) { 14270 return null; 14271 } 14272 return srec.launchedFromPackage; 14273 } 14274 14275 // ========================================================= 14276 // LIFETIME MANAGEMENT 14277 // ========================================================= 14278 14279 // Returns which broadcast queue the app is the current [or imminent] receiver 14280 // on, or 'null' if the app is not an active broadcast recipient. 14281 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14282 BroadcastRecord r = app.curReceiver; 14283 if (r != null) { 14284 return r.queue; 14285 } 14286 14287 // It's not the current receiver, but it might be starting up to become one 14288 synchronized (this) { 14289 for (BroadcastQueue queue : mBroadcastQueues) { 14290 r = queue.mPendingBroadcast; 14291 if (r != null && r.curApp == app) { 14292 // found it; report which queue it's in 14293 return queue; 14294 } 14295 } 14296 } 14297 14298 return null; 14299 } 14300 14301 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14302 boolean doingAll, long now) { 14303 if (mAdjSeq == app.adjSeq) { 14304 // This adjustment has already been computed. 14305 return app.curRawAdj; 14306 } 14307 14308 if (app.thread == null) { 14309 app.adjSeq = mAdjSeq; 14310 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14311 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14312 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14313 } 14314 14315 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14316 app.adjSource = null; 14317 app.adjTarget = null; 14318 app.empty = false; 14319 app.cached = false; 14320 14321 final int activitiesSize = app.activities.size(); 14322 14323 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14324 // The max adjustment doesn't allow this app to be anything 14325 // below foreground, so it is not worth doing work for it. 14326 app.adjType = "fixed"; 14327 app.adjSeq = mAdjSeq; 14328 app.curRawAdj = app.maxAdj; 14329 app.foregroundActivities = false; 14330 app.keeping = true; 14331 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14332 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14333 // System process can do UI, and when they do we want to have 14334 // them trim their memory after the user leaves the UI. To 14335 // facilitate this, here we need to determine whether or not it 14336 // is currently showing UI. 14337 app.systemNoUi = true; 14338 if (app == TOP_APP) { 14339 app.systemNoUi = false; 14340 } else if (activitiesSize > 0) { 14341 for (int j = 0; j < activitiesSize; j++) { 14342 final ActivityRecord r = app.activities.get(j); 14343 if (r.visible) { 14344 app.systemNoUi = false; 14345 } 14346 } 14347 } 14348 if (!app.systemNoUi) { 14349 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14350 } 14351 return (app.curAdj=app.maxAdj); 14352 } 14353 14354 app.keeping = false; 14355 app.systemNoUi = false; 14356 14357 // Determine the importance of the process, starting with most 14358 // important to least, and assign an appropriate OOM adjustment. 14359 int adj; 14360 int schedGroup; 14361 int procState; 14362 boolean foregroundActivities = false; 14363 boolean interesting = false; 14364 BroadcastQueue queue; 14365 if (app == TOP_APP) { 14366 // The last app on the list is the foreground app. 14367 adj = ProcessList.FOREGROUND_APP_ADJ; 14368 schedGroup = Process.THREAD_GROUP_DEFAULT; 14369 app.adjType = "top-activity"; 14370 foregroundActivities = true; 14371 interesting = true; 14372 procState = ActivityManager.PROCESS_STATE_TOP; 14373 } else if (app.instrumentationClass != null) { 14374 // Don't want to kill running instrumentation. 14375 adj = ProcessList.FOREGROUND_APP_ADJ; 14376 schedGroup = Process.THREAD_GROUP_DEFAULT; 14377 app.adjType = "instrumentation"; 14378 interesting = true; 14379 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14380 } else if ((queue = isReceivingBroadcast(app)) != null) { 14381 // An app that is currently receiving a broadcast also 14382 // counts as being in the foreground for OOM killer purposes. 14383 // It's placed in a sched group based on the nature of the 14384 // broadcast as reflected by which queue it's active in. 14385 adj = ProcessList.FOREGROUND_APP_ADJ; 14386 schedGroup = (queue == mFgBroadcastQueue) 14387 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14388 app.adjType = "broadcast"; 14389 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14390 } else if (app.executingServices.size() > 0) { 14391 // An app that is currently executing a service callback also 14392 // counts as being in the foreground. 14393 adj = ProcessList.FOREGROUND_APP_ADJ; 14394 schedGroup = app.execServicesFg ? 14395 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14396 app.adjType = "exec-service"; 14397 procState = ActivityManager.PROCESS_STATE_SERVICE; 14398 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14399 } else { 14400 // As far as we know the process is empty. We may change our mind later. 14401 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14402 // At this point we don't actually know the adjustment. Use the cached adj 14403 // value that the caller wants us to. 14404 adj = cachedAdj; 14405 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14406 app.cached = true; 14407 app.empty = true; 14408 app.adjType = "cch-empty"; 14409 } 14410 14411 // Examine all activities if not already foreground. 14412 if (!foregroundActivities && activitiesSize > 0) { 14413 for (int j = 0; j < activitiesSize; j++) { 14414 final ActivityRecord r = app.activities.get(j); 14415 if (r.app != app) { 14416 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14417 + app + "?!?"); 14418 continue; 14419 } 14420 if (r.visible) { 14421 // App has a visible activity; only upgrade adjustment. 14422 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14423 adj = ProcessList.VISIBLE_APP_ADJ; 14424 app.adjType = "visible"; 14425 } 14426 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14427 procState = ActivityManager.PROCESS_STATE_TOP; 14428 } 14429 schedGroup = Process.THREAD_GROUP_DEFAULT; 14430 app.cached = false; 14431 app.empty = false; 14432 foregroundActivities = true; 14433 break; 14434 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14435 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14436 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14437 app.adjType = "pausing"; 14438 } 14439 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14440 procState = ActivityManager.PROCESS_STATE_TOP; 14441 } 14442 schedGroup = Process.THREAD_GROUP_DEFAULT; 14443 app.cached = false; 14444 app.empty = false; 14445 foregroundActivities = true; 14446 } else if (r.state == ActivityState.STOPPING) { 14447 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14448 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14449 app.adjType = "stopping"; 14450 } 14451 // For the process state, we will at this point consider the 14452 // process to be cached. It will be cached either as an activity 14453 // or empty depending on whether the activity is finishing. We do 14454 // this so that we can treat the process as cached for purposes of 14455 // memory trimming (determing current memory level, trim command to 14456 // send to process) since there can be an arbitrary number of stopping 14457 // processes and they should soon all go into the cached state. 14458 if (!r.finishing) { 14459 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14460 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14461 } 14462 } 14463 app.cached = false; 14464 app.empty = false; 14465 foregroundActivities = true; 14466 } else { 14467 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14468 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14469 app.adjType = "cch-act"; 14470 } 14471 } 14472 } 14473 } 14474 14475 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14476 if (app.foregroundServices) { 14477 // The user is aware of this app, so make it visible. 14478 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14479 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14480 app.cached = false; 14481 app.adjType = "fg-service"; 14482 schedGroup = Process.THREAD_GROUP_DEFAULT; 14483 } else if (app.forcingToForeground != null) { 14484 // The user is aware of this app, so make it visible. 14485 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14486 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14487 app.cached = false; 14488 app.adjType = "force-fg"; 14489 app.adjSource = app.forcingToForeground; 14490 schedGroup = Process.THREAD_GROUP_DEFAULT; 14491 } 14492 } 14493 14494 if (app.foregroundServices) { 14495 interesting = true; 14496 } 14497 14498 if (app == mHeavyWeightProcess) { 14499 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14500 // We don't want to kill the current heavy-weight process. 14501 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14502 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14503 app.cached = false; 14504 app.adjType = "heavy"; 14505 } 14506 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14507 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14508 } 14509 } 14510 14511 if (app == mHomeProcess) { 14512 if (adj > ProcessList.HOME_APP_ADJ) { 14513 // This process is hosting what we currently consider to be the 14514 // home app, so we don't want to let it go into the background. 14515 adj = ProcessList.HOME_APP_ADJ; 14516 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14517 app.cached = false; 14518 app.adjType = "home"; 14519 } 14520 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14521 procState = ActivityManager.PROCESS_STATE_HOME; 14522 } 14523 } 14524 14525 if (app == mPreviousProcess && app.activities.size() > 0) { 14526 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14527 // This was the previous process that showed UI to the user. 14528 // We want to try to keep it around more aggressively, to give 14529 // a good experience around switching between two apps. 14530 adj = ProcessList.PREVIOUS_APP_ADJ; 14531 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14532 app.cached = false; 14533 app.adjType = "previous"; 14534 } 14535 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14536 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14537 } 14538 } 14539 14540 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14541 + " reason=" + app.adjType); 14542 14543 // By default, we use the computed adjustment. It may be changed if 14544 // there are applications dependent on our services or providers, but 14545 // this gives us a baseline and makes sure we don't get into an 14546 // infinite recursion. 14547 app.adjSeq = mAdjSeq; 14548 app.curRawAdj = adj; 14549 app.hasStartedServices = false; 14550 14551 if (mBackupTarget != null && app == mBackupTarget.app) { 14552 // If possible we want to avoid killing apps while they're being backed up 14553 if (adj > ProcessList.BACKUP_APP_ADJ) { 14554 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14555 adj = ProcessList.BACKUP_APP_ADJ; 14556 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14557 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14558 } 14559 app.adjType = "backup"; 14560 app.cached = false; 14561 } 14562 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14563 procState = ActivityManager.PROCESS_STATE_BACKUP; 14564 } 14565 } 14566 14567 boolean mayBeTop = false; 14568 14569 for (int is = app.services.size()-1; 14570 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14571 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14572 || procState > ActivityManager.PROCESS_STATE_TOP); 14573 is--) { 14574 ServiceRecord s = app.services.valueAt(is); 14575 if (s.startRequested) { 14576 app.hasStartedServices = true; 14577 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14578 procState = ActivityManager.PROCESS_STATE_SERVICE; 14579 } 14580 if (app.hasShownUi && app != mHomeProcess) { 14581 // If this process has shown some UI, let it immediately 14582 // go to the LRU list because it may be pretty heavy with 14583 // UI stuff. We'll tag it with a label just to help 14584 // debug and understand what is going on. 14585 if (adj > ProcessList.SERVICE_ADJ) { 14586 app.adjType = "cch-started-ui-services"; 14587 } 14588 } else { 14589 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14590 // This service has seen some activity within 14591 // recent memory, so we will keep its process ahead 14592 // of the background processes. 14593 if (adj > ProcessList.SERVICE_ADJ) { 14594 adj = ProcessList.SERVICE_ADJ; 14595 app.adjType = "started-services"; 14596 app.cached = false; 14597 } 14598 } 14599 // If we have let the service slide into the background 14600 // state, still have some text describing what it is doing 14601 // even though the service no longer has an impact. 14602 if (adj > ProcessList.SERVICE_ADJ) { 14603 app.adjType = "cch-started-services"; 14604 } 14605 } 14606 // Don't kill this process because it is doing work; it 14607 // has said it is doing work. 14608 app.keeping = true; 14609 } 14610 for (int conni = s.connections.size()-1; 14611 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14612 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14613 || procState > ActivityManager.PROCESS_STATE_TOP); 14614 conni--) { 14615 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14616 for (int i = 0; 14617 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14618 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14619 || procState > ActivityManager.PROCESS_STATE_TOP); 14620 i++) { 14621 // XXX should compute this based on the max of 14622 // all connected clients. 14623 ConnectionRecord cr = clist.get(i); 14624 if (cr.binding.client == app) { 14625 // Binding to ourself is not interesting. 14626 continue; 14627 } 14628 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14629 ProcessRecord client = cr.binding.client; 14630 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14631 TOP_APP, doingAll, now); 14632 int clientProcState = client.curProcState; 14633 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14634 // If the other app is cached for any reason, for purposes here 14635 // we are going to consider it empty. The specific cached state 14636 // doesn't propagate except under certain conditions. 14637 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14638 } 14639 String adjType = null; 14640 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14641 // Not doing bind OOM management, so treat 14642 // this guy more like a started service. 14643 if (app.hasShownUi && app != mHomeProcess) { 14644 // If this process has shown some UI, let it immediately 14645 // go to the LRU list because it may be pretty heavy with 14646 // UI stuff. We'll tag it with a label just to help 14647 // debug and understand what is going on. 14648 if (adj > clientAdj) { 14649 adjType = "cch-bound-ui-services"; 14650 } 14651 app.cached = false; 14652 clientAdj = adj; 14653 clientProcState = procState; 14654 } else { 14655 if (now >= (s.lastActivity 14656 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14657 // This service has not seen activity within 14658 // recent memory, so allow it to drop to the 14659 // LRU list if there is no other reason to keep 14660 // it around. We'll also tag it with a label just 14661 // to help debug and undertand what is going on. 14662 if (adj > clientAdj) { 14663 adjType = "cch-bound-services"; 14664 } 14665 clientAdj = adj; 14666 } 14667 } 14668 } 14669 if (adj > clientAdj) { 14670 // If this process has recently shown UI, and 14671 // the process that is binding to it is less 14672 // important than being visible, then we don't 14673 // care about the binding as much as we care 14674 // about letting this process get into the LRU 14675 // list to be killed and restarted if needed for 14676 // memory. 14677 if (app.hasShownUi && app != mHomeProcess 14678 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14679 adjType = "cch-bound-ui-services"; 14680 } else { 14681 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14682 |Context.BIND_IMPORTANT)) != 0) { 14683 adj = clientAdj; 14684 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14685 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14686 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14687 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14688 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14689 adj = clientAdj; 14690 } else { 14691 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14692 adj = ProcessList.VISIBLE_APP_ADJ; 14693 } 14694 } 14695 if (!client.cached) { 14696 app.cached = false; 14697 } 14698 if (client.keeping) { 14699 app.keeping = true; 14700 } 14701 adjType = "service"; 14702 } 14703 } 14704 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14705 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14706 schedGroup = Process.THREAD_GROUP_DEFAULT; 14707 } 14708 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14709 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14710 // Special handling of clients who are in the top state. 14711 // We *may* want to consider this process to be in the 14712 // top state as well, but only if there is not another 14713 // reason for it to be running. Being on the top is a 14714 // special state, meaning you are specifically running 14715 // for the current top app. If the process is already 14716 // running in the background for some other reason, it 14717 // is more important to continue considering it to be 14718 // in the background state. 14719 mayBeTop = true; 14720 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14721 } else { 14722 // Special handling for above-top states (persistent 14723 // processes). These should not bring the current process 14724 // into the top state, since they are not on top. Instead 14725 // give them the best state after that. 14726 clientProcState = 14727 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14728 } 14729 } 14730 } else { 14731 if (clientProcState < 14732 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14733 clientProcState = 14734 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14735 } 14736 } 14737 if (procState > clientProcState) { 14738 procState = clientProcState; 14739 } 14740 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14741 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14742 app.pendingUiClean = true; 14743 } 14744 if (adjType != null) { 14745 app.adjType = adjType; 14746 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14747 .REASON_SERVICE_IN_USE; 14748 app.adjSource = cr.binding.client; 14749 app.adjSourceOom = clientAdj; 14750 app.adjTarget = s.name; 14751 } 14752 } 14753 final ActivityRecord a = cr.activity; 14754 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14755 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14756 (a.visible || a.state == ActivityState.RESUMED 14757 || a.state == ActivityState.PAUSING)) { 14758 adj = ProcessList.FOREGROUND_APP_ADJ; 14759 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14760 schedGroup = Process.THREAD_GROUP_DEFAULT; 14761 } 14762 app.cached = false; 14763 app.adjType = "service"; 14764 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14765 .REASON_SERVICE_IN_USE; 14766 app.adjSource = a; 14767 app.adjSourceOom = adj; 14768 app.adjTarget = s.name; 14769 } 14770 } 14771 } 14772 } 14773 } 14774 14775 for (int provi = app.pubProviders.size()-1; 14776 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14777 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14778 || procState > ActivityManager.PROCESS_STATE_TOP); 14779 provi--) { 14780 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14781 for (int i = cpr.connections.size()-1; 14782 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14783 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14784 || procState > ActivityManager.PROCESS_STATE_TOP); 14785 i--) { 14786 ContentProviderConnection conn = cpr.connections.get(i); 14787 ProcessRecord client = conn.client; 14788 if (client == app) { 14789 // Being our own client is not interesting. 14790 continue; 14791 } 14792 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14793 int clientProcState = client.curProcState; 14794 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14795 // If the other app is cached for any reason, for purposes here 14796 // we are going to consider it empty. 14797 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14798 } 14799 if (adj > clientAdj) { 14800 if (app.hasShownUi && app != mHomeProcess 14801 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14802 app.adjType = "cch-ui-provider"; 14803 } else { 14804 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14805 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14806 app.adjType = "provider"; 14807 } 14808 app.cached &= client.cached; 14809 app.keeping |= client.keeping; 14810 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14811 .REASON_PROVIDER_IN_USE; 14812 app.adjSource = client; 14813 app.adjSourceOom = clientAdj; 14814 app.adjTarget = cpr.name; 14815 } 14816 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14817 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14818 // Special handling of clients who are in the top state. 14819 // We *may* want to consider this process to be in the 14820 // top state as well, but only if there is not another 14821 // reason for it to be running. Being on the top is a 14822 // special state, meaning you are specifically running 14823 // for the current top app. If the process is already 14824 // running in the background for some other reason, it 14825 // is more important to continue considering it to be 14826 // in the background state. 14827 mayBeTop = true; 14828 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14829 } else { 14830 // Special handling for above-top states (persistent 14831 // processes). These should not bring the current process 14832 // into the top state, since they are not on top. Instead 14833 // give them the best state after that. 14834 clientProcState = 14835 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14836 } 14837 } 14838 if (procState > clientProcState) { 14839 procState = clientProcState; 14840 } 14841 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14842 schedGroup = Process.THREAD_GROUP_DEFAULT; 14843 } 14844 } 14845 // If the provider has external (non-framework) process 14846 // dependencies, ensure that its adjustment is at least 14847 // FOREGROUND_APP_ADJ. 14848 if (cpr.hasExternalProcessHandles()) { 14849 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14850 adj = ProcessList.FOREGROUND_APP_ADJ; 14851 schedGroup = Process.THREAD_GROUP_DEFAULT; 14852 app.cached = false; 14853 app.keeping = true; 14854 app.adjType = "provider"; 14855 app.adjTarget = cpr.name; 14856 } 14857 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14858 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14859 } 14860 } 14861 } 14862 14863 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14864 // A client of one of our services or providers is in the top state. We 14865 // *may* want to be in the top state, but not if we are already running in 14866 // the background for some other reason. For the decision here, we are going 14867 // to pick out a few specific states that we want to remain in when a client 14868 // is top (states that tend to be longer-term) and otherwise allow it to go 14869 // to the top state. 14870 switch (procState) { 14871 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14872 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14873 case ActivityManager.PROCESS_STATE_SERVICE: 14874 // These all are longer-term states, so pull them up to the top 14875 // of the background states, but not all the way to the top state. 14876 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14877 break; 14878 default: 14879 // Otherwise, top is a better choice, so take it. 14880 procState = ActivityManager.PROCESS_STATE_TOP; 14881 break; 14882 } 14883 } 14884 14885 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14886 // This is a cached process, but with client activities. Mark it so. 14887 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14888 app.adjType = "cch-client-act"; 14889 } 14890 14891 if (adj == ProcessList.SERVICE_ADJ) { 14892 if (doingAll) { 14893 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14894 mNewNumServiceProcs++; 14895 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14896 if (!app.serviceb) { 14897 // This service isn't far enough down on the LRU list to 14898 // normally be a B service, but if we are low on RAM and it 14899 // is large we want to force it down since we would prefer to 14900 // keep launcher over it. 14901 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 14902 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 14903 app.serviceHighRam = true; 14904 app.serviceb = true; 14905 //Slog.i(TAG, "ADJ " + app + " high ram!"); 14906 } else { 14907 mNewNumAServiceProcs++; 14908 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 14909 } 14910 } else { 14911 app.serviceHighRam = false; 14912 } 14913 } 14914 if (app.serviceb) { 14915 adj = ProcessList.SERVICE_B_ADJ; 14916 } 14917 } 14918 14919 app.curRawAdj = adj; 14920 14921 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14922 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14923 if (adj > app.maxAdj) { 14924 adj = app.maxAdj; 14925 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14926 schedGroup = Process.THREAD_GROUP_DEFAULT; 14927 } 14928 } 14929 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 14930 app.keeping = true; 14931 } 14932 14933 // Do final modification to adj. Everything we do between here and applying 14934 // the final setAdj must be done in this function, because we will also use 14935 // it when computing the final cached adj later. Note that we don't need to 14936 // worry about this for max adj above, since max adj will always be used to 14937 // keep it out of the cached vaues. 14938 adj = app.modifyRawOomAdj(adj); 14939 14940 app.curProcState = procState; 14941 14942 int importance = app.memImportance; 14943 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14944 app.curAdj = adj; 14945 app.curSchedGroup = schedGroup; 14946 if (!interesting) { 14947 // For this reporting, if there is not something explicitly 14948 // interesting in this process then we will push it to the 14949 // background importance. 14950 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14951 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 14952 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14953 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14954 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14955 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14956 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14957 } else if (adj >= ProcessList.SERVICE_ADJ) { 14958 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14959 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14960 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14961 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14962 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14963 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14964 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14965 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14966 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14967 } else { 14968 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14969 } 14970 } 14971 14972 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14973 if (foregroundActivities != app.foregroundActivities) { 14974 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14975 } 14976 if (changes != 0) { 14977 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14978 app.memImportance = importance; 14979 app.foregroundActivities = foregroundActivities; 14980 int i = mPendingProcessChanges.size()-1; 14981 ProcessChangeItem item = null; 14982 while (i >= 0) { 14983 item = mPendingProcessChanges.get(i); 14984 if (item.pid == app.pid) { 14985 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14986 break; 14987 } 14988 i--; 14989 } 14990 if (i < 0) { 14991 // No existing item in pending changes; need a new one. 14992 final int NA = mAvailProcessChanges.size(); 14993 if (NA > 0) { 14994 item = mAvailProcessChanges.remove(NA-1); 14995 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14996 } else { 14997 item = new ProcessChangeItem(); 14998 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14999 } 15000 item.changes = 0; 15001 item.pid = app.pid; 15002 item.uid = app.info.uid; 15003 if (mPendingProcessChanges.size() == 0) { 15004 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15005 "*** Enqueueing dispatch processes changed!"); 15006 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15007 } 15008 mPendingProcessChanges.add(item); 15009 } 15010 item.changes |= changes; 15011 item.importance = importance; 15012 item.foregroundActivities = foregroundActivities; 15013 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15014 + Integer.toHexString(System.identityHashCode(item)) 15015 + " " + app.toShortString() + ": changes=" + item.changes 15016 + " importance=" + item.importance 15017 + " foreground=" + item.foregroundActivities 15018 + " type=" + app.adjType + " source=" + app.adjSource 15019 + " target=" + app.adjTarget); 15020 } 15021 15022 return app.curRawAdj; 15023 } 15024 15025 /** 15026 * Schedule PSS collection of a process. 15027 */ 15028 void requestPssLocked(ProcessRecord proc, int procState) { 15029 if (mPendingPssProcesses.contains(proc)) { 15030 return; 15031 } 15032 if (mPendingPssProcesses.size() == 0) { 15033 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15034 } 15035 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15036 proc.pssProcState = procState; 15037 mPendingPssProcesses.add(proc); 15038 } 15039 15040 /** 15041 * Schedule PSS collection of all processes. 15042 */ 15043 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15044 if (!always) { 15045 if (now < (mLastFullPssTime + 15046 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15047 return; 15048 } 15049 } 15050 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15051 mLastFullPssTime = now; 15052 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15053 mPendingPssProcesses.clear(); 15054 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15055 ProcessRecord app = mLruProcesses.get(i); 15056 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15057 app.pssProcState = app.setProcState; 15058 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15059 mSleeping, now); 15060 mPendingPssProcesses.add(app); 15061 } 15062 } 15063 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15064 } 15065 15066 /** 15067 * Ask a given process to GC right now. 15068 */ 15069 final void performAppGcLocked(ProcessRecord app) { 15070 try { 15071 app.lastRequestedGc = SystemClock.uptimeMillis(); 15072 if (app.thread != null) { 15073 if (app.reportLowMemory) { 15074 app.reportLowMemory = false; 15075 app.thread.scheduleLowMemory(); 15076 } else { 15077 app.thread.processInBackground(); 15078 } 15079 } 15080 } catch (Exception e) { 15081 // whatever. 15082 } 15083 } 15084 15085 /** 15086 * Returns true if things are idle enough to perform GCs. 15087 */ 15088 private final boolean canGcNowLocked() { 15089 boolean processingBroadcasts = false; 15090 for (BroadcastQueue q : mBroadcastQueues) { 15091 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15092 processingBroadcasts = true; 15093 } 15094 } 15095 return !processingBroadcasts 15096 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 15097 } 15098 15099 /** 15100 * Perform GCs on all processes that are waiting for it, but only 15101 * if things are idle. 15102 */ 15103 final void performAppGcsLocked() { 15104 final int N = mProcessesToGc.size(); 15105 if (N <= 0) { 15106 return; 15107 } 15108 if (canGcNowLocked()) { 15109 while (mProcessesToGc.size() > 0) { 15110 ProcessRecord proc = mProcessesToGc.remove(0); 15111 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15112 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15113 <= SystemClock.uptimeMillis()) { 15114 // To avoid spamming the system, we will GC processes one 15115 // at a time, waiting a few seconds between each. 15116 performAppGcLocked(proc); 15117 scheduleAppGcsLocked(); 15118 return; 15119 } else { 15120 // It hasn't been long enough since we last GCed this 15121 // process... put it in the list to wait for its time. 15122 addProcessToGcListLocked(proc); 15123 break; 15124 } 15125 } 15126 } 15127 15128 scheduleAppGcsLocked(); 15129 } 15130 } 15131 15132 /** 15133 * If all looks good, perform GCs on all processes waiting for them. 15134 */ 15135 final void performAppGcsIfAppropriateLocked() { 15136 if (canGcNowLocked()) { 15137 performAppGcsLocked(); 15138 return; 15139 } 15140 // Still not idle, wait some more. 15141 scheduleAppGcsLocked(); 15142 } 15143 15144 /** 15145 * Schedule the execution of all pending app GCs. 15146 */ 15147 final void scheduleAppGcsLocked() { 15148 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15149 15150 if (mProcessesToGc.size() > 0) { 15151 // Schedule a GC for the time to the next process. 15152 ProcessRecord proc = mProcessesToGc.get(0); 15153 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15154 15155 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15156 long now = SystemClock.uptimeMillis(); 15157 if (when < (now+GC_TIMEOUT)) { 15158 when = now + GC_TIMEOUT; 15159 } 15160 mHandler.sendMessageAtTime(msg, when); 15161 } 15162 } 15163 15164 /** 15165 * Add a process to the array of processes waiting to be GCed. Keeps the 15166 * list in sorted order by the last GC time. The process can't already be 15167 * on the list. 15168 */ 15169 final void addProcessToGcListLocked(ProcessRecord proc) { 15170 boolean added = false; 15171 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15172 if (mProcessesToGc.get(i).lastRequestedGc < 15173 proc.lastRequestedGc) { 15174 added = true; 15175 mProcessesToGc.add(i+1, proc); 15176 break; 15177 } 15178 } 15179 if (!added) { 15180 mProcessesToGc.add(0, proc); 15181 } 15182 } 15183 15184 /** 15185 * Set up to ask a process to GC itself. This will either do it 15186 * immediately, or put it on the list of processes to gc the next 15187 * time things are idle. 15188 */ 15189 final void scheduleAppGcLocked(ProcessRecord app) { 15190 long now = SystemClock.uptimeMillis(); 15191 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15192 return; 15193 } 15194 if (!mProcessesToGc.contains(app)) { 15195 addProcessToGcListLocked(app); 15196 scheduleAppGcsLocked(); 15197 } 15198 } 15199 15200 final void checkExcessivePowerUsageLocked(boolean doKills) { 15201 updateCpuStatsNow(); 15202 15203 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15204 boolean doWakeKills = doKills; 15205 boolean doCpuKills = doKills; 15206 if (mLastPowerCheckRealtime == 0) { 15207 doWakeKills = false; 15208 } 15209 if (mLastPowerCheckUptime == 0) { 15210 doCpuKills = false; 15211 } 15212 if (stats.isScreenOn()) { 15213 doWakeKills = false; 15214 } 15215 final long curRealtime = SystemClock.elapsedRealtime(); 15216 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15217 final long curUptime = SystemClock.uptimeMillis(); 15218 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15219 mLastPowerCheckRealtime = curRealtime; 15220 mLastPowerCheckUptime = curUptime; 15221 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15222 doWakeKills = false; 15223 } 15224 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15225 doCpuKills = false; 15226 } 15227 int i = mLruProcesses.size(); 15228 while (i > 0) { 15229 i--; 15230 ProcessRecord app = mLruProcesses.get(i); 15231 if (!app.keeping) { 15232 long wtime; 15233 synchronized (stats) { 15234 wtime = stats.getProcessWakeTime(app.info.uid, 15235 app.pid, curRealtime); 15236 } 15237 long wtimeUsed = wtime - app.lastWakeTime; 15238 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15239 if (DEBUG_POWER) { 15240 StringBuilder sb = new StringBuilder(128); 15241 sb.append("Wake for "); 15242 app.toShortString(sb); 15243 sb.append(": over "); 15244 TimeUtils.formatDuration(realtimeSince, sb); 15245 sb.append(" used "); 15246 TimeUtils.formatDuration(wtimeUsed, sb); 15247 sb.append(" ("); 15248 sb.append((wtimeUsed*100)/realtimeSince); 15249 sb.append("%)"); 15250 Slog.i(TAG, sb.toString()); 15251 sb.setLength(0); 15252 sb.append("CPU for "); 15253 app.toShortString(sb); 15254 sb.append(": over "); 15255 TimeUtils.formatDuration(uptimeSince, sb); 15256 sb.append(" used "); 15257 TimeUtils.formatDuration(cputimeUsed, sb); 15258 sb.append(" ("); 15259 sb.append((cputimeUsed*100)/uptimeSince); 15260 sb.append("%)"); 15261 Slog.i(TAG, sb.toString()); 15262 } 15263 // If a process has held a wake lock for more 15264 // than 50% of the time during this period, 15265 // that sounds bad. Kill! 15266 if (doWakeKills && realtimeSince > 0 15267 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15268 synchronized (stats) { 15269 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15270 realtimeSince, wtimeUsed); 15271 } 15272 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15273 + " during " + realtimeSince); 15274 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15275 } else if (doCpuKills && uptimeSince > 0 15276 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15277 synchronized (stats) { 15278 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15279 uptimeSince, cputimeUsed); 15280 } 15281 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15282 + " during " + uptimeSince); 15283 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15284 } else { 15285 app.lastWakeTime = wtime; 15286 app.lastCpuTime = app.curCpuTime; 15287 } 15288 } 15289 } 15290 } 15291 15292 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15293 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15294 boolean success = true; 15295 15296 if (app.curRawAdj != app.setRawAdj) { 15297 if (wasKeeping && !app.keeping) { 15298 // This app is no longer something we want to keep. Note 15299 // its current wake lock time to later know to kill it if 15300 // it is not behaving well. 15301 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15302 synchronized (stats) { 15303 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15304 app.pid, SystemClock.elapsedRealtime()); 15305 } 15306 app.lastCpuTime = app.curCpuTime; 15307 } 15308 15309 app.setRawAdj = app.curRawAdj; 15310 } 15311 15312 if (app.curAdj != app.setAdj) { 15313 ProcessList.setOomAdj(app.pid, app.curAdj); 15314 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15315 TAG, "Set " + app.pid + " " + app.processName + 15316 " adj " + app.curAdj + ": " + app.adjType); 15317 app.setAdj = app.curAdj; 15318 } 15319 15320 if (app.setSchedGroup != app.curSchedGroup) { 15321 app.setSchedGroup = app.curSchedGroup; 15322 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15323 "Setting process group of " + app.processName 15324 + " to " + app.curSchedGroup); 15325 if (app.waitingToKill != null && 15326 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15327 killUnneededProcessLocked(app, app.waitingToKill); 15328 success = false; 15329 } else { 15330 if (true) { 15331 long oldId = Binder.clearCallingIdentity(); 15332 try { 15333 Process.setProcessGroup(app.pid, app.curSchedGroup); 15334 } catch (Exception e) { 15335 Slog.w(TAG, "Failed setting process group of " + app.pid 15336 + " to " + app.curSchedGroup); 15337 e.printStackTrace(); 15338 } finally { 15339 Binder.restoreCallingIdentity(oldId); 15340 } 15341 } else { 15342 if (app.thread != null) { 15343 try { 15344 app.thread.setSchedulingGroup(app.curSchedGroup); 15345 } catch (RemoteException e) { 15346 } 15347 } 15348 } 15349 Process.setSwappiness(app.pid, 15350 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15351 } 15352 } 15353 if (app.repProcState != app.curProcState) { 15354 app.repProcState = app.curProcState; 15355 if (!reportingProcessState && app.thread != null) { 15356 try { 15357 if (false) { 15358 //RuntimeException h = new RuntimeException("here"); 15359 Slog.i(TAG, "Sending new process state " + app.repProcState 15360 + " to " + app /*, h*/); 15361 } 15362 app.thread.setProcessState(app.repProcState); 15363 } catch (RemoteException e) { 15364 } 15365 } 15366 } 15367 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15368 app.setProcState)) { 15369 app.lastStateTime = now; 15370 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15371 mSleeping, now); 15372 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15373 + ProcessList.makeProcStateString(app.setProcState) + " to " 15374 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15375 + (app.nextPssTime-now) + ": " + app); 15376 } else { 15377 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15378 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15379 requestPssLocked(app, app.setProcState); 15380 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15381 mSleeping, now); 15382 } else if (false && DEBUG_PSS) { 15383 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15384 } 15385 } 15386 if (app.setProcState != app.curProcState) { 15387 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15388 "Proc state change of " + app.processName 15389 + " to " + app.curProcState); 15390 app.setProcState = app.curProcState; 15391 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15392 app.notCachedSinceIdle = false; 15393 } 15394 if (!doingAll) { 15395 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15396 } else { 15397 app.procStateChanged = true; 15398 } 15399 } 15400 return success; 15401 } 15402 15403 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15404 if (proc.thread != null && proc.baseProcessTracker != null) { 15405 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15406 } 15407 } 15408 15409 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15410 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15411 if (app.thread == null) { 15412 return false; 15413 } 15414 15415 final boolean wasKeeping = app.keeping; 15416 15417 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15418 15419 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15420 reportingProcessState, now); 15421 } 15422 15423 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15424 boolean oomAdj) { 15425 if (isForeground != proc.foregroundServices) { 15426 proc.foregroundServices = isForeground; 15427 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15428 proc.info.uid); 15429 if (isForeground) { 15430 if (curProcs == null) { 15431 curProcs = new ArrayList<ProcessRecord>(); 15432 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15433 } 15434 if (!curProcs.contains(proc)) { 15435 curProcs.add(proc); 15436 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15437 proc.info.packageName, proc.info.uid); 15438 } 15439 } else { 15440 if (curProcs != null) { 15441 if (curProcs.remove(proc)) { 15442 mBatteryStatsService.noteEvent( 15443 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15444 proc.info.packageName, proc.info.uid); 15445 if (curProcs.size() <= 0) { 15446 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15447 } 15448 } 15449 } 15450 } 15451 if (oomAdj) { 15452 updateOomAdjLocked(); 15453 } 15454 } 15455 } 15456 15457 private final ActivityRecord resumedAppLocked() { 15458 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15459 String pkg; 15460 int uid; 15461 if (act != null) { 15462 pkg = act.packageName; 15463 uid = act.info.applicationInfo.uid; 15464 } else { 15465 pkg = null; 15466 uid = -1; 15467 } 15468 // Has the UID or resumed package name changed? 15469 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15470 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15471 if (mCurResumedPackage != null) { 15472 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15473 mCurResumedPackage, mCurResumedUid); 15474 } 15475 mCurResumedPackage = pkg; 15476 mCurResumedUid = uid; 15477 if (mCurResumedPackage != null) { 15478 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15479 mCurResumedPackage, mCurResumedUid); 15480 } 15481 } 15482 return act; 15483 } 15484 15485 final boolean updateOomAdjLocked(ProcessRecord app) { 15486 return updateOomAdjLocked(app, false); 15487 } 15488 15489 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15490 final ActivityRecord TOP_ACT = resumedAppLocked(); 15491 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15492 final boolean wasCached = app.cached; 15493 15494 mAdjSeq++; 15495 15496 // This is the desired cached adjusment we want to tell it to use. 15497 // If our app is currently cached, we know it, and that is it. Otherwise, 15498 // we don't know it yet, and it needs to now be cached we will then 15499 // need to do a complete oom adj. 15500 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15501 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15502 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15503 SystemClock.uptimeMillis()); 15504 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15505 // Changed to/from cached state, so apps after it in the LRU 15506 // list may also be changed. 15507 updateOomAdjLocked(); 15508 } 15509 return success; 15510 } 15511 15512 final void updateOomAdjLocked() { 15513 final ActivityRecord TOP_ACT = resumedAppLocked(); 15514 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15515 final long now = SystemClock.uptimeMillis(); 15516 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15517 final int N = mLruProcesses.size(); 15518 15519 if (false) { 15520 RuntimeException e = new RuntimeException(); 15521 e.fillInStackTrace(); 15522 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15523 } 15524 15525 mAdjSeq++; 15526 mNewNumServiceProcs = 0; 15527 mNewNumAServiceProcs = 0; 15528 15529 final int emptyProcessLimit; 15530 final int cachedProcessLimit; 15531 if (mProcessLimit <= 0) { 15532 emptyProcessLimit = cachedProcessLimit = 0; 15533 } else if (mProcessLimit == 1) { 15534 emptyProcessLimit = 1; 15535 cachedProcessLimit = 0; 15536 } else { 15537 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15538 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15539 } 15540 15541 // Let's determine how many processes we have running vs. 15542 // how many slots we have for background processes; we may want 15543 // to put multiple processes in a slot of there are enough of 15544 // them. 15545 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15546 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15547 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15548 if (numEmptyProcs > cachedProcessLimit) { 15549 // If there are more empty processes than our limit on cached 15550 // processes, then use the cached process limit for the factor. 15551 // This ensures that the really old empty processes get pushed 15552 // down to the bottom, so if we are running low on memory we will 15553 // have a better chance at keeping around more cached processes 15554 // instead of a gazillion empty processes. 15555 numEmptyProcs = cachedProcessLimit; 15556 } 15557 int emptyFactor = numEmptyProcs/numSlots; 15558 if (emptyFactor < 1) emptyFactor = 1; 15559 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15560 if (cachedFactor < 1) cachedFactor = 1; 15561 int stepCached = 0; 15562 int stepEmpty = 0; 15563 int numCached = 0; 15564 int numEmpty = 0; 15565 int numTrimming = 0; 15566 15567 mNumNonCachedProcs = 0; 15568 mNumCachedHiddenProcs = 0; 15569 15570 // First update the OOM adjustment for each of the 15571 // application processes based on their current state. 15572 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15573 int nextCachedAdj = curCachedAdj+1; 15574 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15575 int nextEmptyAdj = curEmptyAdj+2; 15576 for (int i=N-1; i>=0; i--) { 15577 ProcessRecord app = mLruProcesses.get(i); 15578 if (!app.killedByAm && app.thread != null) { 15579 app.procStateChanged = false; 15580 final boolean wasKeeping = app.keeping; 15581 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15582 15583 // If we haven't yet assigned the final cached adj 15584 // to the process, do that now. 15585 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15586 switch (app.curProcState) { 15587 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15588 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15589 // This process is a cached process holding activities... 15590 // assign it the next cached value for that type, and then 15591 // step that cached level. 15592 app.curRawAdj = curCachedAdj; 15593 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15594 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15595 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15596 + ")"); 15597 if (curCachedAdj != nextCachedAdj) { 15598 stepCached++; 15599 if (stepCached >= cachedFactor) { 15600 stepCached = 0; 15601 curCachedAdj = nextCachedAdj; 15602 nextCachedAdj += 2; 15603 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15604 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15605 } 15606 } 15607 } 15608 break; 15609 default: 15610 // For everything else, assign next empty cached process 15611 // level and bump that up. Note that this means that 15612 // long-running services that have dropped down to the 15613 // cached level will be treated as empty (since their process 15614 // state is still as a service), which is what we want. 15615 app.curRawAdj = curEmptyAdj; 15616 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15617 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15618 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15619 + ")"); 15620 if (curEmptyAdj != nextEmptyAdj) { 15621 stepEmpty++; 15622 if (stepEmpty >= emptyFactor) { 15623 stepEmpty = 0; 15624 curEmptyAdj = nextEmptyAdj; 15625 nextEmptyAdj += 2; 15626 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15627 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15628 } 15629 } 15630 } 15631 break; 15632 } 15633 } 15634 15635 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15636 15637 // Count the number of process types. 15638 switch (app.curProcState) { 15639 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15640 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15641 mNumCachedHiddenProcs++; 15642 numCached++; 15643 if (numCached > cachedProcessLimit) { 15644 killUnneededProcessLocked(app, "cached #" + numCached); 15645 } 15646 break; 15647 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15648 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15649 && app.lastActivityTime < oldTime) { 15650 killUnneededProcessLocked(app, "empty for " 15651 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15652 / 1000) + "s"); 15653 } else { 15654 numEmpty++; 15655 if (numEmpty > emptyProcessLimit) { 15656 killUnneededProcessLocked(app, "empty #" + numEmpty); 15657 } 15658 } 15659 break; 15660 default: 15661 mNumNonCachedProcs++; 15662 break; 15663 } 15664 15665 if (app.isolated && app.services.size() <= 0) { 15666 // If this is an isolated process, and there are no 15667 // services running in it, then the process is no longer 15668 // needed. We agressively kill these because we can by 15669 // definition not re-use the same process again, and it is 15670 // good to avoid having whatever code was running in them 15671 // left sitting around after no longer needed. 15672 killUnneededProcessLocked(app, "isolated not needed"); 15673 } 15674 15675 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15676 && !app.killedByAm) { 15677 numTrimming++; 15678 } 15679 } 15680 } 15681 15682 mNumServiceProcs = mNewNumServiceProcs; 15683 15684 // Now determine the memory trimming level of background processes. 15685 // Unfortunately we need to start at the back of the list to do this 15686 // properly. We only do this if the number of background apps we 15687 // are managing to keep around is less than half the maximum we desire; 15688 // if we are keeping a good number around, we'll let them use whatever 15689 // memory they want. 15690 final int numCachedAndEmpty = numCached + numEmpty; 15691 int memFactor; 15692 if (numCached <= ProcessList.TRIM_CACHED_APPS 15693 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15694 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15695 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15696 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15697 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15698 } else { 15699 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15700 } 15701 } else { 15702 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15703 } 15704 // We always allow the memory level to go up (better). We only allow it to go 15705 // down if we are in a state where that is allowed, *and* the total number of processes 15706 // has gone down since last time. 15707 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15708 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15709 + " last=" + mLastNumProcesses); 15710 if (memFactor > mLastMemoryLevel) { 15711 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15712 memFactor = mLastMemoryLevel; 15713 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15714 } 15715 } 15716 mLastMemoryLevel = memFactor; 15717 mLastNumProcesses = mLruProcesses.size(); 15718 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15719 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15720 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15721 if (mLowRamStartTime == 0) { 15722 mLowRamStartTime = now; 15723 } 15724 int step = 0; 15725 int fgTrimLevel; 15726 switch (memFactor) { 15727 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15728 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15729 break; 15730 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15731 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15732 break; 15733 default: 15734 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15735 break; 15736 } 15737 int factor = numTrimming/3; 15738 int minFactor = 2; 15739 if (mHomeProcess != null) minFactor++; 15740 if (mPreviousProcess != null) minFactor++; 15741 if (factor < minFactor) factor = minFactor; 15742 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15743 for (int i=N-1; i>=0; i--) { 15744 ProcessRecord app = mLruProcesses.get(i); 15745 if (allChanged || app.procStateChanged) { 15746 setProcessTrackerState(app, trackerMemFactor, now); 15747 app.procStateChanged = false; 15748 } 15749 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15750 && !app.killedByAm) { 15751 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15752 try { 15753 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15754 "Trimming memory of " + app.processName 15755 + " to " + curLevel); 15756 app.thread.scheduleTrimMemory(curLevel); 15757 } catch (RemoteException e) { 15758 } 15759 if (false) { 15760 // For now we won't do this; our memory trimming seems 15761 // to be good enough at this point that destroying 15762 // activities causes more harm than good. 15763 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15764 && app != mHomeProcess && app != mPreviousProcess) { 15765 // Need to do this on its own message because the stack may not 15766 // be in a consistent state at this point. 15767 // For these apps we will also finish their activities 15768 // to help them free memory. 15769 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15770 } 15771 } 15772 } 15773 app.trimMemoryLevel = curLevel; 15774 step++; 15775 if (step >= factor) { 15776 step = 0; 15777 switch (curLevel) { 15778 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15779 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15780 break; 15781 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15782 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15783 break; 15784 } 15785 } 15786 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15787 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15788 && app.thread != null) { 15789 try { 15790 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15791 "Trimming memory of heavy-weight " + app.processName 15792 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15793 app.thread.scheduleTrimMemory( 15794 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15795 } catch (RemoteException e) { 15796 } 15797 } 15798 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15799 } else { 15800 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15801 || app.systemNoUi) && app.pendingUiClean) { 15802 // If this application is now in the background and it 15803 // had done UI, then give it the special trim level to 15804 // have it free UI resources. 15805 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15806 if (app.trimMemoryLevel < level && app.thread != null) { 15807 try { 15808 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15809 "Trimming memory of bg-ui " + app.processName 15810 + " to " + level); 15811 app.thread.scheduleTrimMemory(level); 15812 } catch (RemoteException e) { 15813 } 15814 } 15815 app.pendingUiClean = false; 15816 } 15817 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15818 try { 15819 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15820 "Trimming memory of fg " + app.processName 15821 + " to " + fgTrimLevel); 15822 app.thread.scheduleTrimMemory(fgTrimLevel); 15823 } catch (RemoteException e) { 15824 } 15825 } 15826 app.trimMemoryLevel = fgTrimLevel; 15827 } 15828 } 15829 } else { 15830 if (mLowRamStartTime != 0) { 15831 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15832 mLowRamStartTime = 0; 15833 } 15834 for (int i=N-1; i>=0; i--) { 15835 ProcessRecord app = mLruProcesses.get(i); 15836 if (allChanged || app.procStateChanged) { 15837 setProcessTrackerState(app, trackerMemFactor, now); 15838 app.procStateChanged = false; 15839 } 15840 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15841 || app.systemNoUi) && app.pendingUiClean) { 15842 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15843 && app.thread != null) { 15844 try { 15845 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15846 "Trimming memory of ui hidden " + app.processName 15847 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15848 app.thread.scheduleTrimMemory( 15849 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15850 } catch (RemoteException e) { 15851 } 15852 } 15853 app.pendingUiClean = false; 15854 } 15855 app.trimMemoryLevel = 0; 15856 } 15857 } 15858 15859 if (mAlwaysFinishActivities) { 15860 // Need to do this on its own message because the stack may not 15861 // be in a consistent state at this point. 15862 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15863 } 15864 15865 if (allChanged) { 15866 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15867 } 15868 15869 if (mProcessStats.shouldWriteNowLocked(now)) { 15870 mHandler.post(new Runnable() { 15871 @Override public void run() { 15872 synchronized (ActivityManagerService.this) { 15873 mProcessStats.writeStateAsyncLocked(); 15874 } 15875 } 15876 }); 15877 } 15878 15879 if (DEBUG_OOM_ADJ) { 15880 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15881 } 15882 } 15883 15884 final void trimApplications() { 15885 synchronized (this) { 15886 int i; 15887 15888 // First remove any unused application processes whose package 15889 // has been removed. 15890 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15891 final ProcessRecord app = mRemovedProcesses.get(i); 15892 if (app.activities.size() == 0 15893 && app.curReceiver == null && app.services.size() == 0) { 15894 Slog.i( 15895 TAG, "Exiting empty application process " 15896 + app.processName + " (" 15897 + (app.thread != null ? app.thread.asBinder() : null) 15898 + ")\n"); 15899 if (app.pid > 0 && app.pid != MY_PID) { 15900 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 15901 app.processName, app.setAdj, "empty"); 15902 app.killedByAm = true; 15903 Process.killProcessQuiet(app.pid); 15904 } else { 15905 try { 15906 app.thread.scheduleExit(); 15907 } catch (Exception e) { 15908 // Ignore exceptions. 15909 } 15910 } 15911 cleanUpApplicationRecordLocked(app, false, true, -1); 15912 mRemovedProcesses.remove(i); 15913 15914 if (app.persistent) { 15915 if (app.persistent) { 15916 addAppLocked(app.info, false); 15917 } 15918 } 15919 } 15920 } 15921 15922 // Now update the oom adj for all processes. 15923 updateOomAdjLocked(); 15924 } 15925 } 15926 15927 /** This method sends the specified signal to each of the persistent apps */ 15928 public void signalPersistentProcesses(int sig) throws RemoteException { 15929 if (sig != Process.SIGNAL_USR1) { 15930 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 15931 } 15932 15933 synchronized (this) { 15934 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 15935 != PackageManager.PERMISSION_GRANTED) { 15936 throw new SecurityException("Requires permission " 15937 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 15938 } 15939 15940 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15941 ProcessRecord r = mLruProcesses.get(i); 15942 if (r.thread != null && r.persistent) { 15943 Process.sendSignal(r.pid, sig); 15944 } 15945 } 15946 } 15947 } 15948 15949 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 15950 if (proc == null || proc == mProfileProc) { 15951 proc = mProfileProc; 15952 path = mProfileFile; 15953 profileType = mProfileType; 15954 clearProfilerLocked(); 15955 } 15956 if (proc == null) { 15957 return; 15958 } 15959 try { 15960 proc.thread.profilerControl(false, path, null, profileType); 15961 } catch (RemoteException e) { 15962 throw new IllegalStateException("Process disappeared"); 15963 } 15964 } 15965 15966 private void clearProfilerLocked() { 15967 if (mProfileFd != null) { 15968 try { 15969 mProfileFd.close(); 15970 } catch (IOException e) { 15971 } 15972 } 15973 mProfileApp = null; 15974 mProfileProc = null; 15975 mProfileFile = null; 15976 mProfileType = 0; 15977 mAutoStopProfiler = false; 15978 } 15979 15980 public boolean profileControl(String process, int userId, boolean start, 15981 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 15982 15983 try { 15984 synchronized (this) { 15985 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15986 // its own permission. 15987 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15988 != PackageManager.PERMISSION_GRANTED) { 15989 throw new SecurityException("Requires permission " 15990 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15991 } 15992 15993 if (start && fd == null) { 15994 throw new IllegalArgumentException("null fd"); 15995 } 15996 15997 ProcessRecord proc = null; 15998 if (process != null) { 15999 proc = findProcessLocked(process, userId, "profileControl"); 16000 } 16001 16002 if (start && (proc == null || proc.thread == null)) { 16003 throw new IllegalArgumentException("Unknown process: " + process); 16004 } 16005 16006 if (start) { 16007 stopProfilerLocked(null, null, 0); 16008 setProfileApp(proc.info, proc.processName, path, fd, false); 16009 mProfileProc = proc; 16010 mProfileType = profileType; 16011 try { 16012 fd = fd.dup(); 16013 } catch (IOException e) { 16014 fd = null; 16015 } 16016 proc.thread.profilerControl(start, path, fd, profileType); 16017 fd = null; 16018 mProfileFd = null; 16019 } else { 16020 stopProfilerLocked(proc, path, profileType); 16021 if (fd != null) { 16022 try { 16023 fd.close(); 16024 } catch (IOException e) { 16025 } 16026 } 16027 } 16028 16029 return true; 16030 } 16031 } catch (RemoteException e) { 16032 throw new IllegalStateException("Process disappeared"); 16033 } finally { 16034 if (fd != null) { 16035 try { 16036 fd.close(); 16037 } catch (IOException e) { 16038 } 16039 } 16040 } 16041 } 16042 16043 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16044 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16045 userId, true, true, callName, null); 16046 ProcessRecord proc = null; 16047 try { 16048 int pid = Integer.parseInt(process); 16049 synchronized (mPidsSelfLocked) { 16050 proc = mPidsSelfLocked.get(pid); 16051 } 16052 } catch (NumberFormatException e) { 16053 } 16054 16055 if (proc == null) { 16056 ArrayMap<String, SparseArray<ProcessRecord>> all 16057 = mProcessNames.getMap(); 16058 SparseArray<ProcessRecord> procs = all.get(process); 16059 if (procs != null && procs.size() > 0) { 16060 proc = procs.valueAt(0); 16061 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16062 for (int i=1; i<procs.size(); i++) { 16063 ProcessRecord thisProc = procs.valueAt(i); 16064 if (thisProc.userId == userId) { 16065 proc = thisProc; 16066 break; 16067 } 16068 } 16069 } 16070 } 16071 } 16072 16073 return proc; 16074 } 16075 16076 public boolean dumpHeap(String process, int userId, boolean managed, 16077 String path, ParcelFileDescriptor fd) throws RemoteException { 16078 16079 try { 16080 synchronized (this) { 16081 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16082 // its own permission (same as profileControl). 16083 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16084 != PackageManager.PERMISSION_GRANTED) { 16085 throw new SecurityException("Requires permission " 16086 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16087 } 16088 16089 if (fd == null) { 16090 throw new IllegalArgumentException("null fd"); 16091 } 16092 16093 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16094 if (proc == null || proc.thread == null) { 16095 throw new IllegalArgumentException("Unknown process: " + process); 16096 } 16097 16098 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16099 if (!isDebuggable) { 16100 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16101 throw new SecurityException("Process not debuggable: " + proc); 16102 } 16103 } 16104 16105 proc.thread.dumpHeap(managed, path, fd); 16106 fd = null; 16107 return true; 16108 } 16109 } catch (RemoteException e) { 16110 throw new IllegalStateException("Process disappeared"); 16111 } finally { 16112 if (fd != null) { 16113 try { 16114 fd.close(); 16115 } catch (IOException e) { 16116 } 16117 } 16118 } 16119 } 16120 16121 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16122 public void monitor() { 16123 synchronized (this) { } 16124 } 16125 16126 void onCoreSettingsChange(Bundle settings) { 16127 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16128 ProcessRecord processRecord = mLruProcesses.get(i); 16129 try { 16130 if (processRecord.thread != null) { 16131 processRecord.thread.setCoreSettings(settings); 16132 } 16133 } catch (RemoteException re) { 16134 /* ignore */ 16135 } 16136 } 16137 } 16138 16139 // Multi-user methods 16140 16141 /** 16142 * Start user, if its not already running, but don't bring it to foreground. 16143 */ 16144 @Override 16145 public boolean startUserInBackground(final int userId) { 16146 return startUser(userId, /* foreground */ false); 16147 } 16148 16149 /** 16150 * Refreshes the list of users related to the current user when either a 16151 * user switch happens or when a new related user is started in the 16152 * background. 16153 */ 16154 private void updateRelatedUserIdsLocked() { 16155 final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId); 16156 int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null 16157 for (int i = 0; i < relatedUserIds.length; i++) { 16158 relatedUserIds[i] = relatedUsers.get(i).id; 16159 } 16160 mRelatedUserIds = relatedUserIds; 16161 } 16162 16163 @Override 16164 public boolean switchUser(final int userId) { 16165 return startUser(userId, /* foregound */ true); 16166 } 16167 16168 private boolean startUser(final int userId, boolean foreground) { 16169 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16170 != PackageManager.PERMISSION_GRANTED) { 16171 String msg = "Permission Denial: switchUser() from pid=" 16172 + Binder.getCallingPid() 16173 + ", uid=" + Binder.getCallingUid() 16174 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16175 Slog.w(TAG, msg); 16176 throw new SecurityException(msg); 16177 } 16178 16179 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16180 16181 final long ident = Binder.clearCallingIdentity(); 16182 try { 16183 synchronized (this) { 16184 final int oldUserId = mCurrentUserId; 16185 if (oldUserId == userId) { 16186 return true; 16187 } 16188 16189 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16190 if (userInfo == null) { 16191 Slog.w(TAG, "No user info for user #" + userId); 16192 return false; 16193 } 16194 16195 if (foreground) { 16196 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16197 R.anim.screen_user_enter); 16198 } 16199 16200 boolean needStart = false; 16201 16202 // If the user we are switching to is not currently started, then 16203 // we need to start it now. 16204 if (mStartedUsers.get(userId) == null) { 16205 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16206 updateStartedUserArrayLocked(); 16207 needStart = true; 16208 } 16209 16210 final Integer userIdInt = Integer.valueOf(userId); 16211 mUserLru.remove(userIdInt); 16212 mUserLru.add(userIdInt); 16213 16214 if (foreground) { 16215 mCurrentUserId = userId; 16216 updateRelatedUserIdsLocked(); 16217 mWindowManager.setCurrentUser(userId, mRelatedUserIds); 16218 // Once the internal notion of the active user has switched, we lock the device 16219 // with the option to show the user switcher on the keyguard. 16220 mWindowManager.lockNow(null); 16221 } else { 16222 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16223 updateRelatedUserIdsLocked(); 16224 mWindowManager.updateRelatedUserIds(mRelatedUserIds); 16225 mUserLru.remove(currentUserIdInt); 16226 mUserLru.add(currentUserIdInt); 16227 } 16228 16229 final UserStartedState uss = mStartedUsers.get(userId); 16230 16231 // Make sure user is in the started state. If it is currently 16232 // stopping, we need to knock that off. 16233 if (uss.mState == UserStartedState.STATE_STOPPING) { 16234 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16235 // so we can just fairly silently bring the user back from 16236 // the almost-dead. 16237 uss.mState = UserStartedState.STATE_RUNNING; 16238 updateStartedUserArrayLocked(); 16239 needStart = true; 16240 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16241 // This means ACTION_SHUTDOWN has been sent, so we will 16242 // need to treat this as a new boot of the user. 16243 uss.mState = UserStartedState.STATE_BOOTING; 16244 updateStartedUserArrayLocked(); 16245 needStart = true; 16246 } 16247 16248 if (foreground) { 16249 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16250 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16251 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16252 oldUserId, userId, uss)); 16253 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16254 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16255 } 16256 16257 if (needStart) { 16258 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16259 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16260 | Intent.FLAG_RECEIVER_FOREGROUND); 16261 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16262 broadcastIntentLocked(null, null, intent, 16263 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16264 false, false, MY_PID, Process.SYSTEM_UID, userId); 16265 } 16266 16267 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16268 if (userId != 0) { 16269 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16270 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16271 broadcastIntentLocked(null, null, intent, null, 16272 new IIntentReceiver.Stub() { 16273 public void performReceive(Intent intent, int resultCode, 16274 String data, Bundle extras, boolean ordered, 16275 boolean sticky, int sendingUser) { 16276 userInitialized(uss, userId); 16277 } 16278 }, 0, null, null, null, AppOpsManager.OP_NONE, 16279 true, false, MY_PID, Process.SYSTEM_UID, 16280 userId); 16281 uss.initializing = true; 16282 } else { 16283 getUserManagerLocked().makeInitialized(userInfo.id); 16284 } 16285 } 16286 16287 if (foreground) { 16288 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16289 if (homeInFront) { 16290 startHomeActivityLocked(userId); 16291 } else { 16292 mStackSupervisor.resumeTopActivitiesLocked(); 16293 } 16294 EventLogTags.writeAmSwitchUser(userId); 16295 getUserManagerLocked().userForeground(userId); 16296 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16297 } 16298 16299 if (needStart) { 16300 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16301 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16302 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16303 broadcastIntentLocked(null, null, intent, 16304 null, new IIntentReceiver.Stub() { 16305 @Override 16306 public void performReceive(Intent intent, int resultCode, String data, 16307 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16308 throws RemoteException { 16309 } 16310 }, 0, null, null, 16311 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16312 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16313 } 16314 } 16315 } finally { 16316 Binder.restoreCallingIdentity(ident); 16317 } 16318 16319 return true; 16320 } 16321 16322 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16323 long ident = Binder.clearCallingIdentity(); 16324 try { 16325 Intent intent; 16326 if (oldUserId >= 0) { 16327 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16328 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16329 | Intent.FLAG_RECEIVER_FOREGROUND); 16330 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16331 broadcastIntentLocked(null, null, intent, 16332 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16333 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16334 } 16335 if (newUserId >= 0) { 16336 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16337 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16338 | Intent.FLAG_RECEIVER_FOREGROUND); 16339 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16340 broadcastIntentLocked(null, null, intent, 16341 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16342 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16343 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16344 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16345 | Intent.FLAG_RECEIVER_FOREGROUND); 16346 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16347 broadcastIntentLocked(null, null, intent, 16348 null, null, 0, null, null, 16349 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16350 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16351 } 16352 } finally { 16353 Binder.restoreCallingIdentity(ident); 16354 } 16355 } 16356 16357 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16358 final int newUserId) { 16359 final int N = mUserSwitchObservers.beginBroadcast(); 16360 if (N > 0) { 16361 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16362 int mCount = 0; 16363 @Override 16364 public void sendResult(Bundle data) throws RemoteException { 16365 synchronized (ActivityManagerService.this) { 16366 if (mCurUserSwitchCallback == this) { 16367 mCount++; 16368 if (mCount == N) { 16369 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16370 } 16371 } 16372 } 16373 } 16374 }; 16375 synchronized (this) { 16376 uss.switching = true; 16377 mCurUserSwitchCallback = callback; 16378 } 16379 for (int i=0; i<N; i++) { 16380 try { 16381 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16382 newUserId, callback); 16383 } catch (RemoteException e) { 16384 } 16385 } 16386 } else { 16387 synchronized (this) { 16388 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16389 } 16390 } 16391 mUserSwitchObservers.finishBroadcast(); 16392 } 16393 16394 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16395 synchronized (this) { 16396 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16397 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16398 } 16399 } 16400 16401 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16402 mCurUserSwitchCallback = null; 16403 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16404 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16405 oldUserId, newUserId, uss)); 16406 } 16407 16408 void userInitialized(UserStartedState uss, int newUserId) { 16409 completeSwitchAndInitalize(uss, newUserId, true, false); 16410 } 16411 16412 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16413 completeSwitchAndInitalize(uss, newUserId, false, true); 16414 } 16415 16416 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16417 boolean clearInitializing, boolean clearSwitching) { 16418 boolean unfrozen = false; 16419 synchronized (this) { 16420 if (clearInitializing) { 16421 uss.initializing = false; 16422 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16423 } 16424 if (clearSwitching) { 16425 uss.switching = false; 16426 } 16427 if (!uss.switching && !uss.initializing) { 16428 mWindowManager.stopFreezingScreen(); 16429 unfrozen = true; 16430 } 16431 } 16432 if (unfrozen) { 16433 final int N = mUserSwitchObservers.beginBroadcast(); 16434 for (int i=0; i<N; i++) { 16435 try { 16436 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16437 } catch (RemoteException e) { 16438 } 16439 } 16440 mUserSwitchObservers.finishBroadcast(); 16441 } 16442 } 16443 16444 void scheduleStartRelatedUsersLocked() { 16445 if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) { 16446 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG), 16447 DateUtils.SECOND_IN_MILLIS); 16448 } 16449 } 16450 16451 void startRelatedUsersLocked() { 16452 if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked"); 16453 List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId); 16454 List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size()); 16455 for (UserInfo relatedUser : relatedUsers) { 16456 if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) { 16457 toStart.add(relatedUser); 16458 } 16459 } 16460 final int n = toStart.size(); 16461 int i = 0; 16462 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16463 startUserInBackground(toStart.get(i).id); 16464 } 16465 if (i < n) { 16466 Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS"); 16467 } 16468 } 16469 16470 void finishUserSwitch(UserStartedState uss) { 16471 synchronized (this) { 16472 if (uss.mState == UserStartedState.STATE_BOOTING 16473 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16474 uss.mState = UserStartedState.STATE_RUNNING; 16475 final int userId = uss.mHandle.getIdentifier(); 16476 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16477 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16478 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16479 broadcastIntentLocked(null, null, intent, 16480 null, null, 0, null, null, 16481 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16482 true, false, MY_PID, Process.SYSTEM_UID, userId); 16483 } 16484 16485 startRelatedUsersLocked(); 16486 16487 int num = mUserLru.size(); 16488 int i = 0; 16489 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16490 Integer oldUserId = mUserLru.get(i); 16491 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16492 if (oldUss == null) { 16493 // Shouldn't happen, but be sane if it does. 16494 mUserLru.remove(i); 16495 num--; 16496 continue; 16497 } 16498 if (oldUss.mState == UserStartedState.STATE_STOPPING 16499 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16500 // This user is already stopping, doesn't count. 16501 num--; 16502 i++; 16503 continue; 16504 } 16505 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16506 // Owner and current can't be stopped, but count as running. 16507 i++; 16508 continue; 16509 } 16510 // This is a user to be stopped. 16511 stopUserLocked(oldUserId, null); 16512 num--; 16513 i++; 16514 } 16515 } 16516 } 16517 16518 @Override 16519 public int stopUser(final int userId, final IStopUserCallback callback) { 16520 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16521 != PackageManager.PERMISSION_GRANTED) { 16522 String msg = "Permission Denial: switchUser() from pid=" 16523 + Binder.getCallingPid() 16524 + ", uid=" + Binder.getCallingUid() 16525 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16526 Slog.w(TAG, msg); 16527 throw new SecurityException(msg); 16528 } 16529 if (userId <= 0) { 16530 throw new IllegalArgumentException("Can't stop primary user " + userId); 16531 } 16532 synchronized (this) { 16533 return stopUserLocked(userId, callback); 16534 } 16535 } 16536 16537 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16538 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16539 if (mCurrentUserId == userId) { 16540 return ActivityManager.USER_OP_IS_CURRENT; 16541 } 16542 16543 final UserStartedState uss = mStartedUsers.get(userId); 16544 if (uss == null) { 16545 // User is not started, nothing to do... but we do need to 16546 // callback if requested. 16547 if (callback != null) { 16548 mHandler.post(new Runnable() { 16549 @Override 16550 public void run() { 16551 try { 16552 callback.userStopped(userId); 16553 } catch (RemoteException e) { 16554 } 16555 } 16556 }); 16557 } 16558 return ActivityManager.USER_OP_SUCCESS; 16559 } 16560 16561 if (callback != null) { 16562 uss.mStopCallbacks.add(callback); 16563 } 16564 16565 if (uss.mState != UserStartedState.STATE_STOPPING 16566 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16567 uss.mState = UserStartedState.STATE_STOPPING; 16568 updateStartedUserArrayLocked(); 16569 16570 long ident = Binder.clearCallingIdentity(); 16571 try { 16572 // We are going to broadcast ACTION_USER_STOPPING and then 16573 // once that is done send a final ACTION_SHUTDOWN and then 16574 // stop the user. 16575 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16576 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16577 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16578 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16579 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16580 // This is the result receiver for the final shutdown broadcast. 16581 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16582 @Override 16583 public void performReceive(Intent intent, int resultCode, String data, 16584 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16585 finishUserStop(uss); 16586 } 16587 }; 16588 // This is the result receiver for the initial stopping broadcast. 16589 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16590 @Override 16591 public void performReceive(Intent intent, int resultCode, String data, 16592 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16593 // On to the next. 16594 synchronized (ActivityManagerService.this) { 16595 if (uss.mState != UserStartedState.STATE_STOPPING) { 16596 // Whoops, we are being started back up. Abort, abort! 16597 return; 16598 } 16599 uss.mState = UserStartedState.STATE_SHUTDOWN; 16600 } 16601 broadcastIntentLocked(null, null, shutdownIntent, 16602 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16603 true, false, MY_PID, Process.SYSTEM_UID, userId); 16604 } 16605 }; 16606 // Kick things off. 16607 broadcastIntentLocked(null, null, stoppingIntent, 16608 null, stoppingReceiver, 0, null, null, 16609 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16610 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16611 } finally { 16612 Binder.restoreCallingIdentity(ident); 16613 } 16614 } 16615 16616 return ActivityManager.USER_OP_SUCCESS; 16617 } 16618 16619 void finishUserStop(UserStartedState uss) { 16620 final int userId = uss.mHandle.getIdentifier(); 16621 boolean stopped; 16622 ArrayList<IStopUserCallback> callbacks; 16623 synchronized (this) { 16624 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16625 if (mStartedUsers.get(userId) != uss) { 16626 stopped = false; 16627 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16628 stopped = false; 16629 } else { 16630 stopped = true; 16631 // User can no longer run. 16632 mStartedUsers.remove(userId); 16633 mUserLru.remove(Integer.valueOf(userId)); 16634 updateStartedUserArrayLocked(); 16635 16636 // Clean up all state and processes associated with the user. 16637 // Kill all the processes for the user. 16638 forceStopUserLocked(userId, "finish user"); 16639 } 16640 } 16641 16642 for (int i=0; i<callbacks.size(); i++) { 16643 try { 16644 if (stopped) callbacks.get(i).userStopped(userId); 16645 else callbacks.get(i).userStopAborted(userId); 16646 } catch (RemoteException e) { 16647 } 16648 } 16649 16650 mStackSupervisor.removeUserLocked(userId); 16651 } 16652 16653 @Override 16654 public UserInfo getCurrentUser() { 16655 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16656 != PackageManager.PERMISSION_GRANTED) && ( 16657 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16658 != PackageManager.PERMISSION_GRANTED)) { 16659 String msg = "Permission Denial: getCurrentUser() from pid=" 16660 + Binder.getCallingPid() 16661 + ", uid=" + Binder.getCallingUid() 16662 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16663 Slog.w(TAG, msg); 16664 throw new SecurityException(msg); 16665 } 16666 synchronized (this) { 16667 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16668 } 16669 } 16670 16671 int getCurrentUserIdLocked() { 16672 return mCurrentUserId; 16673 } 16674 16675 @Override 16676 public boolean isUserRunning(int userId, boolean orStopped) { 16677 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16678 != PackageManager.PERMISSION_GRANTED) { 16679 String msg = "Permission Denial: isUserRunning() from pid=" 16680 + Binder.getCallingPid() 16681 + ", uid=" + Binder.getCallingUid() 16682 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16683 Slog.w(TAG, msg); 16684 throw new SecurityException(msg); 16685 } 16686 synchronized (this) { 16687 return isUserRunningLocked(userId, orStopped); 16688 } 16689 } 16690 16691 boolean isUserRunningLocked(int userId, boolean orStopped) { 16692 UserStartedState state = mStartedUsers.get(userId); 16693 if (state == null) { 16694 return false; 16695 } 16696 if (orStopped) { 16697 return true; 16698 } 16699 return state.mState != UserStartedState.STATE_STOPPING 16700 && state.mState != UserStartedState.STATE_SHUTDOWN; 16701 } 16702 16703 @Override 16704 public int[] getRunningUserIds() { 16705 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16706 != PackageManager.PERMISSION_GRANTED) { 16707 String msg = "Permission Denial: isUserRunning() from pid=" 16708 + Binder.getCallingPid() 16709 + ", uid=" + Binder.getCallingUid() 16710 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16711 Slog.w(TAG, msg); 16712 throw new SecurityException(msg); 16713 } 16714 synchronized (this) { 16715 return mStartedUserArray; 16716 } 16717 } 16718 16719 private void updateStartedUserArrayLocked() { 16720 int num = 0; 16721 for (int i=0; i<mStartedUsers.size(); i++) { 16722 UserStartedState uss = mStartedUsers.valueAt(i); 16723 // This list does not include stopping users. 16724 if (uss.mState != UserStartedState.STATE_STOPPING 16725 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16726 num++; 16727 } 16728 } 16729 mStartedUserArray = new int[num]; 16730 num = 0; 16731 for (int i=0; i<mStartedUsers.size(); i++) { 16732 UserStartedState uss = mStartedUsers.valueAt(i); 16733 if (uss.mState != UserStartedState.STATE_STOPPING 16734 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16735 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16736 num++; 16737 } 16738 } 16739 } 16740 16741 @Override 16742 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16743 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16744 != PackageManager.PERMISSION_GRANTED) { 16745 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16746 + Binder.getCallingPid() 16747 + ", uid=" + Binder.getCallingUid() 16748 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16749 Slog.w(TAG, msg); 16750 throw new SecurityException(msg); 16751 } 16752 16753 mUserSwitchObservers.register(observer); 16754 } 16755 16756 @Override 16757 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16758 mUserSwitchObservers.unregister(observer); 16759 } 16760 16761 private boolean userExists(int userId) { 16762 if (userId == 0) { 16763 return true; 16764 } 16765 UserManagerService ums = getUserManagerLocked(); 16766 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16767 } 16768 16769 int[] getUsersLocked() { 16770 UserManagerService ums = getUserManagerLocked(); 16771 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16772 } 16773 16774 UserManagerService getUserManagerLocked() { 16775 if (mUserManager == null) { 16776 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16777 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16778 } 16779 return mUserManager; 16780 } 16781 16782 private int applyUserId(int uid, int userId) { 16783 return UserHandle.getUid(userId, uid); 16784 } 16785 16786 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16787 if (info == null) return null; 16788 ApplicationInfo newInfo = new ApplicationInfo(info); 16789 newInfo.uid = applyUserId(info.uid, userId); 16790 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16791 + info.packageName; 16792 return newInfo; 16793 } 16794 16795 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16796 if (aInfo == null 16797 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16798 return aInfo; 16799 } 16800 16801 ActivityInfo info = new ActivityInfo(aInfo); 16802 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16803 return info; 16804 } 16805} 16806