ActivityManagerService.java revision 6143a02f96a5c6c7a0a84f5dbe70732998256a72
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20import static com.android.internal.util.XmlUtils.readIntAttribute; 21import static com.android.internal.util.XmlUtils.readLongAttribute; 22import static com.android.internal.util.XmlUtils.writeIntAttribute; 23import static com.android.internal.util.XmlUtils.writeLongAttribute; 24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 26import static org.xmlpull.v1.XmlPullParser.START_TAG; 27 28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 29 30import android.app.AppOpsManager; 31import android.app.IActivityContainer; 32import android.app.IActivityContainerCallback; 33import android.appwidget.AppWidgetManager; 34import android.graphics.Rect; 35import android.os.BatteryStats; 36import android.util.ArrayMap; 37import com.android.internal.R; 38import com.android.internal.annotations.GuardedBy; 39import com.android.internal.app.IAppOpsService; 40import com.android.internal.app.ProcessMap; 41import com.android.internal.app.ProcessStats; 42import com.android.internal.os.BackgroundThread; 43import com.android.internal.os.BatteryStatsImpl; 44import com.android.internal.os.ProcessCpuTracker; 45import com.android.internal.os.TransferPipe; 46import com.android.internal.util.FastPrintWriter; 47import com.android.internal.util.FastXmlSerializer; 48import com.android.internal.util.MemInfoReader; 49import com.android.internal.util.Preconditions; 50import com.android.server.AppOpsService; 51import com.android.server.AttributeCache; 52import com.android.server.IntentResolver; 53import com.android.server.ServiceThread; 54import com.android.server.SystemService; 55import com.android.server.Watchdog; 56import com.android.server.am.ActivityStack.ActivityState; 57import com.android.server.firewall.IntentFirewall; 58import com.android.server.pm.UserManagerService; 59import com.android.server.wm.AppTransition; 60import com.android.server.wm.WindowManagerService; 61import com.google.android.collect.Lists; 62import com.google.android.collect.Maps; 63 64import dalvik.system.Zygote; 65 66import libcore.io.IoUtils; 67 68import org.xmlpull.v1.XmlPullParser; 69import org.xmlpull.v1.XmlPullParserException; 70import org.xmlpull.v1.XmlSerializer; 71 72import android.app.Activity; 73import android.app.ActivityManager; 74import android.app.ActivityManager.RunningTaskInfo; 75import android.app.ActivityManager.StackInfo; 76import android.app.ActivityManagerNative; 77import android.app.ActivityOptions; 78import android.app.ActivityThread; 79import android.app.AlertDialog; 80import android.app.AppGlobals; 81import android.app.ApplicationErrorReport; 82import android.app.Dialog; 83import android.app.IActivityController; 84import android.app.IApplicationThread; 85import android.app.IInstrumentationWatcher; 86import android.app.INotificationManager; 87import android.app.IProcessObserver; 88import android.app.IServiceConnection; 89import android.app.IStopUserCallback; 90import android.app.IThumbnailReceiver; 91import android.app.IUiAutomationConnection; 92import android.app.IUserSwitchObserver; 93import android.app.Instrumentation; 94import android.app.Notification; 95import android.app.NotificationManager; 96import android.app.PendingIntent; 97import android.app.backup.IBackupManager; 98import android.content.ActivityNotFoundException; 99import android.content.BroadcastReceiver; 100import android.content.ClipData; 101import android.content.ComponentCallbacks2; 102import android.content.ComponentName; 103import android.content.ContentProvider; 104import android.content.ContentResolver; 105import android.content.Context; 106import android.content.DialogInterface; 107import android.content.IContentProvider; 108import android.content.IIntentReceiver; 109import android.content.IIntentSender; 110import android.content.Intent; 111import android.content.IntentFilter; 112import android.content.IntentSender; 113import android.content.pm.ActivityInfo; 114import android.content.pm.ApplicationInfo; 115import android.content.pm.ConfigurationInfo; 116import android.content.pm.IPackageDataObserver; 117import android.content.pm.IPackageManager; 118import android.content.pm.InstrumentationInfo; 119import android.content.pm.PackageInfo; 120import android.content.pm.PackageManager; 121import android.content.pm.ParceledListSlice; 122import android.content.pm.UserInfo; 123import android.content.pm.PackageManager.NameNotFoundException; 124import android.content.pm.PathPermission; 125import android.content.pm.ProviderInfo; 126import android.content.pm.ResolveInfo; 127import android.content.pm.ServiceInfo; 128import android.content.res.CompatibilityInfo; 129import android.content.res.Configuration; 130import android.graphics.Bitmap; 131import android.net.Proxy; 132import android.net.ProxyProperties; 133import android.net.Uri; 134import android.os.Binder; 135import android.os.Build; 136import android.os.Bundle; 137import android.os.Debug; 138import android.os.DropBoxManager; 139import android.os.Environment; 140import android.os.FactoryTest; 141import android.os.FileObserver; 142import android.os.FileUtils; 143import android.os.Handler; 144import android.os.IBinder; 145import android.os.IPermissionController; 146import android.os.IRemoteCallback; 147import android.os.IUserManager; 148import android.os.Looper; 149import android.os.Message; 150import android.os.Parcel; 151import android.os.ParcelFileDescriptor; 152import android.os.Process; 153import android.os.RemoteCallbackList; 154import android.os.RemoteException; 155import android.os.SELinux; 156import android.os.ServiceManager; 157import android.os.StrictMode; 158import android.os.SystemClock; 159import android.os.SystemProperties; 160import android.os.UpdateLock; 161import android.os.UserHandle; 162import android.provider.Settings; 163import android.text.format.DateUtils; 164import android.text.format.Time; 165import android.util.AtomicFile; 166import android.util.EventLog; 167import android.util.Log; 168import android.util.Pair; 169import android.util.PrintWriterPrinter; 170import android.util.Slog; 171import android.util.SparseArray; 172import android.util.TimeUtils; 173import android.util.Xml; 174import android.view.Gravity; 175import android.view.LayoutInflater; 176import android.view.View; 177import android.view.WindowManager; 178 179import java.io.BufferedInputStream; 180import java.io.BufferedOutputStream; 181import java.io.DataInputStream; 182import java.io.DataOutputStream; 183import java.io.File; 184import java.io.FileDescriptor; 185import java.io.FileInputStream; 186import java.io.FileNotFoundException; 187import java.io.FileOutputStream; 188import java.io.IOException; 189import java.io.InputStreamReader; 190import java.io.PrintWriter; 191import java.io.StringWriter; 192import java.lang.ref.WeakReference; 193import java.util.ArrayList; 194import java.util.Arrays; 195import java.util.Collections; 196import java.util.Comparator; 197import java.util.HashMap; 198import java.util.HashSet; 199import java.util.Iterator; 200import java.util.List; 201import java.util.Locale; 202import java.util.Map; 203import java.util.Set; 204import java.util.concurrent.atomic.AtomicBoolean; 205import java.util.concurrent.atomic.AtomicLong; 206 207public final class ActivityManagerService extends ActivityManagerNative 208 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 209 private static final String USER_DATA_DIR = "/data/user/"; 210 static final String TAG = "ActivityManager"; 211 static final String TAG_MU = "ActivityManagerServiceMU"; 212 static final boolean DEBUG = false; 213 static final boolean localLOGV = DEBUG; 214 static final boolean DEBUG_BACKUP = localLOGV || false; 215 static final boolean DEBUG_BROADCAST = localLOGV || false; 216 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 217 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 218 static final boolean DEBUG_CLEANUP = localLOGV || false; 219 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 220 static final boolean DEBUG_FOCUS = false; 221 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 222 static final boolean DEBUG_MU = localLOGV || false; 223 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 224 static final boolean DEBUG_LRU = localLOGV || false; 225 static final boolean DEBUG_PAUSE = localLOGV || false; 226 static final boolean DEBUG_POWER = localLOGV || false; 227 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 228 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 229 static final boolean DEBUG_PROCESSES = localLOGV || false; 230 static final boolean DEBUG_PROVIDER = localLOGV || false; 231 static final boolean DEBUG_RESULTS = localLOGV || false; 232 static final boolean DEBUG_SERVICE = localLOGV || false; 233 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 234 static final boolean DEBUG_STACK = localLOGV || false; 235 static final boolean DEBUG_SWITCH = localLOGV || false; 236 static final boolean DEBUG_TASKS = localLOGV || false; 237 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 238 static final boolean DEBUG_TRANSITION = localLOGV || false; 239 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 240 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 241 static final boolean DEBUG_VISBILITY = localLOGV || false; 242 static final boolean DEBUG_PSS = localLOGV || false; 243 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 244 static final boolean VALIDATE_TOKENS = false; 245 static final boolean SHOW_ACTIVITY_START_TIME = true; 246 247 // Control over CPU and battery monitoring. 248 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 249 static final boolean MONITOR_CPU_USAGE = true; 250 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 251 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 252 static final boolean MONITOR_THREAD_CPU_USAGE = false; 253 254 // The flags that are set for all calls we make to the package manager. 255 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 256 257 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 258 259 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 260 261 // Maximum number of recent tasks that we can remember. 262 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 263 264 // Amount of time after a call to stopAppSwitches() during which we will 265 // prevent further untrusted switches from happening. 266 static final long APP_SWITCH_DELAY_TIME = 5*1000; 267 268 // How long we wait for a launched process to attach to the activity manager 269 // before we decide it's never going to come up for real. 270 static final int PROC_START_TIMEOUT = 10*1000; 271 272 // How long we wait for a launched process to attach to the activity manager 273 // before we decide it's never going to come up for real, when the process was 274 // started with a wrapper for instrumentation (such as Valgrind) because it 275 // could take much longer than usual. 276 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 277 278 // How long to wait after going idle before forcing apps to GC. 279 static final int GC_TIMEOUT = 5*1000; 280 281 // The minimum amount of time between successive GC requests for a process. 282 static final int GC_MIN_INTERVAL = 60*1000; 283 284 // The minimum amount of time between successive PSS requests for a process. 285 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 286 287 // The minimum amount of time between successive PSS requests for a process 288 // when the request is due to the memory state being lowered. 289 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 290 291 // The rate at which we check for apps using excessive power -- 15 mins. 292 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 293 294 // The minimum sample duration we will allow before deciding we have 295 // enough data on wake locks to start killing things. 296 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 297 298 // The minimum sample duration we will allow before deciding we have 299 // enough data on CPU usage to start killing things. 300 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 301 302 // How long we allow a receiver to run before giving up on it. 303 static final int BROADCAST_FG_TIMEOUT = 10*1000; 304 static final int BROADCAST_BG_TIMEOUT = 60*1000; 305 306 // How long we wait until we timeout on key dispatching. 307 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 308 309 // How long we wait until we timeout on key dispatching during instrumentation. 310 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 311 312 // Amount of time we wait for observers to handle a user switch before 313 // giving up on them and unfreezing the screen. 314 static final int USER_SWITCH_TIMEOUT = 2*1000; 315 316 // Maximum number of users we allow to be running at a time. 317 static final int MAX_RUNNING_USERS = 3; 318 319 // How long to wait in getAssistContextExtras for the activity and foreground services 320 // to respond with the result. 321 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 322 323 // Maximum number of persisted Uri grants a package is allowed 324 static final int MAX_PERSISTED_URI_GRANTS = 128; 325 326 static final int MY_PID = Process.myPid(); 327 328 static final String[] EMPTY_STRING_ARRAY = new String[0]; 329 330 // How many bytes to write into the dropbox log before truncating 331 static final int DROPBOX_MAX_SIZE = 256 * 1024; 332 333 /** Run all ActivityStacks through this */ 334 ActivityStackSupervisor mStackSupervisor; 335 336 public IntentFirewall mIntentFirewall; 337 338 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 339 // default actuion automatically. Important for devices without direct input 340 // devices. 341 private boolean mShowDialogs = true; 342 343 /** 344 * Description of a request to start a new activity, which has been held 345 * due to app switches being disabled. 346 */ 347 static class PendingActivityLaunch { 348 final ActivityRecord r; 349 final ActivityRecord sourceRecord; 350 final int startFlags; 351 final ActivityStack stack; 352 353 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 354 int _startFlags, ActivityStack _stack) { 355 r = _r; 356 sourceRecord = _sourceRecord; 357 startFlags = _startFlags; 358 stack = _stack; 359 } 360 } 361 362 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 363 = new ArrayList<PendingActivityLaunch>(); 364 365 BroadcastQueue mFgBroadcastQueue; 366 BroadcastQueue mBgBroadcastQueue; 367 // Convenient for easy iteration over the queues. Foreground is first 368 // so that dispatch of foreground broadcasts gets precedence. 369 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 370 371 BroadcastQueue broadcastQueueForIntent(Intent intent) { 372 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 373 if (DEBUG_BACKGROUND_BROADCAST) { 374 Slog.i(TAG, "Broadcast intent " + intent + " on " 375 + (isFg ? "foreground" : "background") 376 + " queue"); 377 } 378 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 379 } 380 381 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 382 for (BroadcastQueue queue : mBroadcastQueues) { 383 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 384 if (r != null) { 385 return r; 386 } 387 } 388 return null; 389 } 390 391 /** 392 * Activity we have told the window manager to have key focus. 393 */ 394 ActivityRecord mFocusedActivity = null; 395 396 /** 397 * List of intents that were used to start the most recent tasks. 398 */ 399 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 400 401 public class PendingAssistExtras extends Binder implements Runnable { 402 public final ActivityRecord activity; 403 public boolean haveResult = false; 404 public Bundle result = null; 405 public PendingAssistExtras(ActivityRecord _activity) { 406 activity = _activity; 407 } 408 @Override 409 public void run() { 410 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 411 synchronized (this) { 412 haveResult = true; 413 notifyAll(); 414 } 415 } 416 } 417 418 final ArrayList<PendingAssistExtras> mPendingAssistExtras 419 = new ArrayList<PendingAssistExtras>(); 420 421 /** 422 * Process management. 423 */ 424 final ProcessList mProcessList = new ProcessList(); 425 426 /** 427 * All of the applications we currently have running organized by name. 428 * The keys are strings of the application package name (as 429 * returned by the package manager), and the keys are ApplicationRecord 430 * objects. 431 */ 432 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 433 434 /** 435 * Tracking long-term execution of processes to look for abuse and other 436 * bad app behavior. 437 */ 438 final ProcessStatsService mProcessStats; 439 440 /** 441 * The currently running isolated processes. 442 */ 443 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 444 445 /** 446 * Counter for assigning isolated process uids, to avoid frequently reusing the 447 * same ones. 448 */ 449 int mNextIsolatedProcessUid = 0; 450 451 /** 452 * The currently running heavy-weight process, if any. 453 */ 454 ProcessRecord mHeavyWeightProcess = null; 455 456 /** 457 * The last time that various processes have crashed. 458 */ 459 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 460 461 /** 462 * Information about a process that is currently marked as bad. 463 */ 464 static final class BadProcessInfo { 465 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 466 this.time = time; 467 this.shortMsg = shortMsg; 468 this.longMsg = longMsg; 469 this.stack = stack; 470 } 471 472 final long time; 473 final String shortMsg; 474 final String longMsg; 475 final String stack; 476 } 477 478 /** 479 * Set of applications that we consider to be bad, and will reject 480 * incoming broadcasts from (which the user has no control over). 481 * Processes are added to this set when they have crashed twice within 482 * a minimum amount of time; they are removed from it when they are 483 * later restarted (hopefully due to some user action). The value is the 484 * time it was added to the list. 485 */ 486 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 487 488 /** 489 * All of the processes we currently have running organized by pid. 490 * The keys are the pid running the application. 491 * 492 * <p>NOTE: This object is protected by its own lock, NOT the global 493 * activity manager lock! 494 */ 495 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 496 497 /** 498 * All of the processes that have been forced to be foreground. The key 499 * is the pid of the caller who requested it (we hold a death 500 * link on it). 501 */ 502 abstract class ForegroundToken implements IBinder.DeathRecipient { 503 int pid; 504 IBinder token; 505 } 506 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 507 508 /** 509 * List of records for processes that someone had tried to start before the 510 * system was ready. We don't start them at that point, but ensure they 511 * are started by the time booting is complete. 512 */ 513 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 514 515 /** 516 * List of persistent applications that are in the process 517 * of being started. 518 */ 519 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 520 521 /** 522 * Processes that are being forcibly torn down. 523 */ 524 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 525 526 /** 527 * List of running applications, sorted by recent usage. 528 * The first entry in the list is the least recently used. 529 */ 530 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 531 532 /** 533 * Where in mLruProcesses that the processes hosting activities start. 534 */ 535 int mLruProcessActivityStart = 0; 536 537 /** 538 * Where in mLruProcesses that the processes hosting services start. 539 * This is after (lower index) than mLruProcessesActivityStart. 540 */ 541 int mLruProcessServiceStart = 0; 542 543 /** 544 * List of processes that should gc as soon as things are idle. 545 */ 546 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 547 548 /** 549 * Processes we want to collect PSS data from. 550 */ 551 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 552 553 /** 554 * Last time we requested PSS data of all processes. 555 */ 556 long mLastFullPssTime = SystemClock.uptimeMillis(); 557 558 /** 559 * This is the process holding what we currently consider to be 560 * the "home" activity. 561 */ 562 ProcessRecord mHomeProcess; 563 564 /** 565 * This is the process holding the activity the user last visited that 566 * is in a different process from the one they are currently in. 567 */ 568 ProcessRecord mPreviousProcess; 569 570 /** 571 * The time at which the previous process was last visible. 572 */ 573 long mPreviousProcessVisibleTime; 574 575 /** 576 * Which uses have been started, so are allowed to run code. 577 */ 578 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 579 580 /** 581 * LRU list of history of current users. Most recently current is at the end. 582 */ 583 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 584 585 /** 586 * Constant array of the users that are currently started. 587 */ 588 int[] mStartedUserArray = new int[] { 0 }; 589 590 /** 591 * Registered observers of the user switching mechanics. 592 */ 593 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 594 = new RemoteCallbackList<IUserSwitchObserver>(); 595 596 /** 597 * Currently active user switch. 598 */ 599 Object mCurUserSwitchCallback; 600 601 /** 602 * Packages that the user has asked to have run in screen size 603 * compatibility mode instead of filling the screen. 604 */ 605 final CompatModePackages mCompatModePackages; 606 607 /** 608 * Set of IntentSenderRecord objects that are currently active. 609 */ 610 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 611 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 612 613 /** 614 * Fingerprints (hashCode()) of stack traces that we've 615 * already logged DropBox entries for. Guarded by itself. If 616 * something (rogue user app) forces this over 617 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 618 */ 619 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 620 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 621 622 /** 623 * Strict Mode background batched logging state. 624 * 625 * The string buffer is guarded by itself, and its lock is also 626 * used to determine if another batched write is already 627 * in-flight. 628 */ 629 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 630 631 /** 632 * Keeps track of all IIntentReceivers that have been registered for 633 * broadcasts. Hash keys are the receiver IBinder, hash value is 634 * a ReceiverList. 635 */ 636 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 637 new HashMap<IBinder, ReceiverList>(); 638 639 /** 640 * Resolver for broadcast intents to registered receivers. 641 * Holds BroadcastFilter (subclass of IntentFilter). 642 */ 643 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 644 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 645 @Override 646 protected boolean allowFilterResult( 647 BroadcastFilter filter, List<BroadcastFilter> dest) { 648 IBinder target = filter.receiverList.receiver.asBinder(); 649 for (int i=dest.size()-1; i>=0; i--) { 650 if (dest.get(i).receiverList.receiver.asBinder() == target) { 651 return false; 652 } 653 } 654 return true; 655 } 656 657 @Override 658 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 659 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 660 || userId == filter.owningUserId) { 661 return super.newResult(filter, match, userId); 662 } 663 return null; 664 } 665 666 @Override 667 protected BroadcastFilter[] newArray(int size) { 668 return new BroadcastFilter[size]; 669 } 670 671 @Override 672 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 673 return packageName.equals(filter.packageName); 674 } 675 }; 676 677 /** 678 * State of all active sticky broadcasts per user. Keys are the action of the 679 * sticky Intent, values are an ArrayList of all broadcasted intents with 680 * that action (which should usually be one). The SparseArray is keyed 681 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 682 * for stickies that are sent to all users. 683 */ 684 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 685 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 686 687 final ActiveServices mServices; 688 689 /** 690 * Backup/restore process management 691 */ 692 String mBackupAppName = null; 693 BackupRecord mBackupTarget = null; 694 695 /** 696 * List of PendingThumbnailsRecord objects of clients who are still 697 * waiting to receive all of the thumbnails for a task. 698 */ 699 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 700 new ArrayList<PendingThumbnailsRecord>(); 701 702 final ProviderMap mProviderMap; 703 704 /** 705 * List of content providers who have clients waiting for them. The 706 * application is currently being launched and the provider will be 707 * removed from this list once it is published. 708 */ 709 final ArrayList<ContentProviderRecord> mLaunchingProviders 710 = new ArrayList<ContentProviderRecord>(); 711 712 /** 713 * File storing persisted {@link #mGrantedUriPermissions}. 714 */ 715 private final AtomicFile mGrantFile; 716 717 /** XML constants used in {@link #mGrantFile} */ 718 private static final String TAG_URI_GRANTS = "uri-grants"; 719 private static final String TAG_URI_GRANT = "uri-grant"; 720 private static final String ATTR_USER_HANDLE = "userHandle"; 721 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 722 private static final String ATTR_TARGET_PKG = "targetPkg"; 723 private static final String ATTR_URI = "uri"; 724 private static final String ATTR_MODE_FLAGS = "modeFlags"; 725 private static final String ATTR_CREATED_TIME = "createdTime"; 726 727 /** 728 * Global set of specific {@link Uri} permissions that have been granted. 729 * This optimized lookup structure maps from {@link UriPermission#targetUid} 730 * to {@link UriPermission#uri} to {@link UriPermission}. 731 */ 732 @GuardedBy("this") 733 private final SparseArray<ArrayMap<Uri, UriPermission>> 734 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 735 736 CoreSettingsObserver mCoreSettingsObserver; 737 738 /** 739 * Thread-local storage used to carry caller permissions over through 740 * indirect content-provider access. 741 */ 742 private class Identity { 743 public int pid; 744 public int uid; 745 746 Identity(int _pid, int _uid) { 747 pid = _pid; 748 uid = _uid; 749 } 750 } 751 752 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 753 754 /** 755 * All information we have collected about the runtime performance of 756 * any user id that can impact battery performance. 757 */ 758 final BatteryStatsService mBatteryStatsService; 759 760 /** 761 * Information about component usage 762 */ 763 final UsageStatsService mUsageStatsService; 764 765 /** 766 * Information about and control over application operations 767 */ 768 final AppOpsService mAppOpsService; 769 770 /** 771 * Current configuration information. HistoryRecord objects are given 772 * a reference to this object to indicate which configuration they are 773 * currently running in, so this object must be kept immutable. 774 */ 775 Configuration mConfiguration = new Configuration(); 776 777 /** 778 * Current sequencing integer of the configuration, for skipping old 779 * configurations. 780 */ 781 int mConfigurationSeq = 0; 782 783 /** 784 * Hardware-reported OpenGLES version. 785 */ 786 final int GL_ES_VERSION; 787 788 /** 789 * List of initialization arguments to pass to all processes when binding applications to them. 790 * For example, references to the commonly used services. 791 */ 792 HashMap<String, IBinder> mAppBindArgs; 793 794 /** 795 * Temporary to avoid allocations. Protected by main lock. 796 */ 797 final StringBuilder mStringBuilder = new StringBuilder(256); 798 799 /** 800 * Used to control how we initialize the service. 801 */ 802 boolean mStartRunning = false; 803 ComponentName mTopComponent; 804 String mTopAction; 805 String mTopData; 806 boolean mProcessesReady = false; 807 boolean mSystemReady = false; 808 boolean mBooting = false; 809 boolean mWaitingUpdate = false; 810 boolean mDidUpdate = false; 811 boolean mOnBattery = false; 812 boolean mLaunchWarningShown = false; 813 814 Context mContext; 815 816 int mFactoryTest; 817 818 boolean mCheckedForSetup; 819 820 /** 821 * The time at which we will allow normal application switches again, 822 * after a call to {@link #stopAppSwitches()}. 823 */ 824 long mAppSwitchesAllowedTime; 825 826 /** 827 * This is set to true after the first switch after mAppSwitchesAllowedTime 828 * is set; any switches after that will clear the time. 829 */ 830 boolean mDidAppSwitch; 831 832 /** 833 * Last time (in realtime) at which we checked for power usage. 834 */ 835 long mLastPowerCheckRealtime; 836 837 /** 838 * Last time (in uptime) at which we checked for power usage. 839 */ 840 long mLastPowerCheckUptime; 841 842 /** 843 * Set while we are wanting to sleep, to prevent any 844 * activities from being started/resumed. 845 */ 846 boolean mSleeping = false; 847 848 /** 849 * State of external calls telling us if the device is asleep. 850 */ 851 boolean mWentToSleep = false; 852 853 /** 854 * State of external call telling us if the lock screen is shown. 855 */ 856 boolean mLockScreenShown = false; 857 858 /** 859 * Set if we are shutting down the system, similar to sleeping. 860 */ 861 boolean mShuttingDown = false; 862 863 /** 864 * Current sequence id for oom_adj computation traversal. 865 */ 866 int mAdjSeq = 0; 867 868 /** 869 * Current sequence id for process LRU updating. 870 */ 871 int mLruSeq = 0; 872 873 /** 874 * Keep track of the non-cached/empty process we last found, to help 875 * determine how to distribute cached/empty processes next time. 876 */ 877 int mNumNonCachedProcs = 0; 878 879 /** 880 * Keep track of the number of cached hidden procs, to balance oom adj 881 * distribution between those and empty procs. 882 */ 883 int mNumCachedHiddenProcs = 0; 884 885 /** 886 * Keep track of the number of service processes we last found, to 887 * determine on the next iteration which should be B services. 888 */ 889 int mNumServiceProcs = 0; 890 int mNewNumAServiceProcs = 0; 891 int mNewNumServiceProcs = 0; 892 893 /** 894 * Allow the current computed overall memory level of the system to go down? 895 * This is set to false when we are killing processes for reasons other than 896 * memory management, so that the now smaller process list will not be taken as 897 * an indication that memory is tighter. 898 */ 899 boolean mAllowLowerMemLevel = false; 900 901 /** 902 * The last computed memory level, for holding when we are in a state that 903 * processes are going away for other reasons. 904 */ 905 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 906 907 /** 908 * The last total number of process we have, to determine if changes actually look 909 * like a shrinking number of process due to lower RAM. 910 */ 911 int mLastNumProcesses; 912 913 /** 914 * The uptime of the last time we performed idle maintenance. 915 */ 916 long mLastIdleTime = SystemClock.uptimeMillis(); 917 918 /** 919 * Total time spent with RAM that has been added in the past since the last idle time. 920 */ 921 long mLowRamTimeSinceLastIdle = 0; 922 923 /** 924 * If RAM is currently low, when that horrible situation started. 925 */ 926 long mLowRamStartTime = 0; 927 928 /** 929 * For reporting to battery stats the current top application. 930 */ 931 private String mCurResumedPackage = null; 932 private int mCurResumedUid = -1; 933 934 /** 935 * For reporting to battery stats the apps currently running foreground 936 * service. The ProcessMap is package/uid tuples; each of these contain 937 * an array of the currently foreground processes. 938 */ 939 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 940 = new ProcessMap<ArrayList<ProcessRecord>>(); 941 942 /** 943 * This is set if we had to do a delayed dexopt of an app before launching 944 * it, to increasing the ANR timeouts in that case. 945 */ 946 boolean mDidDexOpt; 947 948 String mDebugApp = null; 949 boolean mWaitForDebugger = false; 950 boolean mDebugTransient = false; 951 String mOrigDebugApp = null; 952 boolean mOrigWaitForDebugger = false; 953 boolean mAlwaysFinishActivities = false; 954 IActivityController mController = null; 955 String mProfileApp = null; 956 ProcessRecord mProfileProc = null; 957 String mProfileFile; 958 ParcelFileDescriptor mProfileFd; 959 int mProfileType = 0; 960 boolean mAutoStopProfiler = false; 961 String mOpenGlTraceApp = null; 962 963 static class ProcessChangeItem { 964 static final int CHANGE_ACTIVITIES = 1<<0; 965 static final int CHANGE_IMPORTANCE= 1<<1; 966 int changes; 967 int uid; 968 int pid; 969 int importance; 970 boolean foregroundActivities; 971 } 972 973 final RemoteCallbackList<IProcessObserver> mProcessObservers 974 = new RemoteCallbackList<IProcessObserver>(); 975 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 976 977 final ArrayList<ProcessChangeItem> mPendingProcessChanges 978 = new ArrayList<ProcessChangeItem>(); 979 final ArrayList<ProcessChangeItem> mAvailProcessChanges 980 = new ArrayList<ProcessChangeItem>(); 981 982 /** 983 * Runtime CPU use collection thread. This object's lock is used to 984 * protect all related state. 985 */ 986 final Thread mProcessCpuThread; 987 988 /** 989 * Used to collect process stats when showing not responding dialog. 990 * Protected by mProcessCpuThread. 991 */ 992 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 993 MONITOR_THREAD_CPU_USAGE); 994 final AtomicLong mLastCpuTime = new AtomicLong(0); 995 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 996 997 long mLastWriteTime = 0; 998 999 /** 1000 * Used to retain an update lock when the foreground activity is in 1001 * immersive mode. 1002 */ 1003 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1004 1005 /** 1006 * Set to true after the system has finished booting. 1007 */ 1008 boolean mBooted = false; 1009 1010 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1011 int mProcessLimitOverride = -1; 1012 1013 WindowManagerService mWindowManager; 1014 1015 final ActivityThread mSystemThread; 1016 1017 int mCurrentUserId = 0; 1018 private UserManagerService mUserManager; 1019 1020 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1021 final ProcessRecord mApp; 1022 final int mPid; 1023 final IApplicationThread mAppThread; 1024 1025 AppDeathRecipient(ProcessRecord app, int pid, 1026 IApplicationThread thread) { 1027 if (localLOGV) Slog.v( 1028 TAG, "New death recipient " + this 1029 + " for thread " + thread.asBinder()); 1030 mApp = app; 1031 mPid = pid; 1032 mAppThread = thread; 1033 } 1034 1035 @Override 1036 public void binderDied() { 1037 if (localLOGV) Slog.v( 1038 TAG, "Death received in " + this 1039 + " for thread " + mAppThread.asBinder()); 1040 synchronized(ActivityManagerService.this) { 1041 appDiedLocked(mApp, mPid, mAppThread); 1042 } 1043 } 1044 } 1045 1046 static final int SHOW_ERROR_MSG = 1; 1047 static final int SHOW_NOT_RESPONDING_MSG = 2; 1048 static final int SHOW_FACTORY_ERROR_MSG = 3; 1049 static final int UPDATE_CONFIGURATION_MSG = 4; 1050 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1051 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1052 static final int SERVICE_TIMEOUT_MSG = 12; 1053 static final int UPDATE_TIME_ZONE = 13; 1054 static final int SHOW_UID_ERROR_MSG = 14; 1055 static final int IM_FEELING_LUCKY_MSG = 15; 1056 static final int PROC_START_TIMEOUT_MSG = 20; 1057 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1058 static final int KILL_APPLICATION_MSG = 22; 1059 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1060 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1061 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1062 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1063 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1064 static final int CLEAR_DNS_CACHE_MSG = 28; 1065 static final int UPDATE_HTTP_PROXY_MSG = 29; 1066 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1067 static final int DISPATCH_PROCESSES_CHANGED = 31; 1068 static final int DISPATCH_PROCESS_DIED = 32; 1069 static final int REPORT_MEM_USAGE_MSG = 33; 1070 static final int REPORT_USER_SWITCH_MSG = 34; 1071 static final int CONTINUE_USER_SWITCH_MSG = 35; 1072 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1073 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1074 static final int PERSIST_URI_GRANTS_MSG = 38; 1075 static final int REQUEST_ALL_PSS_MSG = 39; 1076 static final int START_RELATED_USERS_MSG = 40; 1077 1078 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1079 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1080 static final int FIRST_COMPAT_MODE_MSG = 300; 1081 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1082 1083 AlertDialog mUidAlert; 1084 CompatModeDialog mCompatModeDialog; 1085 long mLastMemUsageReportTime = 0; 1086 1087 /** 1088 * Flag whether the current user is a "monkey", i.e. whether 1089 * the UI is driven by a UI automation tool. 1090 */ 1091 private boolean mUserIsMonkey; 1092 1093 final ServiceThread mHandlerThread; 1094 final MainHandler mHandler; 1095 1096 final class MainHandler extends Handler { 1097 public MainHandler(Looper looper) { 1098 super(looper, null, true); 1099 } 1100 1101 @Override 1102 public void handleMessage(Message msg) { 1103 switch (msg.what) { 1104 case SHOW_ERROR_MSG: { 1105 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1106 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1107 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1108 synchronized (ActivityManagerService.this) { 1109 ProcessRecord proc = (ProcessRecord)data.get("app"); 1110 AppErrorResult res = (AppErrorResult) data.get("result"); 1111 if (proc != null && proc.crashDialog != null) { 1112 Slog.e(TAG, "App already has crash dialog: " + proc); 1113 if (res != null) { 1114 res.set(0); 1115 } 1116 return; 1117 } 1118 if (!showBackground && UserHandle.getAppId(proc.uid) 1119 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1120 && proc.pid != MY_PID) { 1121 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1122 if (res != null) { 1123 res.set(0); 1124 } 1125 return; 1126 } 1127 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1128 Dialog d = new AppErrorDialog(mContext, 1129 ActivityManagerService.this, res, proc); 1130 d.show(); 1131 proc.crashDialog = d; 1132 } else { 1133 // The device is asleep, so just pretend that the user 1134 // saw a crash dialog and hit "force quit". 1135 if (res != null) { 1136 res.set(0); 1137 } 1138 } 1139 } 1140 1141 ensureBootCompleted(); 1142 } break; 1143 case SHOW_NOT_RESPONDING_MSG: { 1144 synchronized (ActivityManagerService.this) { 1145 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1146 ProcessRecord proc = (ProcessRecord)data.get("app"); 1147 if (proc != null && proc.anrDialog != null) { 1148 Slog.e(TAG, "App already has anr dialog: " + proc); 1149 return; 1150 } 1151 1152 Intent intent = new Intent("android.intent.action.ANR"); 1153 if (!mProcessesReady) { 1154 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1155 | Intent.FLAG_RECEIVER_FOREGROUND); 1156 } 1157 broadcastIntentLocked(null, null, intent, 1158 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1159 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1160 1161 if (mShowDialogs) { 1162 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1163 mContext, proc, (ActivityRecord)data.get("activity"), 1164 msg.arg1 != 0); 1165 d.show(); 1166 proc.anrDialog = d; 1167 } else { 1168 // Just kill the app if there is no dialog to be shown. 1169 killAppAtUsersRequest(proc, null); 1170 } 1171 } 1172 1173 ensureBootCompleted(); 1174 } break; 1175 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1176 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1177 synchronized (ActivityManagerService.this) { 1178 ProcessRecord proc = (ProcessRecord) data.get("app"); 1179 if (proc == null) { 1180 Slog.e(TAG, "App not found when showing strict mode dialog."); 1181 break; 1182 } 1183 if (proc.crashDialog != null) { 1184 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1185 return; 1186 } 1187 AppErrorResult res = (AppErrorResult) data.get("result"); 1188 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1189 Dialog d = new StrictModeViolationDialog(mContext, 1190 ActivityManagerService.this, res, proc); 1191 d.show(); 1192 proc.crashDialog = d; 1193 } else { 1194 // The device is asleep, so just pretend that the user 1195 // saw a crash dialog and hit "force quit". 1196 res.set(0); 1197 } 1198 } 1199 ensureBootCompleted(); 1200 } break; 1201 case SHOW_FACTORY_ERROR_MSG: { 1202 Dialog d = new FactoryErrorDialog( 1203 mContext, msg.getData().getCharSequence("msg")); 1204 d.show(); 1205 ensureBootCompleted(); 1206 } break; 1207 case UPDATE_CONFIGURATION_MSG: { 1208 final ContentResolver resolver = mContext.getContentResolver(); 1209 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1210 } break; 1211 case GC_BACKGROUND_PROCESSES_MSG: { 1212 synchronized (ActivityManagerService.this) { 1213 performAppGcsIfAppropriateLocked(); 1214 } 1215 } break; 1216 case WAIT_FOR_DEBUGGER_MSG: { 1217 synchronized (ActivityManagerService.this) { 1218 ProcessRecord app = (ProcessRecord)msg.obj; 1219 if (msg.arg1 != 0) { 1220 if (!app.waitedForDebugger) { 1221 Dialog d = new AppWaitingForDebuggerDialog( 1222 ActivityManagerService.this, 1223 mContext, app); 1224 app.waitDialog = d; 1225 app.waitedForDebugger = true; 1226 d.show(); 1227 } 1228 } else { 1229 if (app.waitDialog != null) { 1230 app.waitDialog.dismiss(); 1231 app.waitDialog = null; 1232 } 1233 } 1234 } 1235 } break; 1236 case SERVICE_TIMEOUT_MSG: { 1237 if (mDidDexOpt) { 1238 mDidDexOpt = false; 1239 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1240 nmsg.obj = msg.obj; 1241 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1242 return; 1243 } 1244 mServices.serviceTimeout((ProcessRecord)msg.obj); 1245 } break; 1246 case UPDATE_TIME_ZONE: { 1247 synchronized (ActivityManagerService.this) { 1248 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1249 ProcessRecord r = mLruProcesses.get(i); 1250 if (r.thread != null) { 1251 try { 1252 r.thread.updateTimeZone(); 1253 } catch (RemoteException ex) { 1254 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1255 } 1256 } 1257 } 1258 } 1259 } break; 1260 case CLEAR_DNS_CACHE_MSG: { 1261 synchronized (ActivityManagerService.this) { 1262 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1263 ProcessRecord r = mLruProcesses.get(i); 1264 if (r.thread != null) { 1265 try { 1266 r.thread.clearDnsCache(); 1267 } catch (RemoteException ex) { 1268 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1269 } 1270 } 1271 } 1272 } 1273 } break; 1274 case UPDATE_HTTP_PROXY_MSG: { 1275 ProxyProperties proxy = (ProxyProperties)msg.obj; 1276 String host = ""; 1277 String port = ""; 1278 String exclList = ""; 1279 String pacFileUrl = null; 1280 if (proxy != null) { 1281 host = proxy.getHost(); 1282 port = Integer.toString(proxy.getPort()); 1283 exclList = proxy.getExclusionList(); 1284 pacFileUrl = proxy.getPacFileUrl(); 1285 } 1286 synchronized (ActivityManagerService.this) { 1287 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1288 ProcessRecord r = mLruProcesses.get(i); 1289 if (r.thread != null) { 1290 try { 1291 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1292 } catch (RemoteException ex) { 1293 Slog.w(TAG, "Failed to update http proxy for: " + 1294 r.info.processName); 1295 } 1296 } 1297 } 1298 } 1299 } break; 1300 case SHOW_UID_ERROR_MSG: { 1301 String title = "System UIDs Inconsistent"; 1302 String text = "UIDs on the system are inconsistent, you need to wipe your" 1303 + " data partition or your device will be unstable."; 1304 Log.e(TAG, title + ": " + text); 1305 if (mShowDialogs) { 1306 // XXX This is a temporary dialog, no need to localize. 1307 AlertDialog d = new BaseErrorDialog(mContext); 1308 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1309 d.setCancelable(false); 1310 d.setTitle(title); 1311 d.setMessage(text); 1312 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1313 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1314 mUidAlert = d; 1315 d.show(); 1316 } 1317 } break; 1318 case IM_FEELING_LUCKY_MSG: { 1319 if (mUidAlert != null) { 1320 mUidAlert.dismiss(); 1321 mUidAlert = null; 1322 } 1323 } break; 1324 case PROC_START_TIMEOUT_MSG: { 1325 if (mDidDexOpt) { 1326 mDidDexOpt = false; 1327 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1328 nmsg.obj = msg.obj; 1329 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1330 return; 1331 } 1332 ProcessRecord app = (ProcessRecord)msg.obj; 1333 synchronized (ActivityManagerService.this) { 1334 processStartTimedOutLocked(app); 1335 } 1336 } break; 1337 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1338 synchronized (ActivityManagerService.this) { 1339 doPendingActivityLaunchesLocked(true); 1340 } 1341 } break; 1342 case KILL_APPLICATION_MSG: { 1343 synchronized (ActivityManagerService.this) { 1344 int appid = msg.arg1; 1345 boolean restart = (msg.arg2 == 1); 1346 Bundle bundle = (Bundle)msg.obj; 1347 String pkg = bundle.getString("pkg"); 1348 String reason = bundle.getString("reason"); 1349 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1350 false, UserHandle.USER_ALL, reason); 1351 } 1352 } break; 1353 case FINALIZE_PENDING_INTENT_MSG: { 1354 ((PendingIntentRecord)msg.obj).completeFinalize(); 1355 } break; 1356 case POST_HEAVY_NOTIFICATION_MSG: { 1357 INotificationManager inm = NotificationManager.getService(); 1358 if (inm == null) { 1359 return; 1360 } 1361 1362 ActivityRecord root = (ActivityRecord)msg.obj; 1363 ProcessRecord process = root.app; 1364 if (process == null) { 1365 return; 1366 } 1367 1368 try { 1369 Context context = mContext.createPackageContext(process.info.packageName, 0); 1370 String text = mContext.getString(R.string.heavy_weight_notification, 1371 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1372 Notification notification = new Notification(); 1373 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1374 notification.when = 0; 1375 notification.flags = Notification.FLAG_ONGOING_EVENT; 1376 notification.tickerText = text; 1377 notification.defaults = 0; // please be quiet 1378 notification.sound = null; 1379 notification.vibrate = null; 1380 notification.setLatestEventInfo(context, text, 1381 mContext.getText(R.string.heavy_weight_notification_detail), 1382 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1383 PendingIntent.FLAG_CANCEL_CURRENT, null, 1384 new UserHandle(root.userId))); 1385 1386 try { 1387 int[] outId = new int[1]; 1388 inm.enqueueNotificationWithTag("android", "android", null, 1389 R.string.heavy_weight_notification, 1390 notification, outId, root.userId); 1391 } catch (RuntimeException e) { 1392 Slog.w(ActivityManagerService.TAG, 1393 "Error showing notification for heavy-weight app", e); 1394 } catch (RemoteException e) { 1395 } 1396 } catch (NameNotFoundException e) { 1397 Slog.w(TAG, "Unable to create context for heavy notification", e); 1398 } 1399 } break; 1400 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1401 INotificationManager inm = NotificationManager.getService(); 1402 if (inm == null) { 1403 return; 1404 } 1405 try { 1406 inm.cancelNotificationWithTag("android", null, 1407 R.string.heavy_weight_notification, msg.arg1); 1408 } catch (RuntimeException e) { 1409 Slog.w(ActivityManagerService.TAG, 1410 "Error canceling notification for service", e); 1411 } catch (RemoteException e) { 1412 } 1413 } break; 1414 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1415 synchronized (ActivityManagerService.this) { 1416 checkExcessivePowerUsageLocked(true); 1417 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1418 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1419 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1420 } 1421 } break; 1422 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1423 synchronized (ActivityManagerService.this) { 1424 ActivityRecord ar = (ActivityRecord)msg.obj; 1425 if (mCompatModeDialog != null) { 1426 if (mCompatModeDialog.mAppInfo.packageName.equals( 1427 ar.info.applicationInfo.packageName)) { 1428 return; 1429 } 1430 mCompatModeDialog.dismiss(); 1431 mCompatModeDialog = null; 1432 } 1433 if (ar != null && false) { 1434 if (mCompatModePackages.getPackageAskCompatModeLocked( 1435 ar.packageName)) { 1436 int mode = mCompatModePackages.computeCompatModeLocked( 1437 ar.info.applicationInfo); 1438 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1439 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1440 mCompatModeDialog = new CompatModeDialog( 1441 ActivityManagerService.this, mContext, 1442 ar.info.applicationInfo); 1443 mCompatModeDialog.show(); 1444 } 1445 } 1446 } 1447 } 1448 break; 1449 } 1450 case DISPATCH_PROCESSES_CHANGED: { 1451 dispatchProcessesChanged(); 1452 break; 1453 } 1454 case DISPATCH_PROCESS_DIED: { 1455 final int pid = msg.arg1; 1456 final int uid = msg.arg2; 1457 dispatchProcessDied(pid, uid); 1458 break; 1459 } 1460 case REPORT_MEM_USAGE_MSG: { 1461 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1462 Thread thread = new Thread() { 1463 @Override public void run() { 1464 final SparseArray<ProcessMemInfo> infoMap 1465 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1466 for (int i=0, N=memInfos.size(); i<N; i++) { 1467 ProcessMemInfo mi = memInfos.get(i); 1468 infoMap.put(mi.pid, mi); 1469 } 1470 updateCpuStatsNow(); 1471 synchronized (mProcessCpuThread) { 1472 final int N = mProcessCpuTracker.countStats(); 1473 for (int i=0; i<N; i++) { 1474 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1475 if (st.vsize > 0) { 1476 long pss = Debug.getPss(st.pid, null); 1477 if (pss > 0) { 1478 if (infoMap.indexOfKey(st.pid) < 0) { 1479 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1480 ProcessList.NATIVE_ADJ, -1, "native", null); 1481 mi.pss = pss; 1482 memInfos.add(mi); 1483 } 1484 } 1485 } 1486 } 1487 } 1488 1489 long totalPss = 0; 1490 for (int i=0, N=memInfos.size(); i<N; i++) { 1491 ProcessMemInfo mi = memInfos.get(i); 1492 if (mi.pss == 0) { 1493 mi.pss = Debug.getPss(mi.pid, null); 1494 } 1495 totalPss += mi.pss; 1496 } 1497 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1498 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1499 if (lhs.oomAdj != rhs.oomAdj) { 1500 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1501 } 1502 if (lhs.pss != rhs.pss) { 1503 return lhs.pss < rhs.pss ? 1 : -1; 1504 } 1505 return 0; 1506 } 1507 }); 1508 1509 StringBuilder tag = new StringBuilder(128); 1510 StringBuilder stack = new StringBuilder(128); 1511 tag.append("Low on memory -- "); 1512 appendMemBucket(tag, totalPss, "total", false); 1513 appendMemBucket(stack, totalPss, "total", true); 1514 1515 StringBuilder logBuilder = new StringBuilder(1024); 1516 logBuilder.append("Low on memory:\n"); 1517 1518 boolean firstLine = true; 1519 int lastOomAdj = Integer.MIN_VALUE; 1520 for (int i=0, N=memInfos.size(); i<N; i++) { 1521 ProcessMemInfo mi = memInfos.get(i); 1522 1523 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1524 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1525 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1526 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1527 if (lastOomAdj != mi.oomAdj) { 1528 lastOomAdj = mi.oomAdj; 1529 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1530 tag.append(" / "); 1531 } 1532 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1533 if (firstLine) { 1534 stack.append(":"); 1535 firstLine = false; 1536 } 1537 stack.append("\n\t at "); 1538 } else { 1539 stack.append("$"); 1540 } 1541 } else { 1542 tag.append(" "); 1543 stack.append("$"); 1544 } 1545 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1546 appendMemBucket(tag, mi.pss, mi.name, false); 1547 } 1548 appendMemBucket(stack, mi.pss, mi.name, true); 1549 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1550 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1551 stack.append("("); 1552 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1553 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1554 stack.append(DUMP_MEM_OOM_LABEL[k]); 1555 stack.append(":"); 1556 stack.append(DUMP_MEM_OOM_ADJ[k]); 1557 } 1558 } 1559 stack.append(")"); 1560 } 1561 } 1562 1563 logBuilder.append(" "); 1564 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1565 logBuilder.append(' '); 1566 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1567 logBuilder.append(' '); 1568 ProcessList.appendRamKb(logBuilder, mi.pss); 1569 logBuilder.append(" kB: "); 1570 logBuilder.append(mi.name); 1571 logBuilder.append(" ("); 1572 logBuilder.append(mi.pid); 1573 logBuilder.append(") "); 1574 logBuilder.append(mi.adjType); 1575 logBuilder.append('\n'); 1576 if (mi.adjReason != null) { 1577 logBuilder.append(" "); 1578 logBuilder.append(mi.adjReason); 1579 logBuilder.append('\n'); 1580 } 1581 } 1582 1583 logBuilder.append(" "); 1584 ProcessList.appendRamKb(logBuilder, totalPss); 1585 logBuilder.append(" kB: TOTAL\n"); 1586 1587 long[] infos = new long[Debug.MEMINFO_COUNT]; 1588 Debug.getMemInfo(infos); 1589 logBuilder.append(" MemInfo: "); 1590 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1591 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1592 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1593 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1594 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1595 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1596 logBuilder.append(" ZRAM: "); 1597 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1598 logBuilder.append(" kB RAM, "); 1599 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1600 logBuilder.append(" kB swap total, "); 1601 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1602 logBuilder.append(" kB swap free\n"); 1603 } 1604 Slog.i(TAG, logBuilder.toString()); 1605 1606 StringBuilder dropBuilder = new StringBuilder(1024); 1607 /* 1608 StringWriter oomSw = new StringWriter(); 1609 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1610 StringWriter catSw = new StringWriter(); 1611 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1612 String[] emptyArgs = new String[] { }; 1613 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1614 oomPw.flush(); 1615 String oomString = oomSw.toString(); 1616 */ 1617 dropBuilder.append(stack); 1618 dropBuilder.append('\n'); 1619 dropBuilder.append('\n'); 1620 dropBuilder.append(logBuilder); 1621 dropBuilder.append('\n'); 1622 /* 1623 dropBuilder.append(oomString); 1624 dropBuilder.append('\n'); 1625 */ 1626 StringWriter catSw = new StringWriter(); 1627 synchronized (ActivityManagerService.this) { 1628 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1629 String[] emptyArgs = new String[] { }; 1630 catPw.println(); 1631 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1632 catPw.println(); 1633 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1634 false, false, null); 1635 catPw.println(); 1636 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1637 catPw.flush(); 1638 } 1639 dropBuilder.append(catSw.toString()); 1640 addErrorToDropBox("lowmem", null, "system_server", null, 1641 null, tag.toString(), dropBuilder.toString(), null, null); 1642 //Slog.i(TAG, "Sent to dropbox:"); 1643 //Slog.i(TAG, dropBuilder.toString()); 1644 synchronized (ActivityManagerService.this) { 1645 long now = SystemClock.uptimeMillis(); 1646 if (mLastMemUsageReportTime < now) { 1647 mLastMemUsageReportTime = now; 1648 } 1649 } 1650 } 1651 }; 1652 thread.start(); 1653 break; 1654 } 1655 case REPORT_USER_SWITCH_MSG: { 1656 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1657 break; 1658 } 1659 case CONTINUE_USER_SWITCH_MSG: { 1660 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1661 break; 1662 } 1663 case USER_SWITCH_TIMEOUT_MSG: { 1664 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1665 break; 1666 } 1667 case IMMERSIVE_MODE_LOCK_MSG: { 1668 final boolean nextState = (msg.arg1 != 0); 1669 if (mUpdateLock.isHeld() != nextState) { 1670 if (DEBUG_IMMERSIVE) { 1671 final ActivityRecord r = (ActivityRecord) msg.obj; 1672 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1673 } 1674 if (nextState) { 1675 mUpdateLock.acquire(); 1676 } else { 1677 mUpdateLock.release(); 1678 } 1679 } 1680 break; 1681 } 1682 case PERSIST_URI_GRANTS_MSG: { 1683 writeGrantedUriPermissions(); 1684 break; 1685 } 1686 case REQUEST_ALL_PSS_MSG: { 1687 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1688 break; 1689 } 1690 case START_RELATED_USERS_MSG: { 1691 synchronized (ActivityManagerService.this) { 1692 startRelatedUsersLocked(); 1693 } 1694 break; 1695 } 1696 } 1697 } 1698 }; 1699 1700 static final int COLLECT_PSS_BG_MSG = 1; 1701 1702 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1703 @Override 1704 public void handleMessage(Message msg) { 1705 switch (msg.what) { 1706 case COLLECT_PSS_BG_MSG: { 1707 int i=0, num=0; 1708 long start = SystemClock.uptimeMillis(); 1709 long[] tmp = new long[1]; 1710 do { 1711 ProcessRecord proc; 1712 int procState; 1713 int pid; 1714 synchronized (ActivityManagerService.this) { 1715 if (i >= mPendingPssProcesses.size()) { 1716 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1717 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1718 mPendingPssProcesses.clear(); 1719 return; 1720 } 1721 proc = mPendingPssProcesses.get(i); 1722 procState = proc.pssProcState; 1723 if (proc.thread != null && procState == proc.setProcState) { 1724 pid = proc.pid; 1725 } else { 1726 proc = null; 1727 pid = 0; 1728 } 1729 i++; 1730 } 1731 if (proc != null) { 1732 long pss = Debug.getPss(pid, tmp); 1733 synchronized (ActivityManagerService.this) { 1734 if (proc.thread != null && proc.setProcState == procState 1735 && proc.pid == pid) { 1736 num++; 1737 proc.lastPssTime = SystemClock.uptimeMillis(); 1738 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1739 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1740 + ": " + pss + " lastPss=" + proc.lastPss 1741 + " state=" + ProcessList.makeProcStateString(procState)); 1742 if (proc.initialIdlePss == 0) { 1743 proc.initialIdlePss = pss; 1744 } 1745 proc.lastPss = pss; 1746 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1747 proc.lastCachedPss = pss; 1748 } 1749 } 1750 } 1751 } 1752 } while (true); 1753 } 1754 } 1755 } 1756 }; 1757 1758 public void setSystemProcess() { 1759 try { 1760 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1761 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1762 ServiceManager.addService("meminfo", new MemBinder(this)); 1763 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1764 ServiceManager.addService("dbinfo", new DbBinder(this)); 1765 if (MONITOR_CPU_USAGE) { 1766 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1767 } 1768 ServiceManager.addService("permission", new PermissionController(this)); 1769 1770 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1771 "android", STOCK_PM_FLAGS); 1772 mSystemThread.installSystemApplicationInfo(info); 1773 1774 synchronized (this) { 1775 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1776 app.persistent = true; 1777 app.pid = MY_PID; 1778 app.maxAdj = ProcessList.SYSTEM_ADJ; 1779 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1780 mProcessNames.put(app.processName, app.uid, app); 1781 synchronized (mPidsSelfLocked) { 1782 mPidsSelfLocked.put(app.pid, app); 1783 } 1784 updateLruProcessLocked(app, false, null); 1785 updateOomAdjLocked(); 1786 } 1787 } catch (PackageManager.NameNotFoundException e) { 1788 throw new RuntimeException( 1789 "Unable to find android system package", e); 1790 } 1791 } 1792 1793 public void setWindowManager(WindowManagerService wm) { 1794 mWindowManager = wm; 1795 mStackSupervisor.setWindowManager(wm); 1796 } 1797 1798 public void startObservingNativeCrashes() { 1799 final NativeCrashListener ncl = new NativeCrashListener(this); 1800 ncl.start(); 1801 } 1802 1803 public IAppOpsService getAppOpsService() { 1804 return mAppOpsService; 1805 } 1806 1807 static class MemBinder extends Binder { 1808 ActivityManagerService mActivityManagerService; 1809 MemBinder(ActivityManagerService activityManagerService) { 1810 mActivityManagerService = activityManagerService; 1811 } 1812 1813 @Override 1814 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1815 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1816 != PackageManager.PERMISSION_GRANTED) { 1817 pw.println("Permission Denial: can't dump meminfo from from pid=" 1818 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1819 + " without permission " + android.Manifest.permission.DUMP); 1820 return; 1821 } 1822 1823 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1824 } 1825 } 1826 1827 static class GraphicsBinder extends Binder { 1828 ActivityManagerService mActivityManagerService; 1829 GraphicsBinder(ActivityManagerService activityManagerService) { 1830 mActivityManagerService = activityManagerService; 1831 } 1832 1833 @Override 1834 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1835 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1836 != PackageManager.PERMISSION_GRANTED) { 1837 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1838 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1839 + " without permission " + android.Manifest.permission.DUMP); 1840 return; 1841 } 1842 1843 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1844 } 1845 } 1846 1847 static class DbBinder extends Binder { 1848 ActivityManagerService mActivityManagerService; 1849 DbBinder(ActivityManagerService activityManagerService) { 1850 mActivityManagerService = activityManagerService; 1851 } 1852 1853 @Override 1854 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1855 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1856 != PackageManager.PERMISSION_GRANTED) { 1857 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1858 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1859 + " without permission " + android.Manifest.permission.DUMP); 1860 return; 1861 } 1862 1863 mActivityManagerService.dumpDbInfo(fd, pw, args); 1864 } 1865 } 1866 1867 static class CpuBinder extends Binder { 1868 ActivityManagerService mActivityManagerService; 1869 CpuBinder(ActivityManagerService activityManagerService) { 1870 mActivityManagerService = activityManagerService; 1871 } 1872 1873 @Override 1874 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1875 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1876 != PackageManager.PERMISSION_GRANTED) { 1877 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1878 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1879 + " without permission " + android.Manifest.permission.DUMP); 1880 return; 1881 } 1882 1883 synchronized (mActivityManagerService.mProcessCpuThread) { 1884 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1885 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1886 SystemClock.uptimeMillis())); 1887 } 1888 } 1889 } 1890 1891 public static final class Lifecycle extends SystemService { 1892 private final ActivityManagerService mService; 1893 1894 public Lifecycle(Context context) { 1895 super(context); 1896 mService = new ActivityManagerService(context); 1897 } 1898 1899 @Override 1900 public void onStart() { 1901 mService.start(); 1902 } 1903 1904 public ActivityManagerService getService() { 1905 return mService; 1906 } 1907 } 1908 1909 // Note: This method is invoked on the main thread but may need to attach various 1910 // handlers to other threads. So take care to be explicit about the looper. 1911 public ActivityManagerService(Context systemContext) { 1912 mContext = systemContext; 1913 mFactoryTest = FactoryTest.getMode(); 1914 mSystemThread = ActivityThread.currentActivityThread(); 1915 1916 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1917 1918 mHandlerThread = new ServiceThread(TAG, 1919 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1920 mHandlerThread.start(); 1921 mHandler = new MainHandler(mHandlerThread.getLooper()); 1922 1923 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1924 "foreground", BROADCAST_FG_TIMEOUT, false); 1925 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1926 "background", BROADCAST_BG_TIMEOUT, true); 1927 mBroadcastQueues[0] = mFgBroadcastQueue; 1928 mBroadcastQueues[1] = mBgBroadcastQueue; 1929 1930 mServices = new ActiveServices(this); 1931 mProviderMap = new ProviderMap(this); 1932 1933 // TODO: Move creation of battery stats service outside of activity manager service. 1934 File dataDir = Environment.getDataDirectory(); 1935 File systemDir = new File(dataDir, "system"); 1936 systemDir.mkdirs(); 1937 mBatteryStatsService = new BatteryStatsService(new File( 1938 systemDir, "batterystats.bin").toString(), mHandler); 1939 mBatteryStatsService.getActiveStatistics().readLocked(); 1940 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1941 mOnBattery = DEBUG_POWER ? true 1942 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1943 mBatteryStatsService.getActiveStatistics().setCallback(this); 1944 1945 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1946 1947 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1948 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1949 1950 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1951 1952 // User 0 is the first and only user that runs at boot. 1953 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1954 mUserLru.add(Integer.valueOf(0)); 1955 updateStartedUserArrayLocked(); 1956 1957 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1958 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1959 1960 mConfiguration.setToDefaults(); 1961 mConfiguration.setLocale(Locale.getDefault()); 1962 1963 mConfigurationSeq = mConfiguration.seq = 1; 1964 mProcessCpuTracker.init(); 1965 1966 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1967 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1968 mStackSupervisor = new ActivityStackSupervisor(this); 1969 1970 mProcessCpuThread = new Thread("CpuTracker") { 1971 @Override 1972 public void run() { 1973 while (true) { 1974 try { 1975 try { 1976 synchronized(this) { 1977 final long now = SystemClock.uptimeMillis(); 1978 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1979 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1980 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1981 // + ", write delay=" + nextWriteDelay); 1982 if (nextWriteDelay < nextCpuDelay) { 1983 nextCpuDelay = nextWriteDelay; 1984 } 1985 if (nextCpuDelay > 0) { 1986 mProcessCpuMutexFree.set(true); 1987 this.wait(nextCpuDelay); 1988 } 1989 } 1990 } catch (InterruptedException e) { 1991 } 1992 updateCpuStatsNow(); 1993 } catch (Exception e) { 1994 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1995 } 1996 } 1997 } 1998 }; 1999 2000 Watchdog.getInstance().addMonitor(this); 2001 Watchdog.getInstance().addThread(mHandler); 2002 } 2003 2004 private void start() { 2005 mProcessCpuThread.start(); 2006 2007 mBatteryStatsService.publish(mContext); 2008 mUsageStatsService.publish(mContext); 2009 mAppOpsService.publish(mContext); 2010 startRunning(null, null, null, null); 2011 } 2012 2013 @Override 2014 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2015 throws RemoteException { 2016 if (code == SYSPROPS_TRANSACTION) { 2017 // We need to tell all apps about the system property change. 2018 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2019 synchronized(this) { 2020 final int NP = mProcessNames.getMap().size(); 2021 for (int ip=0; ip<NP; ip++) { 2022 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2023 final int NA = apps.size(); 2024 for (int ia=0; ia<NA; ia++) { 2025 ProcessRecord app = apps.valueAt(ia); 2026 if (app.thread != null) { 2027 procs.add(app.thread.asBinder()); 2028 } 2029 } 2030 } 2031 } 2032 2033 int N = procs.size(); 2034 for (int i=0; i<N; i++) { 2035 Parcel data2 = Parcel.obtain(); 2036 try { 2037 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2038 } catch (RemoteException e) { 2039 } 2040 data2.recycle(); 2041 } 2042 } 2043 try { 2044 return super.onTransact(code, data, reply, flags); 2045 } catch (RuntimeException e) { 2046 // The activity manager only throws security exceptions, so let's 2047 // log all others. 2048 if (!(e instanceof SecurityException)) { 2049 Slog.wtf(TAG, "Activity Manager Crash", e); 2050 } 2051 throw e; 2052 } 2053 } 2054 2055 void updateCpuStats() { 2056 final long now = SystemClock.uptimeMillis(); 2057 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2058 return; 2059 } 2060 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2061 synchronized (mProcessCpuThread) { 2062 mProcessCpuThread.notify(); 2063 } 2064 } 2065 } 2066 2067 void updateCpuStatsNow() { 2068 synchronized (mProcessCpuThread) { 2069 mProcessCpuMutexFree.set(false); 2070 final long now = SystemClock.uptimeMillis(); 2071 boolean haveNewCpuStats = false; 2072 2073 if (MONITOR_CPU_USAGE && 2074 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2075 mLastCpuTime.set(now); 2076 haveNewCpuStats = true; 2077 mProcessCpuTracker.update(); 2078 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2079 //Slog.i(TAG, "Total CPU usage: " 2080 // + mProcessCpu.getTotalCpuPercent() + "%"); 2081 2082 // Slog the cpu usage if the property is set. 2083 if ("true".equals(SystemProperties.get("events.cpu"))) { 2084 int user = mProcessCpuTracker.getLastUserTime(); 2085 int system = mProcessCpuTracker.getLastSystemTime(); 2086 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2087 int irq = mProcessCpuTracker.getLastIrqTime(); 2088 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2089 int idle = mProcessCpuTracker.getLastIdleTime(); 2090 2091 int total = user + system + iowait + irq + softIrq + idle; 2092 if (total == 0) total = 1; 2093 2094 EventLog.writeEvent(EventLogTags.CPU, 2095 ((user+system+iowait+irq+softIrq) * 100) / total, 2096 (user * 100) / total, 2097 (system * 100) / total, 2098 (iowait * 100) / total, 2099 (irq * 100) / total, 2100 (softIrq * 100) / total); 2101 } 2102 } 2103 2104 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2105 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2106 synchronized(bstats) { 2107 synchronized(mPidsSelfLocked) { 2108 if (haveNewCpuStats) { 2109 if (mOnBattery) { 2110 int perc = bstats.startAddingCpuLocked(); 2111 int totalUTime = 0; 2112 int totalSTime = 0; 2113 final int N = mProcessCpuTracker.countStats(); 2114 for (int i=0; i<N; i++) { 2115 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2116 if (!st.working) { 2117 continue; 2118 } 2119 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2120 int otherUTime = (st.rel_utime*perc)/100; 2121 int otherSTime = (st.rel_stime*perc)/100; 2122 totalUTime += otherUTime; 2123 totalSTime += otherSTime; 2124 if (pr != null) { 2125 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2126 if (ps == null || !ps.isActive()) { 2127 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2128 pr.info.uid, pr.processName); 2129 } 2130 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2131 st.rel_stime-otherSTime); 2132 ps.addSpeedStepTimes(cpuSpeedTimes); 2133 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2134 } else { 2135 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2136 if (ps == null || !ps.isActive()) { 2137 st.batteryStats = ps = bstats.getProcessStatsLocked( 2138 bstats.mapUid(st.uid), st.name); 2139 } 2140 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2141 st.rel_stime-otherSTime); 2142 ps.addSpeedStepTimes(cpuSpeedTimes); 2143 } 2144 } 2145 bstats.finishAddingCpuLocked(perc, totalUTime, 2146 totalSTime, cpuSpeedTimes); 2147 } 2148 } 2149 } 2150 2151 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2152 mLastWriteTime = now; 2153 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2154 } 2155 } 2156 } 2157 } 2158 2159 @Override 2160 public void batteryNeedsCpuUpdate() { 2161 updateCpuStatsNow(); 2162 } 2163 2164 @Override 2165 public void batteryPowerChanged(boolean onBattery) { 2166 // When plugging in, update the CPU stats first before changing 2167 // the plug state. 2168 updateCpuStatsNow(); 2169 synchronized (this) { 2170 synchronized(mPidsSelfLocked) { 2171 mOnBattery = DEBUG_POWER ? true : onBattery; 2172 } 2173 } 2174 } 2175 2176 /** 2177 * Initialize the application bind args. These are passed to each 2178 * process when the bindApplication() IPC is sent to the process. They're 2179 * lazily setup to make sure the services are running when they're asked for. 2180 */ 2181 private HashMap<String, IBinder> getCommonServicesLocked() { 2182 if (mAppBindArgs == null) { 2183 mAppBindArgs = new HashMap<String, IBinder>(); 2184 2185 // Setup the application init args 2186 mAppBindArgs.put("package", ServiceManager.getService("package")); 2187 mAppBindArgs.put("window", ServiceManager.getService("window")); 2188 mAppBindArgs.put(Context.ALARM_SERVICE, 2189 ServiceManager.getService(Context.ALARM_SERVICE)); 2190 } 2191 return mAppBindArgs; 2192 } 2193 2194 final void setFocusedActivityLocked(ActivityRecord r) { 2195 if (mFocusedActivity != r) { 2196 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2197 mFocusedActivity = r; 2198 mStackSupervisor.setFocusedStack(r); 2199 if (r != null) { 2200 mWindowManager.setFocusedApp(r.appToken, true); 2201 } 2202 applyUpdateLockStateLocked(r); 2203 } 2204 } 2205 2206 @Override 2207 public void setFocusedStack(int stackId) { 2208 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2209 synchronized (ActivityManagerService.this) { 2210 ActivityStack stack = mStackSupervisor.getStack(stackId); 2211 if (stack != null) { 2212 ActivityRecord r = stack.topRunningActivityLocked(null); 2213 if (r != null) { 2214 setFocusedActivityLocked(r); 2215 } 2216 } 2217 } 2218 } 2219 2220 @Override 2221 public void notifyActivityDrawn(IBinder token) { 2222 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2223 synchronized (this) { 2224 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2225 if (r != null) { 2226 r.task.stack.notifyActivityDrawnLocked(r); 2227 } 2228 } 2229 } 2230 2231 final void applyUpdateLockStateLocked(ActivityRecord r) { 2232 // Modifications to the UpdateLock state are done on our handler, outside 2233 // the activity manager's locks. The new state is determined based on the 2234 // state *now* of the relevant activity record. The object is passed to 2235 // the handler solely for logging detail, not to be consulted/modified. 2236 final boolean nextState = r != null && r.immersive; 2237 mHandler.sendMessage( 2238 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2239 } 2240 2241 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2242 Message msg = Message.obtain(); 2243 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2244 msg.obj = r.task.askedCompatMode ? null : r; 2245 mHandler.sendMessage(msg); 2246 } 2247 2248 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2249 String what, Object obj, ProcessRecord srcApp) { 2250 app.lastActivityTime = now; 2251 2252 if (app.activities.size() > 0) { 2253 // Don't want to touch dependent processes that are hosting activities. 2254 return index; 2255 } 2256 2257 int lrui = mLruProcesses.lastIndexOf(app); 2258 if (lrui < 0) { 2259 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2260 + what + " " + obj + " from " + srcApp); 2261 return index; 2262 } 2263 2264 if (lrui >= index) { 2265 // Don't want to cause this to move dependent processes *back* in the 2266 // list as if they were less frequently used. 2267 return index; 2268 } 2269 2270 if (lrui >= mLruProcessActivityStart) { 2271 // Don't want to touch dependent processes that are hosting activities. 2272 return index; 2273 } 2274 2275 mLruProcesses.remove(lrui); 2276 if (index > 0) { 2277 index--; 2278 } 2279 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2280 + " in LRU list: " + app); 2281 mLruProcesses.add(index, app); 2282 return index; 2283 } 2284 2285 final void removeLruProcessLocked(ProcessRecord app) { 2286 int lrui = mLruProcesses.lastIndexOf(app); 2287 if (lrui >= 0) { 2288 if (lrui <= mLruProcessActivityStart) { 2289 mLruProcessActivityStart--; 2290 } 2291 if (lrui <= mLruProcessServiceStart) { 2292 mLruProcessServiceStart--; 2293 } 2294 mLruProcesses.remove(lrui); 2295 } 2296 } 2297 2298 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2299 ProcessRecord client) { 2300 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities; 2301 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2302 if (!activityChange && hasActivity) { 2303 // The process has activties, so we are only going to allow activity-based 2304 // adjustments move it. It should be kept in the front of the list with other 2305 // processes that have activities, and we don't want those to change their 2306 // order except due to activity operations. 2307 return; 2308 } 2309 2310 mLruSeq++; 2311 final long now = SystemClock.uptimeMillis(); 2312 app.lastActivityTime = now; 2313 2314 // First a quick reject: if the app is already at the position we will 2315 // put it, then there is nothing to do. 2316 if (hasActivity) { 2317 final int N = mLruProcesses.size(); 2318 if (N > 0 && mLruProcesses.get(N-1) == app) { 2319 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2320 return; 2321 } 2322 } else { 2323 if (mLruProcessServiceStart > 0 2324 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2325 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2326 return; 2327 } 2328 } 2329 2330 int lrui = mLruProcesses.lastIndexOf(app); 2331 2332 if (app.persistent && lrui >= 0) { 2333 // We don't care about the position of persistent processes, as long as 2334 // they are in the list. 2335 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2336 return; 2337 } 2338 2339 /* In progress: compute new position first, so we can avoid doing work 2340 if the process is not actually going to move. Not yet working. 2341 int addIndex; 2342 int nextIndex; 2343 boolean inActivity = false, inService = false; 2344 if (hasActivity) { 2345 // Process has activities, put it at the very tipsy-top. 2346 addIndex = mLruProcesses.size(); 2347 nextIndex = mLruProcessServiceStart; 2348 inActivity = true; 2349 } else if (hasService) { 2350 // Process has services, put it at the top of the service list. 2351 addIndex = mLruProcessActivityStart; 2352 nextIndex = mLruProcessServiceStart; 2353 inActivity = true; 2354 inService = true; 2355 } else { 2356 // Process not otherwise of interest, it goes to the top of the non-service area. 2357 addIndex = mLruProcessServiceStart; 2358 if (client != null) { 2359 int clientIndex = mLruProcesses.lastIndexOf(client); 2360 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2361 + app); 2362 if (clientIndex >= 0 && addIndex > clientIndex) { 2363 addIndex = clientIndex; 2364 } 2365 } 2366 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2367 } 2368 2369 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2370 + mLruProcessActivityStart + "): " + app); 2371 */ 2372 2373 if (lrui >= 0) { 2374 if (lrui < mLruProcessActivityStart) { 2375 mLruProcessActivityStart--; 2376 } 2377 if (lrui < mLruProcessServiceStart) { 2378 mLruProcessServiceStart--; 2379 } 2380 /* 2381 if (addIndex > lrui) { 2382 addIndex--; 2383 } 2384 if (nextIndex > lrui) { 2385 nextIndex--; 2386 } 2387 */ 2388 mLruProcesses.remove(lrui); 2389 } 2390 2391 /* 2392 mLruProcesses.add(addIndex, app); 2393 if (inActivity) { 2394 mLruProcessActivityStart++; 2395 } 2396 if (inService) { 2397 mLruProcessActivityStart++; 2398 } 2399 */ 2400 2401 int nextIndex; 2402 if (hasActivity) { 2403 final int N = mLruProcesses.size(); 2404 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2405 // Process doesn't have activities, but has clients with 2406 // activities... move it up, but one below the top (the top 2407 // should always have a real activity). 2408 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2409 mLruProcesses.add(N-1, app); 2410 // To keep it from spamming the LRU list (by making a bunch of clients), 2411 // we will push down any other entries owned by the app. 2412 final int uid = app.info.uid; 2413 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2414 ProcessRecord subProc = mLruProcesses.get(i); 2415 if (subProc.info.uid == uid) { 2416 // We want to push this one down the list. If the process after 2417 // it is for the same uid, however, don't do so, because we don't 2418 // want them internally to be re-ordered. 2419 if (mLruProcesses.get(i-1).info.uid != uid) { 2420 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2421 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2422 ProcessRecord tmp = mLruProcesses.get(i); 2423 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2424 mLruProcesses.set(i-1, tmp); 2425 i--; 2426 } 2427 } else { 2428 // A gap, we can stop here. 2429 break; 2430 } 2431 } 2432 } else { 2433 // Process has activities, put it at the very tipsy-top. 2434 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2435 mLruProcesses.add(app); 2436 } 2437 nextIndex = mLruProcessServiceStart; 2438 } else if (hasService) { 2439 // Process has services, put it at the top of the service list. 2440 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2441 mLruProcesses.add(mLruProcessActivityStart, app); 2442 nextIndex = mLruProcessServiceStart; 2443 mLruProcessActivityStart++; 2444 } else { 2445 // Process not otherwise of interest, it goes to the top of the non-service area. 2446 int index = mLruProcessServiceStart; 2447 if (client != null) { 2448 // If there is a client, don't allow the process to be moved up higher 2449 // in the list than that client. 2450 int clientIndex = mLruProcesses.lastIndexOf(client); 2451 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2452 + " when updating " + app); 2453 if (clientIndex <= lrui) { 2454 // Don't allow the client index restriction to push it down farther in the 2455 // list than it already is. 2456 clientIndex = lrui; 2457 } 2458 if (clientIndex >= 0 && index > clientIndex) { 2459 index = clientIndex; 2460 } 2461 } 2462 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2463 mLruProcesses.add(index, app); 2464 nextIndex = index-1; 2465 mLruProcessActivityStart++; 2466 mLruProcessServiceStart++; 2467 } 2468 2469 // If the app is currently using a content provider or service, 2470 // bump those processes as well. 2471 for (int j=app.connections.size()-1; j>=0; j--) { 2472 ConnectionRecord cr = app.connections.valueAt(j); 2473 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2474 && cr.binding.service.app != null 2475 && cr.binding.service.app.lruSeq != mLruSeq 2476 && !cr.binding.service.app.persistent) { 2477 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2478 "service connection", cr, app); 2479 } 2480 } 2481 for (int j=app.conProviders.size()-1; j>=0; j--) { 2482 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2483 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2484 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2485 "provider reference", cpr, app); 2486 } 2487 } 2488 } 2489 2490 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2491 if (uid == Process.SYSTEM_UID) { 2492 // The system gets to run in any process. If there are multiple 2493 // processes with the same uid, just pick the first (this 2494 // should never happen). 2495 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2496 if (procs == null) return null; 2497 final int N = procs.size(); 2498 for (int i = 0; i < N; i++) { 2499 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2500 } 2501 } 2502 ProcessRecord proc = mProcessNames.get(processName, uid); 2503 if (false && proc != null && !keepIfLarge 2504 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2505 && proc.lastCachedPss >= 4000) { 2506 // Turn this condition on to cause killing to happen regularly, for testing. 2507 if (proc.baseProcessTracker != null) { 2508 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2509 } 2510 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2511 + "k from cached"); 2512 } else if (proc != null && !keepIfLarge 2513 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2514 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2515 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2516 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2517 if (proc.baseProcessTracker != null) { 2518 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2519 } 2520 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2521 + "k from cached"); 2522 } 2523 } 2524 return proc; 2525 } 2526 2527 void ensurePackageDexOpt(String packageName) { 2528 IPackageManager pm = AppGlobals.getPackageManager(); 2529 try { 2530 if (pm.performDexOpt(packageName)) { 2531 mDidDexOpt = true; 2532 } 2533 } catch (RemoteException e) { 2534 } 2535 } 2536 2537 boolean isNextTransitionForward() { 2538 int transit = mWindowManager.getPendingAppTransition(); 2539 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2540 || transit == AppTransition.TRANSIT_TASK_OPEN 2541 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2542 } 2543 2544 final ProcessRecord startProcessLocked(String processName, 2545 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2546 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2547 boolean isolated, boolean keepIfLarge) { 2548 ProcessRecord app; 2549 if (!isolated) { 2550 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2551 } else { 2552 // If this is an isolated process, it can't re-use an existing process. 2553 app = null; 2554 } 2555 // We don't have to do anything more if: 2556 // (1) There is an existing application record; and 2557 // (2) The caller doesn't think it is dead, OR there is no thread 2558 // object attached to it so we know it couldn't have crashed; and 2559 // (3) There is a pid assigned to it, so it is either starting or 2560 // already running. 2561 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2562 + " app=" + app + " knownToBeDead=" + knownToBeDead 2563 + " thread=" + (app != null ? app.thread : null) 2564 + " pid=" + (app != null ? app.pid : -1)); 2565 if (app != null && app.pid > 0) { 2566 if (!knownToBeDead || app.thread == null) { 2567 // We already have the app running, or are waiting for it to 2568 // come up (we have a pid but not yet its thread), so keep it. 2569 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2570 // If this is a new package in the process, add the package to the list 2571 app.addPackage(info.packageName, mProcessStats); 2572 return app; 2573 } 2574 2575 // An application record is attached to a previous process, 2576 // clean it up now. 2577 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2578 handleAppDiedLocked(app, true, true); 2579 } 2580 2581 String hostingNameStr = hostingName != null 2582 ? hostingName.flattenToShortString() : null; 2583 2584 if (!isolated) { 2585 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2586 // If we are in the background, then check to see if this process 2587 // is bad. If so, we will just silently fail. 2588 if (mBadProcesses.get(info.processName, info.uid) != null) { 2589 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2590 + "/" + info.processName); 2591 return null; 2592 } 2593 } else { 2594 // When the user is explicitly starting a process, then clear its 2595 // crash count so that we won't make it bad until they see at 2596 // least one crash dialog again, and make the process good again 2597 // if it had been bad. 2598 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2599 + "/" + info.processName); 2600 mProcessCrashTimes.remove(info.processName, info.uid); 2601 if (mBadProcesses.get(info.processName, info.uid) != null) { 2602 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2603 UserHandle.getUserId(info.uid), info.uid, 2604 info.processName); 2605 mBadProcesses.remove(info.processName, info.uid); 2606 if (app != null) { 2607 app.bad = false; 2608 } 2609 } 2610 } 2611 } 2612 2613 if (app == null) { 2614 app = newProcessRecordLocked(info, processName, isolated); 2615 if (app == null) { 2616 Slog.w(TAG, "Failed making new process record for " 2617 + processName + "/" + info.uid + " isolated=" + isolated); 2618 return null; 2619 } 2620 mProcessNames.put(processName, app.uid, app); 2621 if (isolated) { 2622 mIsolatedProcesses.put(app.uid, app); 2623 } 2624 } else { 2625 // If this is a new package in the process, add the package to the list 2626 app.addPackage(info.packageName, mProcessStats); 2627 } 2628 2629 // If the system is not ready yet, then hold off on starting this 2630 // process until it is. 2631 if (!mProcessesReady 2632 && !isAllowedWhileBooting(info) 2633 && !allowWhileBooting) { 2634 if (!mProcessesOnHold.contains(app)) { 2635 mProcessesOnHold.add(app); 2636 } 2637 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2638 return app; 2639 } 2640 2641 startProcessLocked(app, hostingType, hostingNameStr); 2642 return (app.pid != 0) ? app : null; 2643 } 2644 2645 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2646 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2647 } 2648 2649 private final void startProcessLocked(ProcessRecord app, 2650 String hostingType, String hostingNameStr) { 2651 if (app.pid > 0 && app.pid != MY_PID) { 2652 synchronized (mPidsSelfLocked) { 2653 mPidsSelfLocked.remove(app.pid); 2654 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2655 } 2656 app.setPid(0); 2657 } 2658 2659 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2660 "startProcessLocked removing on hold: " + app); 2661 mProcessesOnHold.remove(app); 2662 2663 updateCpuStats(); 2664 2665 try { 2666 int uid = app.uid; 2667 2668 int[] gids = null; 2669 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2670 if (!app.isolated) { 2671 int[] permGids = null; 2672 try { 2673 final PackageManager pm = mContext.getPackageManager(); 2674 permGids = pm.getPackageGids(app.info.packageName); 2675 2676 if (Environment.isExternalStorageEmulated()) { 2677 if (pm.checkPermission( 2678 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2679 app.info.packageName) == PERMISSION_GRANTED) { 2680 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2681 } else { 2682 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2683 } 2684 } 2685 } catch (PackageManager.NameNotFoundException e) { 2686 Slog.w(TAG, "Unable to retrieve gids", e); 2687 } 2688 2689 /* 2690 * Add shared application GID so applications can share some 2691 * resources like shared libraries 2692 */ 2693 if (permGids == null) { 2694 gids = new int[1]; 2695 } else { 2696 gids = new int[permGids.length + 1]; 2697 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2698 } 2699 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2700 } 2701 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2702 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2703 && mTopComponent != null 2704 && app.processName.equals(mTopComponent.getPackageName())) { 2705 uid = 0; 2706 } 2707 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2708 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2709 uid = 0; 2710 } 2711 } 2712 int debugFlags = 0; 2713 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2714 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2715 // Also turn on CheckJNI for debuggable apps. It's quite 2716 // awkward to turn on otherwise. 2717 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2718 } 2719 // Run the app in safe mode if its manifest requests so or the 2720 // system is booted in safe mode. 2721 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2722 Zygote.systemInSafeMode == true) { 2723 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2724 } 2725 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2726 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2727 } 2728 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2729 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2730 } 2731 if ("1".equals(SystemProperties.get("debug.assert"))) { 2732 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2733 } 2734 2735 // Start the process. It will either succeed and return a result containing 2736 // the PID of the new process, or else throw a RuntimeException. 2737 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2738 app.processName, uid, uid, gids, debugFlags, mountExternal, 2739 app.info.targetSdkVersion, app.info.seinfo, null); 2740 2741 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2742 synchronized (bs) { 2743 if (bs.isOnBattery()) { 2744 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2745 } 2746 } 2747 2748 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2749 UserHandle.getUserId(uid), startResult.pid, uid, 2750 app.processName, hostingType, 2751 hostingNameStr != null ? hostingNameStr : ""); 2752 2753 if (app.persistent) { 2754 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2755 } 2756 2757 StringBuilder buf = mStringBuilder; 2758 buf.setLength(0); 2759 buf.append("Start proc "); 2760 buf.append(app.processName); 2761 buf.append(" for "); 2762 buf.append(hostingType); 2763 if (hostingNameStr != null) { 2764 buf.append(" "); 2765 buf.append(hostingNameStr); 2766 } 2767 buf.append(": pid="); 2768 buf.append(startResult.pid); 2769 buf.append(" uid="); 2770 buf.append(uid); 2771 buf.append(" gids={"); 2772 if (gids != null) { 2773 for (int gi=0; gi<gids.length; gi++) { 2774 if (gi != 0) buf.append(", "); 2775 buf.append(gids[gi]); 2776 2777 } 2778 } 2779 buf.append("}"); 2780 Slog.i(TAG, buf.toString()); 2781 app.setPid(startResult.pid); 2782 app.usingWrapper = startResult.usingWrapper; 2783 app.removed = false; 2784 synchronized (mPidsSelfLocked) { 2785 this.mPidsSelfLocked.put(startResult.pid, app); 2786 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2787 msg.obj = app; 2788 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2789 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2790 } 2791 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2792 app.processName, app.info.uid); 2793 if (app.isolated) { 2794 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2795 } 2796 } catch (RuntimeException e) { 2797 // XXX do better error recovery. 2798 app.setPid(0); 2799 Slog.e(TAG, "Failure starting process " + app.processName, e); 2800 } 2801 } 2802 2803 void updateUsageStats(ActivityRecord component, boolean resumed) { 2804 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2805 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2806 if (resumed) { 2807 mUsageStatsService.noteResumeComponent(component.realActivity); 2808 synchronized (stats) { 2809 stats.noteActivityResumedLocked(component.app.uid); 2810 } 2811 } else { 2812 mUsageStatsService.notePauseComponent(component.realActivity); 2813 synchronized (stats) { 2814 stats.noteActivityPausedLocked(component.app.uid); 2815 } 2816 } 2817 } 2818 2819 Intent getHomeIntent() { 2820 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2821 intent.setComponent(mTopComponent); 2822 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2823 intent.addCategory(Intent.CATEGORY_HOME); 2824 } 2825 return intent; 2826 } 2827 2828 boolean startHomeActivityLocked(int userId) { 2829 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2830 && mTopAction == null) { 2831 // We are running in factory test mode, but unable to find 2832 // the factory test app, so just sit around displaying the 2833 // error message and don't try to start anything. 2834 return false; 2835 } 2836 Intent intent = getHomeIntent(); 2837 ActivityInfo aInfo = 2838 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2839 if (aInfo != null) { 2840 intent.setComponent(new ComponentName( 2841 aInfo.applicationInfo.packageName, aInfo.name)); 2842 // Don't do this if the home app is currently being 2843 // instrumented. 2844 aInfo = new ActivityInfo(aInfo); 2845 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2846 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2847 aInfo.applicationInfo.uid, true); 2848 if (app == null || app.instrumentationClass == null) { 2849 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2850 mStackSupervisor.startHomeActivity(intent, aInfo); 2851 } 2852 } 2853 2854 return true; 2855 } 2856 2857 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2858 ActivityInfo ai = null; 2859 ComponentName comp = intent.getComponent(); 2860 try { 2861 if (comp != null) { 2862 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2863 } else { 2864 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2865 intent, 2866 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2867 flags, userId); 2868 2869 if (info != null) { 2870 ai = info.activityInfo; 2871 } 2872 } 2873 } catch (RemoteException e) { 2874 // ignore 2875 } 2876 2877 return ai; 2878 } 2879 2880 /** 2881 * Starts the "new version setup screen" if appropriate. 2882 */ 2883 void startSetupActivityLocked() { 2884 // Only do this once per boot. 2885 if (mCheckedForSetup) { 2886 return; 2887 } 2888 2889 // We will show this screen if the current one is a different 2890 // version than the last one shown, and we are not running in 2891 // low-level factory test mode. 2892 final ContentResolver resolver = mContext.getContentResolver(); 2893 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2894 Settings.Global.getInt(resolver, 2895 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2896 mCheckedForSetup = true; 2897 2898 // See if we should be showing the platform update setup UI. 2899 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2900 List<ResolveInfo> ris = mContext.getPackageManager() 2901 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2902 2903 // We don't allow third party apps to replace this. 2904 ResolveInfo ri = null; 2905 for (int i=0; ris != null && i<ris.size(); i++) { 2906 if ((ris.get(i).activityInfo.applicationInfo.flags 2907 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2908 ri = ris.get(i); 2909 break; 2910 } 2911 } 2912 2913 if (ri != null) { 2914 String vers = ri.activityInfo.metaData != null 2915 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2916 : null; 2917 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2918 vers = ri.activityInfo.applicationInfo.metaData.getString( 2919 Intent.METADATA_SETUP_VERSION); 2920 } 2921 String lastVers = Settings.Secure.getString( 2922 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2923 if (vers != null && !vers.equals(lastVers)) { 2924 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2925 intent.setComponent(new ComponentName( 2926 ri.activityInfo.packageName, ri.activityInfo.name)); 2927 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2928 null, null, 0, 0, 0, null, 0, null, false, null, null); 2929 } 2930 } 2931 } 2932 } 2933 2934 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2935 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2936 } 2937 2938 void enforceNotIsolatedCaller(String caller) { 2939 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2940 throw new SecurityException("Isolated process not allowed to call " + caller); 2941 } 2942 } 2943 2944 @Override 2945 public int getFrontActivityScreenCompatMode() { 2946 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2947 synchronized (this) { 2948 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2949 } 2950 } 2951 2952 @Override 2953 public void setFrontActivityScreenCompatMode(int mode) { 2954 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2955 "setFrontActivityScreenCompatMode"); 2956 synchronized (this) { 2957 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2958 } 2959 } 2960 2961 @Override 2962 public int getPackageScreenCompatMode(String packageName) { 2963 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2964 synchronized (this) { 2965 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2966 } 2967 } 2968 2969 @Override 2970 public void setPackageScreenCompatMode(String packageName, int mode) { 2971 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2972 "setPackageScreenCompatMode"); 2973 synchronized (this) { 2974 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2975 } 2976 } 2977 2978 @Override 2979 public boolean getPackageAskScreenCompat(String packageName) { 2980 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2981 synchronized (this) { 2982 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2983 } 2984 } 2985 2986 @Override 2987 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2988 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2989 "setPackageAskScreenCompat"); 2990 synchronized (this) { 2991 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2992 } 2993 } 2994 2995 private void dispatchProcessesChanged() { 2996 int N; 2997 synchronized (this) { 2998 N = mPendingProcessChanges.size(); 2999 if (mActiveProcessChanges.length < N) { 3000 mActiveProcessChanges = new ProcessChangeItem[N]; 3001 } 3002 mPendingProcessChanges.toArray(mActiveProcessChanges); 3003 mAvailProcessChanges.addAll(mPendingProcessChanges); 3004 mPendingProcessChanges.clear(); 3005 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3006 } 3007 3008 int i = mProcessObservers.beginBroadcast(); 3009 while (i > 0) { 3010 i--; 3011 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3012 if (observer != null) { 3013 try { 3014 for (int j=0; j<N; j++) { 3015 ProcessChangeItem item = mActiveProcessChanges[j]; 3016 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3017 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3018 + item.pid + " uid=" + item.uid + ": " 3019 + item.foregroundActivities); 3020 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3021 item.foregroundActivities); 3022 } 3023 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3024 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3025 + item.pid + " uid=" + item.uid + ": " + item.importance); 3026 observer.onImportanceChanged(item.pid, item.uid, 3027 item.importance); 3028 } 3029 } 3030 } catch (RemoteException e) { 3031 } 3032 } 3033 } 3034 mProcessObservers.finishBroadcast(); 3035 } 3036 3037 private void dispatchProcessDied(int pid, int uid) { 3038 int i = mProcessObservers.beginBroadcast(); 3039 while (i > 0) { 3040 i--; 3041 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3042 if (observer != null) { 3043 try { 3044 observer.onProcessDied(pid, uid); 3045 } catch (RemoteException e) { 3046 } 3047 } 3048 } 3049 mProcessObservers.finishBroadcast(); 3050 } 3051 3052 final void doPendingActivityLaunchesLocked(boolean doResume) { 3053 final int N = mPendingActivityLaunches.size(); 3054 if (N <= 0) { 3055 return; 3056 } 3057 for (int i=0; i<N; i++) { 3058 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3059 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3060 doResume && i == (N-1), null); 3061 } 3062 mPendingActivityLaunches.clear(); 3063 } 3064 3065 @Override 3066 public final int startActivity(IApplicationThread caller, String callingPackage, 3067 Intent intent, String resolvedType, IBinder resultTo, 3068 String resultWho, int requestCode, int startFlags, 3069 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3070 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3071 resultWho, requestCode, 3072 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3073 } 3074 3075 @Override 3076 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3077 Intent intent, String resolvedType, IBinder resultTo, 3078 String resultWho, int requestCode, int startFlags, 3079 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3080 enforceNotIsolatedCaller("startActivity"); 3081 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3082 false, true, "startActivity", null); 3083 // TODO: Switch to user app stacks here. 3084 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3085 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3086 null, null, options, userId, null); 3087 } 3088 3089 @Override 3090 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3091 Intent intent, String resolvedType, IBinder resultTo, 3092 String resultWho, int requestCode, int startFlags, String profileFile, 3093 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3094 enforceNotIsolatedCaller("startActivityAndWait"); 3095 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3096 false, true, "startActivityAndWait", null); 3097 WaitResult res = new WaitResult(); 3098 // TODO: Switch to user app stacks here. 3099 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3100 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3101 res, null, options, UserHandle.getCallingUserId(), null); 3102 return res; 3103 } 3104 3105 @Override 3106 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3107 Intent intent, String resolvedType, IBinder resultTo, 3108 String resultWho, int requestCode, int startFlags, Configuration config, 3109 Bundle options, int userId) { 3110 enforceNotIsolatedCaller("startActivityWithConfig"); 3111 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3112 false, true, "startActivityWithConfig", null); 3113 // TODO: Switch to user app stacks here. 3114 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3115 resolvedType, resultTo, resultWho, requestCode, startFlags, 3116 null, null, null, config, options, userId, null); 3117 return ret; 3118 } 3119 3120 @Override 3121 public int startActivityIntentSender(IApplicationThread caller, 3122 IntentSender intent, Intent fillInIntent, String resolvedType, 3123 IBinder resultTo, String resultWho, int requestCode, 3124 int flagsMask, int flagsValues, Bundle options) { 3125 enforceNotIsolatedCaller("startActivityIntentSender"); 3126 // Refuse possible leaked file descriptors 3127 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3128 throw new IllegalArgumentException("File descriptors passed in Intent"); 3129 } 3130 3131 IIntentSender sender = intent.getTarget(); 3132 if (!(sender instanceof PendingIntentRecord)) { 3133 throw new IllegalArgumentException("Bad PendingIntent object"); 3134 } 3135 3136 PendingIntentRecord pir = (PendingIntentRecord)sender; 3137 3138 synchronized (this) { 3139 // If this is coming from the currently resumed activity, it is 3140 // effectively saying that app switches are allowed at this point. 3141 final ActivityStack stack = getFocusedStack(); 3142 if (stack.mResumedActivity != null && 3143 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3144 mAppSwitchesAllowedTime = 0; 3145 } 3146 } 3147 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3148 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3149 return ret; 3150 } 3151 3152 @Override 3153 public boolean startNextMatchingActivity(IBinder callingActivity, 3154 Intent intent, Bundle options) { 3155 // Refuse possible leaked file descriptors 3156 if (intent != null && intent.hasFileDescriptors() == true) { 3157 throw new IllegalArgumentException("File descriptors passed in Intent"); 3158 } 3159 3160 synchronized (this) { 3161 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3162 if (r == null) { 3163 ActivityOptions.abort(options); 3164 return false; 3165 } 3166 if (r.app == null || r.app.thread == null) { 3167 // The caller is not running... d'oh! 3168 ActivityOptions.abort(options); 3169 return false; 3170 } 3171 intent = new Intent(intent); 3172 // The caller is not allowed to change the data. 3173 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3174 // And we are resetting to find the next component... 3175 intent.setComponent(null); 3176 3177 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3178 3179 ActivityInfo aInfo = null; 3180 try { 3181 List<ResolveInfo> resolves = 3182 AppGlobals.getPackageManager().queryIntentActivities( 3183 intent, r.resolvedType, 3184 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3185 UserHandle.getCallingUserId()); 3186 3187 // Look for the original activity in the list... 3188 final int N = resolves != null ? resolves.size() : 0; 3189 for (int i=0; i<N; i++) { 3190 ResolveInfo rInfo = resolves.get(i); 3191 if (rInfo.activityInfo.packageName.equals(r.packageName) 3192 && rInfo.activityInfo.name.equals(r.info.name)) { 3193 // We found the current one... the next matching is 3194 // after it. 3195 i++; 3196 if (i<N) { 3197 aInfo = resolves.get(i).activityInfo; 3198 } 3199 if (debug) { 3200 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3201 + "/" + r.info.name); 3202 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3203 + "/" + aInfo.name); 3204 } 3205 break; 3206 } 3207 } 3208 } catch (RemoteException e) { 3209 } 3210 3211 if (aInfo == null) { 3212 // Nobody who is next! 3213 ActivityOptions.abort(options); 3214 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3215 return false; 3216 } 3217 3218 intent.setComponent(new ComponentName( 3219 aInfo.applicationInfo.packageName, aInfo.name)); 3220 intent.setFlags(intent.getFlags()&~( 3221 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3222 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3223 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3224 Intent.FLAG_ACTIVITY_NEW_TASK)); 3225 3226 // Okay now we need to start the new activity, replacing the 3227 // currently running activity. This is a little tricky because 3228 // we want to start the new one as if the current one is finished, 3229 // but not finish the current one first so that there is no flicker. 3230 // And thus... 3231 final boolean wasFinishing = r.finishing; 3232 r.finishing = true; 3233 3234 // Propagate reply information over to the new activity. 3235 final ActivityRecord resultTo = r.resultTo; 3236 final String resultWho = r.resultWho; 3237 final int requestCode = r.requestCode; 3238 r.resultTo = null; 3239 if (resultTo != null) { 3240 resultTo.removeResultsLocked(r, resultWho, requestCode); 3241 } 3242 3243 final long origId = Binder.clearCallingIdentity(); 3244 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3245 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3246 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3247 options, false, null, null); 3248 Binder.restoreCallingIdentity(origId); 3249 3250 r.finishing = wasFinishing; 3251 if (res != ActivityManager.START_SUCCESS) { 3252 return false; 3253 } 3254 return true; 3255 } 3256 } 3257 3258 final int startActivityInPackage(int uid, String callingPackage, 3259 Intent intent, String resolvedType, IBinder resultTo, 3260 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3261 IActivityContainer container) { 3262 3263 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3264 false, true, "startActivityInPackage", null); 3265 3266 // TODO: Switch to user app stacks here. 3267 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3268 resultTo, resultWho, requestCode, startFlags, 3269 null, null, null, null, options, userId, container); 3270 return ret; 3271 } 3272 3273 @Override 3274 public final int startActivities(IApplicationThread caller, String callingPackage, 3275 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3276 int userId) { 3277 enforceNotIsolatedCaller("startActivities"); 3278 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3279 false, true, "startActivity", null); 3280 // TODO: Switch to user app stacks here. 3281 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3282 resolvedTypes, resultTo, options, userId); 3283 return ret; 3284 } 3285 3286 final int startActivitiesInPackage(int uid, String callingPackage, 3287 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3288 Bundle options, int userId) { 3289 3290 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3291 false, true, "startActivityInPackage", null); 3292 // TODO: Switch to user app stacks here. 3293 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3294 resultTo, options, userId); 3295 return ret; 3296 } 3297 3298 final void addRecentTaskLocked(TaskRecord task) { 3299 int N = mRecentTasks.size(); 3300 // Quick case: check if the top-most recent task is the same. 3301 if (N > 0 && mRecentTasks.get(0) == task) { 3302 return; 3303 } 3304 // Remove any existing entries that are the same kind of task. 3305 for (int i=0; i<N; i++) { 3306 TaskRecord tr = mRecentTasks.get(i); 3307 if (task.userId == tr.userId 3308 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 3309 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 3310 tr.disposeThumbnail(); 3311 mRecentTasks.remove(i); 3312 i--; 3313 N--; 3314 if (task.intent == null) { 3315 // If the new recent task we are adding is not fully 3316 // specified, then replace it with the existing recent task. 3317 task = tr; 3318 } 3319 } 3320 } 3321 if (N >= MAX_RECENT_TASKS) { 3322 mRecentTasks.remove(N-1).disposeThumbnail(); 3323 } 3324 mRecentTasks.add(0, task); 3325 } 3326 3327 @Override 3328 public void reportActivityFullyDrawn(IBinder token) { 3329 synchronized (this) { 3330 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3331 if (r == null) { 3332 return; 3333 } 3334 r.reportFullyDrawnLocked(); 3335 } 3336 } 3337 3338 @Override 3339 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3340 synchronized (this) { 3341 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3342 if (r == null) { 3343 return; 3344 } 3345 final long origId = Binder.clearCallingIdentity(); 3346 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3347 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3348 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3349 if (config != null) { 3350 r.frozenBeforeDestroy = true; 3351 if (!updateConfigurationLocked(config, r, false, false)) { 3352 mStackSupervisor.resumeTopActivitiesLocked(); 3353 } 3354 } 3355 Binder.restoreCallingIdentity(origId); 3356 } 3357 } 3358 3359 @Override 3360 public int getRequestedOrientation(IBinder token) { 3361 synchronized (this) { 3362 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3363 if (r == null) { 3364 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3365 } 3366 return mWindowManager.getAppOrientation(r.appToken); 3367 } 3368 } 3369 3370 /** 3371 * This is the internal entry point for handling Activity.finish(). 3372 * 3373 * @param token The Binder token referencing the Activity we want to finish. 3374 * @param resultCode Result code, if any, from this Activity. 3375 * @param resultData Result data (Intent), if any, from this Activity. 3376 * 3377 * @return Returns true if the activity successfully finished, or false if it is still running. 3378 */ 3379 @Override 3380 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3381 // Refuse possible leaked file descriptors 3382 if (resultData != null && resultData.hasFileDescriptors() == true) { 3383 throw new IllegalArgumentException("File descriptors passed in Intent"); 3384 } 3385 3386 synchronized(this) { 3387 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3388 if (r == null) { 3389 return true; 3390 } 3391 if (mController != null) { 3392 // Find the first activity that is not finishing. 3393 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3394 if (next != null) { 3395 // ask watcher if this is allowed 3396 boolean resumeOK = true; 3397 try { 3398 resumeOK = mController.activityResuming(next.packageName); 3399 } catch (RemoteException e) { 3400 mController = null; 3401 Watchdog.getInstance().setActivityController(null); 3402 } 3403 3404 if (!resumeOK) { 3405 return false; 3406 } 3407 } 3408 } 3409 final long origId = Binder.clearCallingIdentity(); 3410 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3411 resultData, "app-request", true); 3412 Binder.restoreCallingIdentity(origId); 3413 return res; 3414 } 3415 } 3416 3417 @Override 3418 public final void finishHeavyWeightApp() { 3419 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3420 != PackageManager.PERMISSION_GRANTED) { 3421 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3422 + Binder.getCallingPid() 3423 + ", uid=" + Binder.getCallingUid() 3424 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3425 Slog.w(TAG, msg); 3426 throw new SecurityException(msg); 3427 } 3428 3429 synchronized(this) { 3430 if (mHeavyWeightProcess == null) { 3431 return; 3432 } 3433 3434 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3435 mHeavyWeightProcess.activities); 3436 for (int i=0; i<activities.size(); i++) { 3437 ActivityRecord r = activities.get(i); 3438 if (!r.finishing) { 3439 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3440 null, "finish-heavy", true); 3441 } 3442 } 3443 3444 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3445 mHeavyWeightProcess.userId, 0)); 3446 mHeavyWeightProcess = null; 3447 } 3448 } 3449 3450 @Override 3451 public void crashApplication(int uid, int initialPid, String packageName, 3452 String message) { 3453 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3454 != PackageManager.PERMISSION_GRANTED) { 3455 String msg = "Permission Denial: crashApplication() from pid=" 3456 + Binder.getCallingPid() 3457 + ", uid=" + Binder.getCallingUid() 3458 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3459 Slog.w(TAG, msg); 3460 throw new SecurityException(msg); 3461 } 3462 3463 synchronized(this) { 3464 ProcessRecord proc = null; 3465 3466 // Figure out which process to kill. We don't trust that initialPid 3467 // still has any relation to current pids, so must scan through the 3468 // list. 3469 synchronized (mPidsSelfLocked) { 3470 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3471 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3472 if (p.uid != uid) { 3473 continue; 3474 } 3475 if (p.pid == initialPid) { 3476 proc = p; 3477 break; 3478 } 3479 if (p.pkgList.containsKey(packageName)) { 3480 proc = p; 3481 } 3482 } 3483 } 3484 3485 if (proc == null) { 3486 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3487 + " initialPid=" + initialPid 3488 + " packageName=" + packageName); 3489 return; 3490 } 3491 3492 if (proc.thread != null) { 3493 if (proc.pid == Process.myPid()) { 3494 Log.w(TAG, "crashApplication: trying to crash self!"); 3495 return; 3496 } 3497 long ident = Binder.clearCallingIdentity(); 3498 try { 3499 proc.thread.scheduleCrash(message); 3500 } catch (RemoteException e) { 3501 } 3502 Binder.restoreCallingIdentity(ident); 3503 } 3504 } 3505 } 3506 3507 @Override 3508 public final void finishSubActivity(IBinder token, String resultWho, 3509 int requestCode) { 3510 synchronized(this) { 3511 final long origId = Binder.clearCallingIdentity(); 3512 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3513 if (r != null) { 3514 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3515 } 3516 Binder.restoreCallingIdentity(origId); 3517 } 3518 } 3519 3520 @Override 3521 public boolean finishActivityAffinity(IBinder token) { 3522 synchronized(this) { 3523 final long origId = Binder.clearCallingIdentity(); 3524 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3525 boolean res = false; 3526 if (r != null) { 3527 res = r.task.stack.finishActivityAffinityLocked(r); 3528 } 3529 Binder.restoreCallingIdentity(origId); 3530 return res; 3531 } 3532 } 3533 3534 @Override 3535 public boolean willActivityBeVisible(IBinder token) { 3536 synchronized(this) { 3537 ActivityStack stack = ActivityRecord.getStackLocked(token); 3538 if (stack != null) { 3539 return stack.willActivityBeVisibleLocked(token); 3540 } 3541 return false; 3542 } 3543 } 3544 3545 @Override 3546 public void overridePendingTransition(IBinder token, String packageName, 3547 int enterAnim, int exitAnim) { 3548 synchronized(this) { 3549 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3550 if (self == null) { 3551 return; 3552 } 3553 3554 final long origId = Binder.clearCallingIdentity(); 3555 3556 if (self.state == ActivityState.RESUMED 3557 || self.state == ActivityState.PAUSING) { 3558 mWindowManager.overridePendingAppTransition(packageName, 3559 enterAnim, exitAnim, null); 3560 } 3561 3562 Binder.restoreCallingIdentity(origId); 3563 } 3564 } 3565 3566 /** 3567 * Main function for removing an existing process from the activity manager 3568 * as a result of that process going away. Clears out all connections 3569 * to the process. 3570 */ 3571 private final void handleAppDiedLocked(ProcessRecord app, 3572 boolean restarting, boolean allowRestart) { 3573 int pid = app.pid; 3574 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3575 if (!restarting) { 3576 removeLruProcessLocked(app); 3577 if (pid > 0) { 3578 ProcessList.remove(pid); 3579 } 3580 } 3581 3582 if (mProfileProc == app) { 3583 clearProfilerLocked(); 3584 } 3585 3586 // Remove this application's activities from active lists. 3587 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3588 3589 app.activities.clear(); 3590 3591 if (app.instrumentationClass != null) { 3592 Slog.w(TAG, "Crash of app " + app.processName 3593 + " running instrumentation " + app.instrumentationClass); 3594 Bundle info = new Bundle(); 3595 info.putString("shortMsg", "Process crashed."); 3596 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3597 } 3598 3599 if (!restarting) { 3600 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3601 // If there was nothing to resume, and we are not already 3602 // restarting this process, but there is a visible activity that 3603 // is hosted by the process... then make sure all visible 3604 // activities are running, taking care of restarting this 3605 // process. 3606 if (hasVisibleActivities) { 3607 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3608 } 3609 } 3610 } 3611 } 3612 3613 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3614 IBinder threadBinder = thread.asBinder(); 3615 // Find the application record. 3616 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3617 ProcessRecord rec = mLruProcesses.get(i); 3618 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3619 return i; 3620 } 3621 } 3622 return -1; 3623 } 3624 3625 final ProcessRecord getRecordForAppLocked( 3626 IApplicationThread thread) { 3627 if (thread == null) { 3628 return null; 3629 } 3630 3631 int appIndex = getLRURecordIndexForAppLocked(thread); 3632 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3633 } 3634 3635 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3636 // If there are no longer any background processes running, 3637 // and the app that died was not running instrumentation, 3638 // then tell everyone we are now low on memory. 3639 boolean haveBg = false; 3640 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3641 ProcessRecord rec = mLruProcesses.get(i); 3642 if (rec.thread != null 3643 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3644 haveBg = true; 3645 break; 3646 } 3647 } 3648 3649 if (!haveBg) { 3650 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3651 if (doReport) { 3652 long now = SystemClock.uptimeMillis(); 3653 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3654 doReport = false; 3655 } else { 3656 mLastMemUsageReportTime = now; 3657 } 3658 } 3659 final ArrayList<ProcessMemInfo> memInfos 3660 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3661 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3662 long now = SystemClock.uptimeMillis(); 3663 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3664 ProcessRecord rec = mLruProcesses.get(i); 3665 if (rec == dyingProc || rec.thread == null) { 3666 continue; 3667 } 3668 if (doReport) { 3669 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3670 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3671 } 3672 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3673 // The low memory report is overriding any current 3674 // state for a GC request. Make sure to do 3675 // heavy/important/visible/foreground processes first. 3676 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3677 rec.lastRequestedGc = 0; 3678 } else { 3679 rec.lastRequestedGc = rec.lastLowMemory; 3680 } 3681 rec.reportLowMemory = true; 3682 rec.lastLowMemory = now; 3683 mProcessesToGc.remove(rec); 3684 addProcessToGcListLocked(rec); 3685 } 3686 } 3687 if (doReport) { 3688 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3689 mHandler.sendMessage(msg); 3690 } 3691 scheduleAppGcsLocked(); 3692 } 3693 } 3694 3695 final void appDiedLocked(ProcessRecord app, int pid, 3696 IApplicationThread thread) { 3697 3698 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3699 synchronized (stats) { 3700 stats.noteProcessDiedLocked(app.info.uid, pid); 3701 } 3702 3703 // Clean up already done if the process has been re-started. 3704 if (app.pid == pid && app.thread != null && 3705 app.thread.asBinder() == thread.asBinder()) { 3706 boolean doLowMem = app.instrumentationClass == null; 3707 boolean doOomAdj = doLowMem; 3708 if (!app.killedByAm) { 3709 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3710 + ") has died."); 3711 mAllowLowerMemLevel = true; 3712 } else { 3713 // Note that we always want to do oom adj to update our state with the 3714 // new number of procs. 3715 mAllowLowerMemLevel = false; 3716 doLowMem = false; 3717 } 3718 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3719 if (DEBUG_CLEANUP) Slog.v( 3720 TAG, "Dying app: " + app + ", pid: " + pid 3721 + ", thread: " + thread.asBinder()); 3722 handleAppDiedLocked(app, false, true); 3723 3724 if (doOomAdj) { 3725 updateOomAdjLocked(); 3726 } 3727 if (doLowMem) { 3728 doLowMemReportIfNeededLocked(app); 3729 } 3730 } else if (app.pid != pid) { 3731 // A new process has already been started. 3732 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3733 + ") has died and restarted (pid " + app.pid + ")."); 3734 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3735 } else if (DEBUG_PROCESSES) { 3736 Slog.d(TAG, "Received spurious death notification for thread " 3737 + thread.asBinder()); 3738 } 3739 } 3740 3741 /** 3742 * If a stack trace dump file is configured, dump process stack traces. 3743 * @param clearTraces causes the dump file to be erased prior to the new 3744 * traces being written, if true; when false, the new traces will be 3745 * appended to any existing file content. 3746 * @param firstPids of dalvik VM processes to dump stack traces for first 3747 * @param lastPids of dalvik VM processes to dump stack traces for last 3748 * @param nativeProcs optional list of native process names to dump stack crawls 3749 * @return file containing stack traces, or null if no dump file is configured 3750 */ 3751 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3752 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3753 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3754 if (tracesPath == null || tracesPath.length() == 0) { 3755 return null; 3756 } 3757 3758 File tracesFile = new File(tracesPath); 3759 try { 3760 File tracesDir = tracesFile.getParentFile(); 3761 if (!tracesDir.exists()) { 3762 tracesFile.mkdirs(); 3763 if (!SELinux.restorecon(tracesDir)) { 3764 return null; 3765 } 3766 } 3767 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3768 3769 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3770 tracesFile.createNewFile(); 3771 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3772 } catch (IOException e) { 3773 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3774 return null; 3775 } 3776 3777 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3778 return tracesFile; 3779 } 3780 3781 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3782 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3783 // Use a FileObserver to detect when traces finish writing. 3784 // The order of traces is considered important to maintain for legibility. 3785 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3786 @Override 3787 public synchronized void onEvent(int event, String path) { notify(); } 3788 }; 3789 3790 try { 3791 observer.startWatching(); 3792 3793 // First collect all of the stacks of the most important pids. 3794 if (firstPids != null) { 3795 try { 3796 int num = firstPids.size(); 3797 for (int i = 0; i < num; i++) { 3798 synchronized (observer) { 3799 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3800 observer.wait(200); // Wait for write-close, give up after 200msec 3801 } 3802 } 3803 } catch (InterruptedException e) { 3804 Log.wtf(TAG, e); 3805 } 3806 } 3807 3808 // Next collect the stacks of the native pids 3809 if (nativeProcs != null) { 3810 int[] pids = Process.getPidsForCommands(nativeProcs); 3811 if (pids != null) { 3812 for (int pid : pids) { 3813 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3814 } 3815 } 3816 } 3817 3818 // Lastly, measure CPU usage. 3819 if (processCpuTracker != null) { 3820 processCpuTracker.init(); 3821 System.gc(); 3822 processCpuTracker.update(); 3823 try { 3824 synchronized (processCpuTracker) { 3825 processCpuTracker.wait(500); // measure over 1/2 second. 3826 } 3827 } catch (InterruptedException e) { 3828 } 3829 processCpuTracker.update(); 3830 3831 // We'll take the stack crawls of just the top apps using CPU. 3832 final int N = processCpuTracker.countWorkingStats(); 3833 int numProcs = 0; 3834 for (int i=0; i<N && numProcs<5; i++) { 3835 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3836 if (lastPids.indexOfKey(stats.pid) >= 0) { 3837 numProcs++; 3838 try { 3839 synchronized (observer) { 3840 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3841 observer.wait(200); // Wait for write-close, give up after 200msec 3842 } 3843 } catch (InterruptedException e) { 3844 Log.wtf(TAG, e); 3845 } 3846 3847 } 3848 } 3849 } 3850 } finally { 3851 observer.stopWatching(); 3852 } 3853 } 3854 3855 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3856 if (true || IS_USER_BUILD) { 3857 return; 3858 } 3859 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3860 if (tracesPath == null || tracesPath.length() == 0) { 3861 return; 3862 } 3863 3864 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3865 StrictMode.allowThreadDiskWrites(); 3866 try { 3867 final File tracesFile = new File(tracesPath); 3868 final File tracesDir = tracesFile.getParentFile(); 3869 final File tracesTmp = new File(tracesDir, "__tmp__"); 3870 try { 3871 if (!tracesDir.exists()) { 3872 tracesFile.mkdirs(); 3873 if (!SELinux.restorecon(tracesDir.getPath())) { 3874 return; 3875 } 3876 } 3877 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3878 3879 if (tracesFile.exists()) { 3880 tracesTmp.delete(); 3881 tracesFile.renameTo(tracesTmp); 3882 } 3883 StringBuilder sb = new StringBuilder(); 3884 Time tobj = new Time(); 3885 tobj.set(System.currentTimeMillis()); 3886 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3887 sb.append(": "); 3888 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3889 sb.append(" since "); 3890 sb.append(msg); 3891 FileOutputStream fos = new FileOutputStream(tracesFile); 3892 fos.write(sb.toString().getBytes()); 3893 if (app == null) { 3894 fos.write("\n*** No application process!".getBytes()); 3895 } 3896 fos.close(); 3897 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3898 } catch (IOException e) { 3899 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3900 return; 3901 } 3902 3903 if (app != null) { 3904 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3905 firstPids.add(app.pid); 3906 dumpStackTraces(tracesPath, firstPids, null, null, null); 3907 } 3908 3909 File lastTracesFile = null; 3910 File curTracesFile = null; 3911 for (int i=9; i>=0; i--) { 3912 String name = String.format(Locale.US, "slow%02d.txt", i); 3913 curTracesFile = new File(tracesDir, name); 3914 if (curTracesFile.exists()) { 3915 if (lastTracesFile != null) { 3916 curTracesFile.renameTo(lastTracesFile); 3917 } else { 3918 curTracesFile.delete(); 3919 } 3920 } 3921 lastTracesFile = curTracesFile; 3922 } 3923 tracesFile.renameTo(curTracesFile); 3924 if (tracesTmp.exists()) { 3925 tracesTmp.renameTo(tracesFile); 3926 } 3927 } finally { 3928 StrictMode.setThreadPolicy(oldPolicy); 3929 } 3930 } 3931 3932 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3933 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3934 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3935 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3936 3937 if (mController != null) { 3938 try { 3939 // 0 == continue, -1 = kill process immediately 3940 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3941 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3942 } catch (RemoteException e) { 3943 mController = null; 3944 Watchdog.getInstance().setActivityController(null); 3945 } 3946 } 3947 3948 long anrTime = SystemClock.uptimeMillis(); 3949 if (MONITOR_CPU_USAGE) { 3950 updateCpuStatsNow(); 3951 } 3952 3953 synchronized (this) { 3954 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3955 if (mShuttingDown) { 3956 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3957 return; 3958 } else if (app.notResponding) { 3959 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3960 return; 3961 } else if (app.crashing) { 3962 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3963 return; 3964 } 3965 3966 // In case we come through here for the same app before completing 3967 // this one, mark as anring now so we will bail out. 3968 app.notResponding = true; 3969 3970 // Log the ANR to the event log. 3971 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3972 app.processName, app.info.flags, annotation); 3973 3974 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3975 firstPids.add(app.pid); 3976 3977 int parentPid = app.pid; 3978 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3979 if (parentPid != app.pid) firstPids.add(parentPid); 3980 3981 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3982 3983 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3984 ProcessRecord r = mLruProcesses.get(i); 3985 if (r != null && r.thread != null) { 3986 int pid = r.pid; 3987 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3988 if (r.persistent) { 3989 firstPids.add(pid); 3990 } else { 3991 lastPids.put(pid, Boolean.TRUE); 3992 } 3993 } 3994 } 3995 } 3996 } 3997 3998 // Log the ANR to the main log. 3999 StringBuilder info = new StringBuilder(); 4000 info.setLength(0); 4001 info.append("ANR in ").append(app.processName); 4002 if (activity != null && activity.shortComponentName != null) { 4003 info.append(" (").append(activity.shortComponentName).append(")"); 4004 } 4005 info.append("\n"); 4006 info.append("PID: ").append(app.pid).append("\n"); 4007 if (annotation != null) { 4008 info.append("Reason: ").append(annotation).append("\n"); 4009 } 4010 if (parent != null && parent != activity) { 4011 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4012 } 4013 4014 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4015 4016 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4017 NATIVE_STACKS_OF_INTEREST); 4018 4019 String cpuInfo = null; 4020 if (MONITOR_CPU_USAGE) { 4021 updateCpuStatsNow(); 4022 synchronized (mProcessCpuThread) { 4023 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4024 } 4025 info.append(processCpuTracker.printCurrentLoad()); 4026 info.append(cpuInfo); 4027 } 4028 4029 info.append(processCpuTracker.printCurrentState(anrTime)); 4030 4031 Slog.e(TAG, info.toString()); 4032 if (tracesFile == null) { 4033 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4034 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4035 } 4036 4037 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4038 cpuInfo, tracesFile, null); 4039 4040 if (mController != null) { 4041 try { 4042 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4043 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4044 if (res != 0) { 4045 if (res < 0 && app.pid != MY_PID) { 4046 Process.killProcess(app.pid); 4047 } else { 4048 synchronized (this) { 4049 mServices.scheduleServiceTimeoutLocked(app); 4050 } 4051 } 4052 return; 4053 } 4054 } catch (RemoteException e) { 4055 mController = null; 4056 Watchdog.getInstance().setActivityController(null); 4057 } 4058 } 4059 4060 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4061 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4062 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4063 4064 synchronized (this) { 4065 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4066 killUnneededProcessLocked(app, "background ANR"); 4067 return; 4068 } 4069 4070 // Set the app's notResponding state, and look up the errorReportReceiver 4071 makeAppNotRespondingLocked(app, 4072 activity != null ? activity.shortComponentName : null, 4073 annotation != null ? "ANR " + annotation : "ANR", 4074 info.toString()); 4075 4076 // Bring up the infamous App Not Responding dialog 4077 Message msg = Message.obtain(); 4078 HashMap<String, Object> map = new HashMap<String, Object>(); 4079 msg.what = SHOW_NOT_RESPONDING_MSG; 4080 msg.obj = map; 4081 msg.arg1 = aboveSystem ? 1 : 0; 4082 map.put("app", app); 4083 if (activity != null) { 4084 map.put("activity", activity); 4085 } 4086 4087 mHandler.sendMessage(msg); 4088 } 4089 } 4090 4091 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4092 if (!mLaunchWarningShown) { 4093 mLaunchWarningShown = true; 4094 mHandler.post(new Runnable() { 4095 @Override 4096 public void run() { 4097 synchronized (ActivityManagerService.this) { 4098 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4099 d.show(); 4100 mHandler.postDelayed(new Runnable() { 4101 @Override 4102 public void run() { 4103 synchronized (ActivityManagerService.this) { 4104 d.dismiss(); 4105 mLaunchWarningShown = false; 4106 } 4107 } 4108 }, 4000); 4109 } 4110 } 4111 }); 4112 } 4113 } 4114 4115 @Override 4116 public boolean clearApplicationUserData(final String packageName, 4117 final IPackageDataObserver observer, int userId) { 4118 enforceNotIsolatedCaller("clearApplicationUserData"); 4119 int uid = Binder.getCallingUid(); 4120 int pid = Binder.getCallingPid(); 4121 userId = handleIncomingUser(pid, uid, 4122 userId, false, true, "clearApplicationUserData", null); 4123 long callingId = Binder.clearCallingIdentity(); 4124 try { 4125 IPackageManager pm = AppGlobals.getPackageManager(); 4126 int pkgUid = -1; 4127 synchronized(this) { 4128 try { 4129 pkgUid = pm.getPackageUid(packageName, userId); 4130 } catch (RemoteException e) { 4131 } 4132 if (pkgUid == -1) { 4133 Slog.w(TAG, "Invalid packageName: " + packageName); 4134 if (observer != null) { 4135 try { 4136 observer.onRemoveCompleted(packageName, false); 4137 } catch (RemoteException e) { 4138 Slog.i(TAG, "Observer no longer exists."); 4139 } 4140 } 4141 return false; 4142 } 4143 if (uid == pkgUid || checkComponentPermission( 4144 android.Manifest.permission.CLEAR_APP_USER_DATA, 4145 pid, uid, -1, true) 4146 == PackageManager.PERMISSION_GRANTED) { 4147 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4148 } else { 4149 throw new SecurityException("PID " + pid + " does not have permission " 4150 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4151 + " of package " + packageName); 4152 } 4153 } 4154 4155 try { 4156 // Clear application user data 4157 pm.clearApplicationUserData(packageName, observer, userId); 4158 4159 // Remove all permissions granted from/to this package 4160 removeUriPermissionsForPackageLocked(packageName, userId, true); 4161 4162 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4163 Uri.fromParts("package", packageName, null)); 4164 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4165 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4166 null, null, 0, null, null, null, false, false, userId); 4167 } catch (RemoteException e) { 4168 } 4169 } finally { 4170 Binder.restoreCallingIdentity(callingId); 4171 } 4172 return true; 4173 } 4174 4175 @Override 4176 public void killBackgroundProcesses(final String packageName, int userId) { 4177 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4178 != PackageManager.PERMISSION_GRANTED && 4179 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4180 != PackageManager.PERMISSION_GRANTED) { 4181 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4182 + Binder.getCallingPid() 4183 + ", uid=" + Binder.getCallingUid() 4184 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4185 Slog.w(TAG, msg); 4186 throw new SecurityException(msg); 4187 } 4188 4189 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4190 userId, true, true, "killBackgroundProcesses", null); 4191 long callingId = Binder.clearCallingIdentity(); 4192 try { 4193 IPackageManager pm = AppGlobals.getPackageManager(); 4194 synchronized(this) { 4195 int appId = -1; 4196 try { 4197 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4198 } catch (RemoteException e) { 4199 } 4200 if (appId == -1) { 4201 Slog.w(TAG, "Invalid packageName: " + packageName); 4202 return; 4203 } 4204 killPackageProcessesLocked(packageName, appId, userId, 4205 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4206 } 4207 } finally { 4208 Binder.restoreCallingIdentity(callingId); 4209 } 4210 } 4211 4212 @Override 4213 public void killAllBackgroundProcesses() { 4214 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4215 != PackageManager.PERMISSION_GRANTED) { 4216 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4217 + Binder.getCallingPid() 4218 + ", uid=" + Binder.getCallingUid() 4219 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4220 Slog.w(TAG, msg); 4221 throw new SecurityException(msg); 4222 } 4223 4224 long callingId = Binder.clearCallingIdentity(); 4225 try { 4226 synchronized(this) { 4227 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4228 final int NP = mProcessNames.getMap().size(); 4229 for (int ip=0; ip<NP; ip++) { 4230 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4231 final int NA = apps.size(); 4232 for (int ia=0; ia<NA; ia++) { 4233 ProcessRecord app = apps.valueAt(ia); 4234 if (app.persistent) { 4235 // we don't kill persistent processes 4236 continue; 4237 } 4238 if (app.removed) { 4239 procs.add(app); 4240 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4241 app.removed = true; 4242 procs.add(app); 4243 } 4244 } 4245 } 4246 4247 int N = procs.size(); 4248 for (int i=0; i<N; i++) { 4249 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4250 } 4251 mAllowLowerMemLevel = true; 4252 updateOomAdjLocked(); 4253 doLowMemReportIfNeededLocked(null); 4254 } 4255 } finally { 4256 Binder.restoreCallingIdentity(callingId); 4257 } 4258 } 4259 4260 @Override 4261 public void forceStopPackage(final String packageName, int userId) { 4262 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4263 != PackageManager.PERMISSION_GRANTED) { 4264 String msg = "Permission Denial: forceStopPackage() from pid=" 4265 + Binder.getCallingPid() 4266 + ", uid=" + Binder.getCallingUid() 4267 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4268 Slog.w(TAG, msg); 4269 throw new SecurityException(msg); 4270 } 4271 final int callingPid = Binder.getCallingPid(); 4272 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4273 userId, true, true, "forceStopPackage", null); 4274 long callingId = Binder.clearCallingIdentity(); 4275 try { 4276 IPackageManager pm = AppGlobals.getPackageManager(); 4277 synchronized(this) { 4278 int[] users = userId == UserHandle.USER_ALL 4279 ? getUsersLocked() : new int[] { userId }; 4280 for (int user : users) { 4281 int pkgUid = -1; 4282 try { 4283 pkgUid = pm.getPackageUid(packageName, user); 4284 } catch (RemoteException e) { 4285 } 4286 if (pkgUid == -1) { 4287 Slog.w(TAG, "Invalid packageName: " + packageName); 4288 continue; 4289 } 4290 try { 4291 pm.setPackageStoppedState(packageName, true, user); 4292 } catch (RemoteException e) { 4293 } catch (IllegalArgumentException e) { 4294 Slog.w(TAG, "Failed trying to unstop package " 4295 + packageName + ": " + e); 4296 } 4297 if (isUserRunningLocked(user, false)) { 4298 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4299 } 4300 } 4301 } 4302 } finally { 4303 Binder.restoreCallingIdentity(callingId); 4304 } 4305 } 4306 4307 /* 4308 * The pkg name and app id have to be specified. 4309 */ 4310 @Override 4311 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4312 if (pkg == null) { 4313 return; 4314 } 4315 // Make sure the uid is valid. 4316 if (appid < 0) { 4317 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4318 return; 4319 } 4320 int callerUid = Binder.getCallingUid(); 4321 // Only the system server can kill an application 4322 if (callerUid == Process.SYSTEM_UID) { 4323 // Post an aysnc message to kill the application 4324 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4325 msg.arg1 = appid; 4326 msg.arg2 = 0; 4327 Bundle bundle = new Bundle(); 4328 bundle.putString("pkg", pkg); 4329 bundle.putString("reason", reason); 4330 msg.obj = bundle; 4331 mHandler.sendMessage(msg); 4332 } else { 4333 throw new SecurityException(callerUid + " cannot kill pkg: " + 4334 pkg); 4335 } 4336 } 4337 4338 @Override 4339 public void closeSystemDialogs(String reason) { 4340 enforceNotIsolatedCaller("closeSystemDialogs"); 4341 4342 final int pid = Binder.getCallingPid(); 4343 final int uid = Binder.getCallingUid(); 4344 final long origId = Binder.clearCallingIdentity(); 4345 try { 4346 synchronized (this) { 4347 // Only allow this from foreground processes, so that background 4348 // applications can't abuse it to prevent system UI from being shown. 4349 if (uid >= Process.FIRST_APPLICATION_UID) { 4350 ProcessRecord proc; 4351 synchronized (mPidsSelfLocked) { 4352 proc = mPidsSelfLocked.get(pid); 4353 } 4354 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4355 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4356 + " from background process " + proc); 4357 return; 4358 } 4359 } 4360 closeSystemDialogsLocked(reason); 4361 } 4362 } finally { 4363 Binder.restoreCallingIdentity(origId); 4364 } 4365 } 4366 4367 void closeSystemDialogsLocked(String reason) { 4368 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4369 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4370 | Intent.FLAG_RECEIVER_FOREGROUND); 4371 if (reason != null) { 4372 intent.putExtra("reason", reason); 4373 } 4374 mWindowManager.closeSystemDialogs(reason); 4375 4376 mStackSupervisor.closeSystemDialogsLocked(); 4377 4378 broadcastIntentLocked(null, null, intent, null, 4379 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4380 Process.SYSTEM_UID, UserHandle.USER_ALL); 4381 } 4382 4383 @Override 4384 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4385 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4386 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4387 for (int i=pids.length-1; i>=0; i--) { 4388 ProcessRecord proc; 4389 int oomAdj; 4390 synchronized (this) { 4391 synchronized (mPidsSelfLocked) { 4392 proc = mPidsSelfLocked.get(pids[i]); 4393 oomAdj = proc != null ? proc.setAdj : 0; 4394 } 4395 } 4396 infos[i] = new Debug.MemoryInfo(); 4397 Debug.getMemoryInfo(pids[i], infos[i]); 4398 if (proc != null) { 4399 synchronized (this) { 4400 if (proc.thread != null && proc.setAdj == oomAdj) { 4401 // Record this for posterity if the process has been stable. 4402 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4403 infos[i].getTotalUss(), false, proc.pkgList); 4404 } 4405 } 4406 } 4407 } 4408 return infos; 4409 } 4410 4411 @Override 4412 public long[] getProcessPss(int[] pids) { 4413 enforceNotIsolatedCaller("getProcessPss"); 4414 long[] pss = new long[pids.length]; 4415 for (int i=pids.length-1; i>=0; i--) { 4416 ProcessRecord proc; 4417 int oomAdj; 4418 synchronized (this) { 4419 synchronized (mPidsSelfLocked) { 4420 proc = mPidsSelfLocked.get(pids[i]); 4421 oomAdj = proc != null ? proc.setAdj : 0; 4422 } 4423 } 4424 long[] tmpUss = new long[1]; 4425 pss[i] = Debug.getPss(pids[i], tmpUss); 4426 if (proc != null) { 4427 synchronized (this) { 4428 if (proc.thread != null && proc.setAdj == oomAdj) { 4429 // Record this for posterity if the process has been stable. 4430 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4431 } 4432 } 4433 } 4434 } 4435 return pss; 4436 } 4437 4438 @Override 4439 public void killApplicationProcess(String processName, int uid) { 4440 if (processName == null) { 4441 return; 4442 } 4443 4444 int callerUid = Binder.getCallingUid(); 4445 // Only the system server can kill an application 4446 if (callerUid == Process.SYSTEM_UID) { 4447 synchronized (this) { 4448 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4449 if (app != null && app.thread != null) { 4450 try { 4451 app.thread.scheduleSuicide(); 4452 } catch (RemoteException e) { 4453 // If the other end already died, then our work here is done. 4454 } 4455 } else { 4456 Slog.w(TAG, "Process/uid not found attempting kill of " 4457 + processName + " / " + uid); 4458 } 4459 } 4460 } else { 4461 throw new SecurityException(callerUid + " cannot kill app process: " + 4462 processName); 4463 } 4464 } 4465 4466 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4467 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4468 false, true, false, false, UserHandle.getUserId(uid), reason); 4469 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4470 Uri.fromParts("package", packageName, null)); 4471 if (!mProcessesReady) { 4472 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4473 | Intent.FLAG_RECEIVER_FOREGROUND); 4474 } 4475 intent.putExtra(Intent.EXTRA_UID, uid); 4476 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4477 broadcastIntentLocked(null, null, intent, 4478 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4479 false, false, 4480 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4481 } 4482 4483 private void forceStopUserLocked(int userId, String reason) { 4484 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4485 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4486 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4487 | Intent.FLAG_RECEIVER_FOREGROUND); 4488 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4489 broadcastIntentLocked(null, null, intent, 4490 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4491 false, false, 4492 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4493 } 4494 4495 private final boolean killPackageProcessesLocked(String packageName, int appId, 4496 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4497 boolean doit, boolean evenPersistent, String reason) { 4498 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4499 4500 // Remove all processes this package may have touched: all with the 4501 // same UID (except for the system or root user), and all whose name 4502 // matches the package name. 4503 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4504 final int NP = mProcessNames.getMap().size(); 4505 for (int ip=0; ip<NP; ip++) { 4506 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4507 final int NA = apps.size(); 4508 for (int ia=0; ia<NA; ia++) { 4509 ProcessRecord app = apps.valueAt(ia); 4510 if (app.persistent && !evenPersistent) { 4511 // we don't kill persistent processes 4512 continue; 4513 } 4514 if (app.removed) { 4515 if (doit) { 4516 procs.add(app); 4517 } 4518 continue; 4519 } 4520 4521 // Skip process if it doesn't meet our oom adj requirement. 4522 if (app.setAdj < minOomAdj) { 4523 continue; 4524 } 4525 4526 // If no package is specified, we call all processes under the 4527 // give user id. 4528 if (packageName == null) { 4529 if (app.userId != userId) { 4530 continue; 4531 } 4532 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4533 continue; 4534 } 4535 // Package has been specified, we want to hit all processes 4536 // that match it. We need to qualify this by the processes 4537 // that are running under the specified app and user ID. 4538 } else { 4539 if (UserHandle.getAppId(app.uid) != appId) { 4540 continue; 4541 } 4542 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4543 continue; 4544 } 4545 if (!app.pkgList.containsKey(packageName)) { 4546 continue; 4547 } 4548 } 4549 4550 // Process has passed all conditions, kill it! 4551 if (!doit) { 4552 return true; 4553 } 4554 app.removed = true; 4555 procs.add(app); 4556 } 4557 } 4558 4559 int N = procs.size(); 4560 for (int i=0; i<N; i++) { 4561 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4562 } 4563 updateOomAdjLocked(); 4564 return N > 0; 4565 } 4566 4567 private final boolean forceStopPackageLocked(String name, int appId, 4568 boolean callerWillRestart, boolean purgeCache, boolean doit, 4569 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4570 int i; 4571 int N; 4572 4573 if (userId == UserHandle.USER_ALL && name == null) { 4574 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4575 } 4576 4577 if (appId < 0 && name != null) { 4578 try { 4579 appId = UserHandle.getAppId( 4580 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4581 } catch (RemoteException e) { 4582 } 4583 } 4584 4585 if (doit) { 4586 if (name != null) { 4587 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4588 + " user=" + userId + ": " + reason); 4589 } else { 4590 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4591 } 4592 4593 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4594 for (int ip=pmap.size()-1; ip>=0; ip--) { 4595 SparseArray<Long> ba = pmap.valueAt(ip); 4596 for (i=ba.size()-1; i>=0; i--) { 4597 boolean remove = false; 4598 final int entUid = ba.keyAt(i); 4599 if (name != null) { 4600 if (userId == UserHandle.USER_ALL) { 4601 if (UserHandle.getAppId(entUid) == appId) { 4602 remove = true; 4603 } 4604 } else { 4605 if (entUid == UserHandle.getUid(userId, appId)) { 4606 remove = true; 4607 } 4608 } 4609 } else if (UserHandle.getUserId(entUid) == userId) { 4610 remove = true; 4611 } 4612 if (remove) { 4613 ba.removeAt(i); 4614 } 4615 } 4616 if (ba.size() == 0) { 4617 pmap.removeAt(ip); 4618 } 4619 } 4620 } 4621 4622 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4623 -100, callerWillRestart, true, doit, evenPersistent, 4624 name == null ? ("stop user " + userId) : ("stop " + name)); 4625 4626 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4627 if (!doit) { 4628 return true; 4629 } 4630 didSomething = true; 4631 } 4632 4633 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4634 if (!doit) { 4635 return true; 4636 } 4637 didSomething = true; 4638 } 4639 4640 if (name == null) { 4641 // Remove all sticky broadcasts from this user. 4642 mStickyBroadcasts.remove(userId); 4643 } 4644 4645 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4646 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4647 userId, providers)) { 4648 if (!doit) { 4649 return true; 4650 } 4651 didSomething = true; 4652 } 4653 N = providers.size(); 4654 for (i=0; i<N; i++) { 4655 removeDyingProviderLocked(null, providers.get(i), true); 4656 } 4657 4658 // Remove transient permissions granted from/to this package/user 4659 removeUriPermissionsForPackageLocked(name, userId, false); 4660 4661 if (name == null || uninstalling) { 4662 // Remove pending intents. For now we only do this when force 4663 // stopping users, because we have some problems when doing this 4664 // for packages -- app widgets are not currently cleaned up for 4665 // such packages, so they can be left with bad pending intents. 4666 if (mIntentSenderRecords.size() > 0) { 4667 Iterator<WeakReference<PendingIntentRecord>> it 4668 = mIntentSenderRecords.values().iterator(); 4669 while (it.hasNext()) { 4670 WeakReference<PendingIntentRecord> wpir = it.next(); 4671 if (wpir == null) { 4672 it.remove(); 4673 continue; 4674 } 4675 PendingIntentRecord pir = wpir.get(); 4676 if (pir == null) { 4677 it.remove(); 4678 continue; 4679 } 4680 if (name == null) { 4681 // Stopping user, remove all objects for the user. 4682 if (pir.key.userId != userId) { 4683 // Not the same user, skip it. 4684 continue; 4685 } 4686 } else { 4687 if (UserHandle.getAppId(pir.uid) != appId) { 4688 // Different app id, skip it. 4689 continue; 4690 } 4691 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4692 // Different user, skip it. 4693 continue; 4694 } 4695 if (!pir.key.packageName.equals(name)) { 4696 // Different package, skip it. 4697 continue; 4698 } 4699 } 4700 if (!doit) { 4701 return true; 4702 } 4703 didSomething = true; 4704 it.remove(); 4705 pir.canceled = true; 4706 if (pir.key.activity != null) { 4707 pir.key.activity.pendingResults.remove(pir.ref); 4708 } 4709 } 4710 } 4711 } 4712 4713 if (doit) { 4714 if (purgeCache && name != null) { 4715 AttributeCache ac = AttributeCache.instance(); 4716 if (ac != null) { 4717 ac.removePackage(name); 4718 } 4719 } 4720 if (mBooted) { 4721 mStackSupervisor.resumeTopActivitiesLocked(); 4722 mStackSupervisor.scheduleIdleLocked(); 4723 } 4724 } 4725 4726 return didSomething; 4727 } 4728 4729 private final boolean removeProcessLocked(ProcessRecord app, 4730 boolean callerWillRestart, boolean allowRestart, String reason) { 4731 final String name = app.processName; 4732 final int uid = app.uid; 4733 if (DEBUG_PROCESSES) Slog.d( 4734 TAG, "Force removing proc " + app.toShortString() + " (" + name 4735 + "/" + uid + ")"); 4736 4737 mProcessNames.remove(name, uid); 4738 mIsolatedProcesses.remove(app.uid); 4739 if (mHeavyWeightProcess == app) { 4740 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4741 mHeavyWeightProcess.userId, 0)); 4742 mHeavyWeightProcess = null; 4743 } 4744 boolean needRestart = false; 4745 if (app.pid > 0 && app.pid != MY_PID) { 4746 int pid = app.pid; 4747 synchronized (mPidsSelfLocked) { 4748 mPidsSelfLocked.remove(pid); 4749 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4750 } 4751 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4752 app.processName, app.info.uid); 4753 if (app.isolated) { 4754 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4755 } 4756 killUnneededProcessLocked(app, reason); 4757 handleAppDiedLocked(app, true, allowRestart); 4758 removeLruProcessLocked(app); 4759 4760 if (app.persistent && !app.isolated) { 4761 if (!callerWillRestart) { 4762 addAppLocked(app.info, false); 4763 } else { 4764 needRestart = true; 4765 } 4766 } 4767 } else { 4768 mRemovedProcesses.add(app); 4769 } 4770 4771 return needRestart; 4772 } 4773 4774 private final void processStartTimedOutLocked(ProcessRecord app) { 4775 final int pid = app.pid; 4776 boolean gone = false; 4777 synchronized (mPidsSelfLocked) { 4778 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4779 if (knownApp != null && knownApp.thread == null) { 4780 mPidsSelfLocked.remove(pid); 4781 gone = true; 4782 } 4783 } 4784 4785 if (gone) { 4786 Slog.w(TAG, "Process " + app + " failed to attach"); 4787 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4788 pid, app.uid, app.processName); 4789 mProcessNames.remove(app.processName, app.uid); 4790 mIsolatedProcesses.remove(app.uid); 4791 if (mHeavyWeightProcess == app) { 4792 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4793 mHeavyWeightProcess.userId, 0)); 4794 mHeavyWeightProcess = null; 4795 } 4796 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4797 app.processName, app.info.uid); 4798 if (app.isolated) { 4799 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4800 } 4801 // Take care of any launching providers waiting for this process. 4802 checkAppInLaunchingProvidersLocked(app, true); 4803 // Take care of any services that are waiting for the process. 4804 mServices.processStartTimedOutLocked(app); 4805 killUnneededProcessLocked(app, "start timeout"); 4806 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4807 Slog.w(TAG, "Unattached app died before backup, skipping"); 4808 try { 4809 IBackupManager bm = IBackupManager.Stub.asInterface( 4810 ServiceManager.getService(Context.BACKUP_SERVICE)); 4811 bm.agentDisconnected(app.info.packageName); 4812 } catch (RemoteException e) { 4813 // Can't happen; the backup manager is local 4814 } 4815 } 4816 if (isPendingBroadcastProcessLocked(pid)) { 4817 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4818 skipPendingBroadcastLocked(pid); 4819 } 4820 } else { 4821 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4822 } 4823 } 4824 4825 private final boolean attachApplicationLocked(IApplicationThread thread, 4826 int pid) { 4827 4828 // Find the application record that is being attached... either via 4829 // the pid if we are running in multiple processes, or just pull the 4830 // next app record if we are emulating process with anonymous threads. 4831 ProcessRecord app; 4832 if (pid != MY_PID && pid >= 0) { 4833 synchronized (mPidsSelfLocked) { 4834 app = mPidsSelfLocked.get(pid); 4835 } 4836 } else { 4837 app = null; 4838 } 4839 4840 if (app == null) { 4841 Slog.w(TAG, "No pending application record for pid " + pid 4842 + " (IApplicationThread " + thread + "); dropping process"); 4843 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4844 if (pid > 0 && pid != MY_PID) { 4845 Process.killProcessQuiet(pid); 4846 } else { 4847 try { 4848 thread.scheduleExit(); 4849 } catch (Exception e) { 4850 // Ignore exceptions. 4851 } 4852 } 4853 return false; 4854 } 4855 4856 // If this application record is still attached to a previous 4857 // process, clean it up now. 4858 if (app.thread != null) { 4859 handleAppDiedLocked(app, true, true); 4860 } 4861 4862 // Tell the process all about itself. 4863 4864 if (localLOGV) Slog.v( 4865 TAG, "Binding process pid " + pid + " to record " + app); 4866 4867 final String processName = app.processName; 4868 try { 4869 AppDeathRecipient adr = new AppDeathRecipient( 4870 app, pid, thread); 4871 thread.asBinder().linkToDeath(adr, 0); 4872 app.deathRecipient = adr; 4873 } catch (RemoteException e) { 4874 app.resetPackageList(mProcessStats); 4875 startProcessLocked(app, "link fail", processName); 4876 return false; 4877 } 4878 4879 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4880 4881 app.makeActive(thread, mProcessStats); 4882 app.curAdj = app.setAdj = -100; 4883 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4884 app.forcingToForeground = null; 4885 updateProcessForegroundLocked(app, false, false); 4886 app.hasShownUi = false; 4887 app.debugging = false; 4888 app.cached = false; 4889 4890 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4891 4892 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4893 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4894 4895 if (!normalMode) { 4896 Slog.i(TAG, "Launching preboot mode app: " + app); 4897 } 4898 4899 if (localLOGV) Slog.v( 4900 TAG, "New app record " + app 4901 + " thread=" + thread.asBinder() + " pid=" + pid); 4902 try { 4903 int testMode = IApplicationThread.DEBUG_OFF; 4904 if (mDebugApp != null && mDebugApp.equals(processName)) { 4905 testMode = mWaitForDebugger 4906 ? IApplicationThread.DEBUG_WAIT 4907 : IApplicationThread.DEBUG_ON; 4908 app.debugging = true; 4909 if (mDebugTransient) { 4910 mDebugApp = mOrigDebugApp; 4911 mWaitForDebugger = mOrigWaitForDebugger; 4912 } 4913 } 4914 String profileFile = app.instrumentationProfileFile; 4915 ParcelFileDescriptor profileFd = null; 4916 boolean profileAutoStop = false; 4917 if (mProfileApp != null && mProfileApp.equals(processName)) { 4918 mProfileProc = app; 4919 profileFile = mProfileFile; 4920 profileFd = mProfileFd; 4921 profileAutoStop = mAutoStopProfiler; 4922 } 4923 boolean enableOpenGlTrace = false; 4924 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4925 enableOpenGlTrace = true; 4926 mOpenGlTraceApp = null; 4927 } 4928 4929 // If the app is being launched for restore or full backup, set it up specially 4930 boolean isRestrictedBackupMode = false; 4931 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4932 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4933 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4934 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4935 } 4936 4937 ensurePackageDexOpt(app.instrumentationInfo != null 4938 ? app.instrumentationInfo.packageName 4939 : app.info.packageName); 4940 if (app.instrumentationClass != null) { 4941 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4942 } 4943 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4944 + processName + " with config " + mConfiguration); 4945 ApplicationInfo appInfo = app.instrumentationInfo != null 4946 ? app.instrumentationInfo : app.info; 4947 app.compat = compatibilityInfoForPackageLocked(appInfo); 4948 if (profileFd != null) { 4949 profileFd = profileFd.dup(); 4950 } 4951 thread.bindApplication(processName, appInfo, providers, 4952 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4953 app.instrumentationArguments, app.instrumentationWatcher, 4954 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4955 isRestrictedBackupMode || !normalMode, app.persistent, 4956 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4957 mCoreSettingsObserver.getCoreSettingsLocked()); 4958 updateLruProcessLocked(app, false, null); 4959 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4960 } catch (Exception e) { 4961 // todo: Yikes! What should we do? For now we will try to 4962 // start another process, but that could easily get us in 4963 // an infinite loop of restarting processes... 4964 Slog.w(TAG, "Exception thrown during bind!", e); 4965 4966 app.resetPackageList(mProcessStats); 4967 app.unlinkDeathRecipient(); 4968 startProcessLocked(app, "bind fail", processName); 4969 return false; 4970 } 4971 4972 // Remove this record from the list of starting applications. 4973 mPersistentStartingProcesses.remove(app); 4974 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4975 "Attach application locked removing on hold: " + app); 4976 mProcessesOnHold.remove(app); 4977 4978 boolean badApp = false; 4979 boolean didSomething = false; 4980 4981 // See if the top visible activity is waiting to run in this process... 4982 if (normalMode) { 4983 try { 4984 if (mStackSupervisor.attachApplicationLocked(app)) { 4985 didSomething = true; 4986 } 4987 } catch (Exception e) { 4988 badApp = true; 4989 } 4990 } 4991 4992 // Find any services that should be running in this process... 4993 if (!badApp) { 4994 try { 4995 didSomething |= mServices.attachApplicationLocked(app, processName); 4996 } catch (Exception e) { 4997 badApp = true; 4998 } 4999 } 5000 5001 // Check if a next-broadcast receiver is in this process... 5002 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5003 try { 5004 didSomething |= sendPendingBroadcastsLocked(app); 5005 } catch (Exception e) { 5006 // If the app died trying to launch the receiver we declare it 'bad' 5007 badApp = true; 5008 } 5009 } 5010 5011 // Check whether the next backup agent is in this process... 5012 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5013 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5014 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5015 try { 5016 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5017 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5018 mBackupTarget.backupMode); 5019 } catch (Exception e) { 5020 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5021 e.printStackTrace(); 5022 } 5023 } 5024 5025 if (badApp) { 5026 // todo: Also need to kill application to deal with all 5027 // kinds of exceptions. 5028 handleAppDiedLocked(app, false, true); 5029 return false; 5030 } 5031 5032 if (!didSomething) { 5033 updateOomAdjLocked(); 5034 } 5035 5036 return true; 5037 } 5038 5039 @Override 5040 public final void attachApplication(IApplicationThread thread) { 5041 synchronized (this) { 5042 int callingPid = Binder.getCallingPid(); 5043 final long origId = Binder.clearCallingIdentity(); 5044 attachApplicationLocked(thread, callingPid); 5045 Binder.restoreCallingIdentity(origId); 5046 } 5047 } 5048 5049 @Override 5050 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5051 final long origId = Binder.clearCallingIdentity(); 5052 synchronized (this) { 5053 ActivityStack stack = ActivityRecord.getStackLocked(token); 5054 if (stack != null) { 5055 ActivityRecord r = 5056 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5057 if (stopProfiling) { 5058 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5059 try { 5060 mProfileFd.close(); 5061 } catch (IOException e) { 5062 } 5063 clearProfilerLocked(); 5064 } 5065 } 5066 } 5067 } 5068 Binder.restoreCallingIdentity(origId); 5069 } 5070 5071 void enableScreenAfterBoot() { 5072 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5073 SystemClock.uptimeMillis()); 5074 mWindowManager.enableScreenAfterBoot(); 5075 5076 synchronized (this) { 5077 updateEventDispatchingLocked(); 5078 } 5079 } 5080 5081 @Override 5082 public void showBootMessage(final CharSequence msg, final boolean always) { 5083 enforceNotIsolatedCaller("showBootMessage"); 5084 mWindowManager.showBootMessage(msg, always); 5085 } 5086 5087 @Override 5088 public void dismissKeyguardOnNextActivity() { 5089 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5090 final long token = Binder.clearCallingIdentity(); 5091 try { 5092 synchronized (this) { 5093 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5094 if (mLockScreenShown) { 5095 mLockScreenShown = false; 5096 comeOutOfSleepIfNeededLocked(); 5097 } 5098 mStackSupervisor.setDismissKeyguard(true); 5099 } 5100 } finally { 5101 Binder.restoreCallingIdentity(token); 5102 } 5103 } 5104 5105 final void finishBooting() { 5106 IntentFilter pkgFilter = new IntentFilter(); 5107 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5108 pkgFilter.addDataScheme("package"); 5109 mContext.registerReceiver(new BroadcastReceiver() { 5110 @Override 5111 public void onReceive(Context context, Intent intent) { 5112 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5113 if (pkgs != null) { 5114 for (String pkg : pkgs) { 5115 synchronized (ActivityManagerService.this) { 5116 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 5117 "finished booting")) { 5118 setResultCode(Activity.RESULT_OK); 5119 return; 5120 } 5121 } 5122 } 5123 } 5124 } 5125 }, pkgFilter); 5126 5127 synchronized (this) { 5128 // Ensure that any processes we had put on hold are now started 5129 // up. 5130 final int NP = mProcessesOnHold.size(); 5131 if (NP > 0) { 5132 ArrayList<ProcessRecord> procs = 5133 new ArrayList<ProcessRecord>(mProcessesOnHold); 5134 for (int ip=0; ip<NP; ip++) { 5135 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5136 + procs.get(ip)); 5137 startProcessLocked(procs.get(ip), "on-hold", null); 5138 } 5139 } 5140 5141 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5142 // Start looking for apps that are abusing wake locks. 5143 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5144 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5145 // Tell anyone interested that we are done booting! 5146 SystemProperties.set("sys.boot_completed", "1"); 5147 SystemProperties.set("dev.bootcomplete", "1"); 5148 for (int i=0; i<mStartedUsers.size(); i++) { 5149 UserStartedState uss = mStartedUsers.valueAt(i); 5150 if (uss.mState == UserStartedState.STATE_BOOTING) { 5151 uss.mState = UserStartedState.STATE_RUNNING; 5152 final int userId = mStartedUsers.keyAt(i); 5153 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5154 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5155 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5156 broadcastIntentLocked(null, null, intent, null, 5157 new IIntentReceiver.Stub() { 5158 @Override 5159 public void performReceive(Intent intent, int resultCode, 5160 String data, Bundle extras, boolean ordered, 5161 boolean sticky, int sendingUser) { 5162 synchronized (ActivityManagerService.this) { 5163 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5164 true, false); 5165 } 5166 } 5167 }, 5168 0, null, null, 5169 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5170 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5171 userId); 5172 } 5173 } 5174 scheduleStartRelatedUsersLocked(); 5175 } 5176 } 5177 } 5178 5179 final void ensureBootCompleted() { 5180 boolean booting; 5181 boolean enableScreen; 5182 synchronized (this) { 5183 booting = mBooting; 5184 mBooting = false; 5185 enableScreen = !mBooted; 5186 mBooted = true; 5187 } 5188 5189 if (booting) { 5190 finishBooting(); 5191 } 5192 5193 if (enableScreen) { 5194 enableScreenAfterBoot(); 5195 } 5196 } 5197 5198 @Override 5199 public final void activityResumed(IBinder token) { 5200 final long origId = Binder.clearCallingIdentity(); 5201 synchronized(this) { 5202 ActivityStack stack = ActivityRecord.getStackLocked(token); 5203 if (stack != null) { 5204 ActivityRecord.activityResumedLocked(token); 5205 } 5206 } 5207 Binder.restoreCallingIdentity(origId); 5208 } 5209 5210 @Override 5211 public final void activityPaused(IBinder token) { 5212 final long origId = Binder.clearCallingIdentity(); 5213 synchronized(this) { 5214 ActivityStack stack = ActivityRecord.getStackLocked(token); 5215 if (stack != null) { 5216 stack.activityPausedLocked(token, false); 5217 } 5218 } 5219 Binder.restoreCallingIdentity(origId); 5220 } 5221 5222 @Override 5223 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5224 CharSequence description) { 5225 if (localLOGV) Slog.v( 5226 TAG, "Activity stopped: token=" + token); 5227 5228 // Refuse possible leaked file descriptors 5229 if (icicle != null && icicle.hasFileDescriptors()) { 5230 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5231 } 5232 5233 ActivityRecord r = null; 5234 5235 final long origId = Binder.clearCallingIdentity(); 5236 5237 synchronized (this) { 5238 r = ActivityRecord.isInStackLocked(token); 5239 if (r != null) { 5240 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5241 } 5242 } 5243 5244 if (r != null) { 5245 sendPendingThumbnail(r, null, null, null, false); 5246 } 5247 5248 trimApplications(); 5249 5250 Binder.restoreCallingIdentity(origId); 5251 } 5252 5253 @Override 5254 public final void activityDestroyed(IBinder token) { 5255 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5256 synchronized (this) { 5257 ActivityStack stack = ActivityRecord.getStackLocked(token); 5258 if (stack != null) { 5259 stack.activityDestroyedLocked(token); 5260 } 5261 } 5262 } 5263 5264 @Override 5265 public String getCallingPackage(IBinder token) { 5266 synchronized (this) { 5267 ActivityRecord r = getCallingRecordLocked(token); 5268 return r != null ? r.info.packageName : null; 5269 } 5270 } 5271 5272 @Override 5273 public ComponentName getCallingActivity(IBinder token) { 5274 synchronized (this) { 5275 ActivityRecord r = getCallingRecordLocked(token); 5276 return r != null ? r.intent.getComponent() : null; 5277 } 5278 } 5279 5280 private ActivityRecord getCallingRecordLocked(IBinder token) { 5281 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5282 if (r == null) { 5283 return null; 5284 } 5285 return r.resultTo; 5286 } 5287 5288 @Override 5289 public ComponentName getActivityClassForToken(IBinder token) { 5290 synchronized(this) { 5291 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5292 if (r == null) { 5293 return null; 5294 } 5295 return r.intent.getComponent(); 5296 } 5297 } 5298 5299 @Override 5300 public String getPackageForToken(IBinder token) { 5301 synchronized(this) { 5302 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5303 if (r == null) { 5304 return null; 5305 } 5306 return r.packageName; 5307 } 5308 } 5309 5310 @Override 5311 public IIntentSender getIntentSender(int type, 5312 String packageName, IBinder token, String resultWho, 5313 int requestCode, Intent[] intents, String[] resolvedTypes, 5314 int flags, Bundle options, int userId) { 5315 enforceNotIsolatedCaller("getIntentSender"); 5316 // Refuse possible leaked file descriptors 5317 if (intents != null) { 5318 if (intents.length < 1) { 5319 throw new IllegalArgumentException("Intents array length must be >= 1"); 5320 } 5321 for (int i=0; i<intents.length; i++) { 5322 Intent intent = intents[i]; 5323 if (intent != null) { 5324 if (intent.hasFileDescriptors()) { 5325 throw new IllegalArgumentException("File descriptors passed in Intent"); 5326 } 5327 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5328 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5329 throw new IllegalArgumentException( 5330 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5331 } 5332 intents[i] = new Intent(intent); 5333 } 5334 } 5335 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5336 throw new IllegalArgumentException( 5337 "Intent array length does not match resolvedTypes length"); 5338 } 5339 } 5340 if (options != null) { 5341 if (options.hasFileDescriptors()) { 5342 throw new IllegalArgumentException("File descriptors passed in options"); 5343 } 5344 } 5345 5346 synchronized(this) { 5347 int callingUid = Binder.getCallingUid(); 5348 int origUserId = userId; 5349 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5350 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5351 "getIntentSender", null); 5352 if (origUserId == UserHandle.USER_CURRENT) { 5353 // We don't want to evaluate this until the pending intent is 5354 // actually executed. However, we do want to always do the 5355 // security checking for it above. 5356 userId = UserHandle.USER_CURRENT; 5357 } 5358 try { 5359 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5360 int uid = AppGlobals.getPackageManager() 5361 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5362 if (!UserHandle.isSameApp(callingUid, uid)) { 5363 String msg = "Permission Denial: getIntentSender() from pid=" 5364 + Binder.getCallingPid() 5365 + ", uid=" + Binder.getCallingUid() 5366 + ", (need uid=" + uid + ")" 5367 + " is not allowed to send as package " + packageName; 5368 Slog.w(TAG, msg); 5369 throw new SecurityException(msg); 5370 } 5371 } 5372 5373 return getIntentSenderLocked(type, packageName, callingUid, userId, 5374 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5375 5376 } catch (RemoteException e) { 5377 throw new SecurityException(e); 5378 } 5379 } 5380 } 5381 5382 IIntentSender getIntentSenderLocked(int type, String packageName, 5383 int callingUid, int userId, IBinder token, String resultWho, 5384 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5385 Bundle options) { 5386 if (DEBUG_MU) 5387 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5388 ActivityRecord activity = null; 5389 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5390 activity = ActivityRecord.isInStackLocked(token); 5391 if (activity == null) { 5392 return null; 5393 } 5394 if (activity.finishing) { 5395 return null; 5396 } 5397 } 5398 5399 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5400 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5401 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5402 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5403 |PendingIntent.FLAG_UPDATE_CURRENT); 5404 5405 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5406 type, packageName, activity, resultWho, 5407 requestCode, intents, resolvedTypes, flags, options, userId); 5408 WeakReference<PendingIntentRecord> ref; 5409 ref = mIntentSenderRecords.get(key); 5410 PendingIntentRecord rec = ref != null ? ref.get() : null; 5411 if (rec != null) { 5412 if (!cancelCurrent) { 5413 if (updateCurrent) { 5414 if (rec.key.requestIntent != null) { 5415 rec.key.requestIntent.replaceExtras(intents != null ? 5416 intents[intents.length - 1] : null); 5417 } 5418 if (intents != null) { 5419 intents[intents.length-1] = rec.key.requestIntent; 5420 rec.key.allIntents = intents; 5421 rec.key.allResolvedTypes = resolvedTypes; 5422 } else { 5423 rec.key.allIntents = null; 5424 rec.key.allResolvedTypes = null; 5425 } 5426 } 5427 return rec; 5428 } 5429 rec.canceled = true; 5430 mIntentSenderRecords.remove(key); 5431 } 5432 if (noCreate) { 5433 return rec; 5434 } 5435 rec = new PendingIntentRecord(this, key, callingUid); 5436 mIntentSenderRecords.put(key, rec.ref); 5437 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5438 if (activity.pendingResults == null) { 5439 activity.pendingResults 5440 = new HashSet<WeakReference<PendingIntentRecord>>(); 5441 } 5442 activity.pendingResults.add(rec.ref); 5443 } 5444 return rec; 5445 } 5446 5447 @Override 5448 public void cancelIntentSender(IIntentSender sender) { 5449 if (!(sender instanceof PendingIntentRecord)) { 5450 return; 5451 } 5452 synchronized(this) { 5453 PendingIntentRecord rec = (PendingIntentRecord)sender; 5454 try { 5455 int uid = AppGlobals.getPackageManager() 5456 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5457 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5458 String msg = "Permission Denial: cancelIntentSender() from pid=" 5459 + Binder.getCallingPid() 5460 + ", uid=" + Binder.getCallingUid() 5461 + " is not allowed to cancel packges " 5462 + rec.key.packageName; 5463 Slog.w(TAG, msg); 5464 throw new SecurityException(msg); 5465 } 5466 } catch (RemoteException e) { 5467 throw new SecurityException(e); 5468 } 5469 cancelIntentSenderLocked(rec, true); 5470 } 5471 } 5472 5473 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5474 rec.canceled = true; 5475 mIntentSenderRecords.remove(rec.key); 5476 if (cleanActivity && rec.key.activity != null) { 5477 rec.key.activity.pendingResults.remove(rec.ref); 5478 } 5479 } 5480 5481 @Override 5482 public String getPackageForIntentSender(IIntentSender pendingResult) { 5483 if (!(pendingResult instanceof PendingIntentRecord)) { 5484 return null; 5485 } 5486 try { 5487 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5488 return res.key.packageName; 5489 } catch (ClassCastException e) { 5490 } 5491 return null; 5492 } 5493 5494 @Override 5495 public int getUidForIntentSender(IIntentSender sender) { 5496 if (sender instanceof PendingIntentRecord) { 5497 try { 5498 PendingIntentRecord res = (PendingIntentRecord)sender; 5499 return res.uid; 5500 } catch (ClassCastException e) { 5501 } 5502 } 5503 return -1; 5504 } 5505 5506 @Override 5507 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5508 if (!(pendingResult instanceof PendingIntentRecord)) { 5509 return false; 5510 } 5511 try { 5512 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5513 if (res.key.allIntents == null) { 5514 return false; 5515 } 5516 for (int i=0; i<res.key.allIntents.length; i++) { 5517 Intent intent = res.key.allIntents[i]; 5518 if (intent.getPackage() != null && intent.getComponent() != null) { 5519 return false; 5520 } 5521 } 5522 return true; 5523 } catch (ClassCastException e) { 5524 } 5525 return false; 5526 } 5527 5528 @Override 5529 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5530 if (!(pendingResult instanceof PendingIntentRecord)) { 5531 return false; 5532 } 5533 try { 5534 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5535 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5536 return true; 5537 } 5538 return false; 5539 } catch (ClassCastException e) { 5540 } 5541 return false; 5542 } 5543 5544 @Override 5545 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5546 if (!(pendingResult instanceof PendingIntentRecord)) { 5547 return null; 5548 } 5549 try { 5550 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5551 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5552 } catch (ClassCastException e) { 5553 } 5554 return null; 5555 } 5556 5557 @Override 5558 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5559 if (!(pendingResult instanceof PendingIntentRecord)) { 5560 return null; 5561 } 5562 try { 5563 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5564 Intent intent = res.key.requestIntent; 5565 if (intent != null) { 5566 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5567 || res.lastTagPrefix.equals(prefix))) { 5568 return res.lastTag; 5569 } 5570 res.lastTagPrefix = prefix; 5571 StringBuilder sb = new StringBuilder(128); 5572 if (prefix != null) { 5573 sb.append(prefix); 5574 } 5575 if (intent.getAction() != null) { 5576 sb.append(intent.getAction()); 5577 } else if (intent.getComponent() != null) { 5578 intent.getComponent().appendShortString(sb); 5579 } else { 5580 sb.append("?"); 5581 } 5582 return res.lastTag = sb.toString(); 5583 } 5584 } catch (ClassCastException e) { 5585 } 5586 return null; 5587 } 5588 5589 @Override 5590 public void setProcessLimit(int max) { 5591 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5592 "setProcessLimit()"); 5593 synchronized (this) { 5594 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5595 mProcessLimitOverride = max; 5596 } 5597 trimApplications(); 5598 } 5599 5600 @Override 5601 public int getProcessLimit() { 5602 synchronized (this) { 5603 return mProcessLimitOverride; 5604 } 5605 } 5606 5607 void foregroundTokenDied(ForegroundToken token) { 5608 synchronized (ActivityManagerService.this) { 5609 synchronized (mPidsSelfLocked) { 5610 ForegroundToken cur 5611 = mForegroundProcesses.get(token.pid); 5612 if (cur != token) { 5613 return; 5614 } 5615 mForegroundProcesses.remove(token.pid); 5616 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5617 if (pr == null) { 5618 return; 5619 } 5620 pr.forcingToForeground = null; 5621 updateProcessForegroundLocked(pr, false, false); 5622 } 5623 updateOomAdjLocked(); 5624 } 5625 } 5626 5627 @Override 5628 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5629 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5630 "setProcessForeground()"); 5631 synchronized(this) { 5632 boolean changed = false; 5633 5634 synchronized (mPidsSelfLocked) { 5635 ProcessRecord pr = mPidsSelfLocked.get(pid); 5636 if (pr == null && isForeground) { 5637 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5638 return; 5639 } 5640 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5641 if (oldToken != null) { 5642 oldToken.token.unlinkToDeath(oldToken, 0); 5643 mForegroundProcesses.remove(pid); 5644 if (pr != null) { 5645 pr.forcingToForeground = null; 5646 } 5647 changed = true; 5648 } 5649 if (isForeground && token != null) { 5650 ForegroundToken newToken = new ForegroundToken() { 5651 @Override 5652 public void binderDied() { 5653 foregroundTokenDied(this); 5654 } 5655 }; 5656 newToken.pid = pid; 5657 newToken.token = token; 5658 try { 5659 token.linkToDeath(newToken, 0); 5660 mForegroundProcesses.put(pid, newToken); 5661 pr.forcingToForeground = token; 5662 changed = true; 5663 } catch (RemoteException e) { 5664 // If the process died while doing this, we will later 5665 // do the cleanup with the process death link. 5666 } 5667 } 5668 } 5669 5670 if (changed) { 5671 updateOomAdjLocked(); 5672 } 5673 } 5674 } 5675 5676 // ========================================================= 5677 // PERMISSIONS 5678 // ========================================================= 5679 5680 static class PermissionController extends IPermissionController.Stub { 5681 ActivityManagerService mActivityManagerService; 5682 PermissionController(ActivityManagerService activityManagerService) { 5683 mActivityManagerService = activityManagerService; 5684 } 5685 5686 @Override 5687 public boolean checkPermission(String permission, int pid, int uid) { 5688 return mActivityManagerService.checkPermission(permission, pid, 5689 uid) == PackageManager.PERMISSION_GRANTED; 5690 } 5691 } 5692 5693 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5694 @Override 5695 public int checkComponentPermission(String permission, int pid, int uid, 5696 int owningUid, boolean exported) { 5697 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5698 owningUid, exported); 5699 } 5700 5701 @Override 5702 public Object getAMSLock() { 5703 return ActivityManagerService.this; 5704 } 5705 } 5706 5707 /** 5708 * This can be called with or without the global lock held. 5709 */ 5710 int checkComponentPermission(String permission, int pid, int uid, 5711 int owningUid, boolean exported) { 5712 // We might be performing an operation on behalf of an indirect binder 5713 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5714 // client identity accordingly before proceeding. 5715 Identity tlsIdentity = sCallerIdentity.get(); 5716 if (tlsIdentity != null) { 5717 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5718 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5719 uid = tlsIdentity.uid; 5720 pid = tlsIdentity.pid; 5721 } 5722 5723 if (pid == MY_PID) { 5724 return PackageManager.PERMISSION_GRANTED; 5725 } 5726 5727 return ActivityManager.checkComponentPermission(permission, uid, 5728 owningUid, exported); 5729 } 5730 5731 /** 5732 * As the only public entry point for permissions checking, this method 5733 * can enforce the semantic that requesting a check on a null global 5734 * permission is automatically denied. (Internally a null permission 5735 * string is used when calling {@link #checkComponentPermission} in cases 5736 * when only uid-based security is needed.) 5737 * 5738 * This can be called with or without the global lock held. 5739 */ 5740 @Override 5741 public int checkPermission(String permission, int pid, int uid) { 5742 if (permission == null) { 5743 return PackageManager.PERMISSION_DENIED; 5744 } 5745 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5746 } 5747 5748 /** 5749 * Binder IPC calls go through the public entry point. 5750 * This can be called with or without the global lock held. 5751 */ 5752 int checkCallingPermission(String permission) { 5753 return checkPermission(permission, 5754 Binder.getCallingPid(), 5755 UserHandle.getAppId(Binder.getCallingUid())); 5756 } 5757 5758 /** 5759 * This can be called with or without the global lock held. 5760 */ 5761 void enforceCallingPermission(String permission, String func) { 5762 if (checkCallingPermission(permission) 5763 == PackageManager.PERMISSION_GRANTED) { 5764 return; 5765 } 5766 5767 String msg = "Permission Denial: " + func + " from pid=" 5768 + Binder.getCallingPid() 5769 + ", uid=" + Binder.getCallingUid() 5770 + " requires " + permission; 5771 Slog.w(TAG, msg); 5772 throw new SecurityException(msg); 5773 } 5774 5775 /** 5776 * Determine if UID is holding permissions required to access {@link Uri} in 5777 * the given {@link ProviderInfo}. Final permission checking is always done 5778 * in {@link ContentProvider}. 5779 */ 5780 private final boolean checkHoldingPermissionsLocked( 5781 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5782 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5783 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5784 5785 if (pi.applicationInfo.uid == uid) { 5786 return true; 5787 } else if (!pi.exported) { 5788 return false; 5789 } 5790 5791 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5792 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5793 try { 5794 // check if target holds top-level <provider> permissions 5795 if (!readMet && pi.readPermission != null 5796 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5797 readMet = true; 5798 } 5799 if (!writeMet && pi.writePermission != null 5800 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5801 writeMet = true; 5802 } 5803 5804 // track if unprotected read/write is allowed; any denied 5805 // <path-permission> below removes this ability 5806 boolean allowDefaultRead = pi.readPermission == null; 5807 boolean allowDefaultWrite = pi.writePermission == null; 5808 5809 // check if target holds any <path-permission> that match uri 5810 final PathPermission[] pps = pi.pathPermissions; 5811 if (pps != null) { 5812 final String path = uri.getPath(); 5813 int i = pps.length; 5814 while (i > 0 && (!readMet || !writeMet)) { 5815 i--; 5816 PathPermission pp = pps[i]; 5817 if (pp.match(path)) { 5818 if (!readMet) { 5819 final String pprperm = pp.getReadPermission(); 5820 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5821 + pprperm + " for " + pp.getPath() 5822 + ": match=" + pp.match(path) 5823 + " check=" + pm.checkUidPermission(pprperm, uid)); 5824 if (pprperm != null) { 5825 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5826 readMet = true; 5827 } else { 5828 allowDefaultRead = false; 5829 } 5830 } 5831 } 5832 if (!writeMet) { 5833 final String ppwperm = pp.getWritePermission(); 5834 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5835 + ppwperm + " for " + pp.getPath() 5836 + ": match=" + pp.match(path) 5837 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5838 if (ppwperm != null) { 5839 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5840 writeMet = true; 5841 } else { 5842 allowDefaultWrite = false; 5843 } 5844 } 5845 } 5846 } 5847 } 5848 } 5849 5850 // grant unprotected <provider> read/write, if not blocked by 5851 // <path-permission> above 5852 if (allowDefaultRead) readMet = true; 5853 if (allowDefaultWrite) writeMet = true; 5854 5855 } catch (RemoteException e) { 5856 return false; 5857 } 5858 5859 return readMet && writeMet; 5860 } 5861 5862 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5863 ProviderInfo pi = null; 5864 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5865 if (cpr != null) { 5866 pi = cpr.info; 5867 } else { 5868 try { 5869 pi = AppGlobals.getPackageManager().resolveContentProvider( 5870 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5871 } catch (RemoteException ex) { 5872 } 5873 } 5874 return pi; 5875 } 5876 5877 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5878 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5879 if (targetUris != null) { 5880 return targetUris.get(uri); 5881 } else { 5882 return null; 5883 } 5884 } 5885 5886 private UriPermission findOrCreateUriPermissionLocked( 5887 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5888 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5889 if (targetUris == null) { 5890 targetUris = Maps.newArrayMap(); 5891 mGrantedUriPermissions.put(targetUid, targetUris); 5892 } 5893 5894 UriPermission perm = targetUris.get(uri); 5895 if (perm == null) { 5896 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5897 targetUris.put(uri, perm); 5898 } 5899 5900 return perm; 5901 } 5902 5903 private final boolean checkUriPermissionLocked( 5904 Uri uri, int uid, int modeFlags, int minStrength) { 5905 // Root gets to do everything. 5906 if (uid == 0) { 5907 return true; 5908 } 5909 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5910 if (perms == null) return false; 5911 UriPermission perm = perms.get(uri); 5912 if (perm == null) return false; 5913 return perm.getStrength(modeFlags) >= minStrength; 5914 } 5915 5916 @Override 5917 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5918 enforceNotIsolatedCaller("checkUriPermission"); 5919 5920 // Another redirected-binder-call permissions check as in 5921 // {@link checkComponentPermission}. 5922 Identity tlsIdentity = sCallerIdentity.get(); 5923 if (tlsIdentity != null) { 5924 uid = tlsIdentity.uid; 5925 pid = tlsIdentity.pid; 5926 } 5927 5928 // Our own process gets to do everything. 5929 if (pid == MY_PID) { 5930 return PackageManager.PERMISSION_GRANTED; 5931 } 5932 synchronized(this) { 5933 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5934 ? PackageManager.PERMISSION_GRANTED 5935 : PackageManager.PERMISSION_DENIED; 5936 } 5937 } 5938 5939 /** 5940 * Check if the targetPkg can be granted permission to access uri by 5941 * the callingUid using the given modeFlags. Throws a security exception 5942 * if callingUid is not allowed to do this. Returns the uid of the target 5943 * if the URI permission grant should be performed; returns -1 if it is not 5944 * needed (for example targetPkg already has permission to access the URI). 5945 * If you already know the uid of the target, you can supply it in 5946 * lastTargetUid else set that to -1. 5947 */ 5948 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5949 Uri uri, int modeFlags, int lastTargetUid) { 5950 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5951 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5952 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5953 if (modeFlags == 0) { 5954 return -1; 5955 } 5956 5957 if (targetPkg != null) { 5958 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5959 "Checking grant " + targetPkg + " permission to " + uri); 5960 } 5961 5962 final IPackageManager pm = AppGlobals.getPackageManager(); 5963 5964 // If this is not a content: uri, we can't do anything with it. 5965 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5966 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5967 "Can't grant URI permission for non-content URI: " + uri); 5968 return -1; 5969 } 5970 5971 final String authority = uri.getAuthority(); 5972 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 5973 if (pi == null) { 5974 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5975 return -1; 5976 } 5977 5978 int targetUid = lastTargetUid; 5979 if (targetUid < 0 && targetPkg != null) { 5980 try { 5981 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5982 if (targetUid < 0) { 5983 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5984 "Can't grant URI permission no uid for: " + targetPkg); 5985 return -1; 5986 } 5987 } catch (RemoteException ex) { 5988 return -1; 5989 } 5990 } 5991 5992 if (targetUid >= 0) { 5993 // First... does the target actually need this permission? 5994 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5995 // No need to grant the target this permission. 5996 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5997 "Target " + targetPkg + " already has full permission to " + uri); 5998 return -1; 5999 } 6000 } else { 6001 // First... there is no target package, so can anyone access it? 6002 boolean allowed = pi.exported; 6003 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6004 if (pi.readPermission != null) { 6005 allowed = false; 6006 } 6007 } 6008 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6009 if (pi.writePermission != null) { 6010 allowed = false; 6011 } 6012 } 6013 if (allowed) { 6014 return -1; 6015 } 6016 } 6017 6018 // Second... is the provider allowing granting of URI permissions? 6019 if (!pi.grantUriPermissions) { 6020 throw new SecurityException("Provider " + pi.packageName 6021 + "/" + pi.name 6022 + " does not allow granting of Uri permissions (uri " 6023 + uri + ")"); 6024 } 6025 if (pi.uriPermissionPatterns != null) { 6026 final int N = pi.uriPermissionPatterns.length; 6027 boolean allowed = false; 6028 for (int i=0; i<N; i++) { 6029 if (pi.uriPermissionPatterns[i] != null 6030 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6031 allowed = true; 6032 break; 6033 } 6034 } 6035 if (!allowed) { 6036 throw new SecurityException("Provider " + pi.packageName 6037 + "/" + pi.name 6038 + " does not allow granting of permission to path of Uri " 6039 + uri); 6040 } 6041 } 6042 6043 // Third... does the caller itself have permission to access 6044 // this uri? 6045 if (callingUid != Process.myUid()) { 6046 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6047 // Require they hold a strong enough Uri permission 6048 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6049 : UriPermission.STRENGTH_OWNED; 6050 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6051 throw new SecurityException("Uid " + callingUid 6052 + " does not have permission to uri " + uri); 6053 } 6054 } 6055 } 6056 6057 return targetUid; 6058 } 6059 6060 @Override 6061 public int checkGrantUriPermission(int callingUid, String targetPkg, 6062 Uri uri, int modeFlags) { 6063 enforceNotIsolatedCaller("checkGrantUriPermission"); 6064 synchronized(this) { 6065 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6066 } 6067 } 6068 6069 void grantUriPermissionUncheckedLocked( 6070 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6071 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6072 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6073 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6074 if (modeFlags == 0) { 6075 return; 6076 } 6077 6078 // So here we are: the caller has the assumed permission 6079 // to the uri, and the target doesn't. Let's now give this to 6080 // the target. 6081 6082 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6083 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6084 6085 final String authority = uri.getAuthority(); 6086 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6087 if (pi == null) { 6088 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6089 return; 6090 } 6091 6092 final UriPermission perm = findOrCreateUriPermissionLocked( 6093 pi.packageName, targetPkg, targetUid, uri); 6094 perm.grantModes(modeFlags, persistable, owner); 6095 } 6096 6097 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6098 int modeFlags, UriPermissionOwner owner) { 6099 if (targetPkg == null) { 6100 throw new NullPointerException("targetPkg"); 6101 } 6102 6103 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6104 if (targetUid < 0) { 6105 return; 6106 } 6107 6108 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6109 } 6110 6111 static class NeededUriGrants extends ArrayList<Uri> { 6112 final String targetPkg; 6113 final int targetUid; 6114 final int flags; 6115 6116 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6117 this.targetPkg = targetPkg; 6118 this.targetUid = targetUid; 6119 this.flags = flags; 6120 } 6121 } 6122 6123 /** 6124 * Like checkGrantUriPermissionLocked, but takes an Intent. 6125 */ 6126 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6127 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6128 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6129 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6130 + " clip=" + (intent != null ? intent.getClipData() : null) 6131 + " from " + intent + "; flags=0x" 6132 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6133 6134 if (targetPkg == null) { 6135 throw new NullPointerException("targetPkg"); 6136 } 6137 6138 if (intent == null) { 6139 return null; 6140 } 6141 Uri data = intent.getData(); 6142 ClipData clip = intent.getClipData(); 6143 if (data == null && clip == null) { 6144 return null; 6145 } 6146 6147 if (data != null) { 6148 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6149 mode, needed != null ? needed.targetUid : -1); 6150 if (targetUid > 0) { 6151 if (needed == null) { 6152 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6153 } 6154 needed.add(data); 6155 } 6156 } 6157 if (clip != null) { 6158 for (int i=0; i<clip.getItemCount(); i++) { 6159 Uri uri = clip.getItemAt(i).getUri(); 6160 if (uri != null) { 6161 int targetUid = -1; 6162 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6163 mode, needed != null ? needed.targetUid : -1); 6164 if (targetUid > 0) { 6165 if (needed == null) { 6166 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6167 } 6168 needed.add(uri); 6169 } 6170 } else { 6171 Intent clipIntent = clip.getItemAt(i).getIntent(); 6172 if (clipIntent != null) { 6173 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6174 callingUid, targetPkg, clipIntent, mode, needed); 6175 if (newNeeded != null) { 6176 needed = newNeeded; 6177 } 6178 } 6179 } 6180 } 6181 } 6182 6183 return needed; 6184 } 6185 6186 /** 6187 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6188 */ 6189 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6190 UriPermissionOwner owner) { 6191 if (needed != null) { 6192 for (int i=0; i<needed.size(); i++) { 6193 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6194 needed.get(i), needed.flags, owner); 6195 } 6196 } 6197 } 6198 6199 void grantUriPermissionFromIntentLocked(int callingUid, 6200 String targetPkg, Intent intent, UriPermissionOwner owner) { 6201 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6202 intent, intent != null ? intent.getFlags() : 0, null); 6203 if (needed == null) { 6204 return; 6205 } 6206 6207 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6208 } 6209 6210 @Override 6211 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6212 Uri uri, int modeFlags) { 6213 enforceNotIsolatedCaller("grantUriPermission"); 6214 synchronized(this) { 6215 final ProcessRecord r = getRecordForAppLocked(caller); 6216 if (r == null) { 6217 throw new SecurityException("Unable to find app for caller " 6218 + caller 6219 + " when granting permission to uri " + uri); 6220 } 6221 if (targetPkg == null) { 6222 throw new IllegalArgumentException("null target"); 6223 } 6224 if (uri == null) { 6225 throw new IllegalArgumentException("null uri"); 6226 } 6227 6228 // Persistable only supported through Intents 6229 Preconditions.checkFlagsArgument(modeFlags, 6230 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6231 6232 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6233 null); 6234 } 6235 } 6236 6237 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6238 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6239 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6240 ArrayMap<Uri, UriPermission> perms 6241 = mGrantedUriPermissions.get(perm.targetUid); 6242 if (perms != null) { 6243 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6244 "Removing " + perm.targetUid + " permission to " + perm.uri); 6245 perms.remove(perm.uri); 6246 if (perms.size() == 0) { 6247 mGrantedUriPermissions.remove(perm.targetUid); 6248 } 6249 } 6250 } 6251 } 6252 6253 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6254 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6255 6256 final IPackageManager pm = AppGlobals.getPackageManager(); 6257 final String authority = uri.getAuthority(); 6258 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6259 if (pi == null) { 6260 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6261 return; 6262 } 6263 6264 // Does the caller have this permission on the URI? 6265 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6266 // Right now, if you are not the original owner of the permission, 6267 // you are not allowed to revoke it. 6268 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6269 throw new SecurityException("Uid " + callingUid 6270 + " does not have permission to uri " + uri); 6271 //} 6272 } 6273 6274 boolean persistChanged = false; 6275 6276 // Go through all of the permissions and remove any that match. 6277 final List<String> SEGMENTS = uri.getPathSegments(); 6278 if (SEGMENTS != null) { 6279 final int NS = SEGMENTS.size(); 6280 int N = mGrantedUriPermissions.size(); 6281 for (int i=0; i<N; i++) { 6282 ArrayMap<Uri, UriPermission> perms 6283 = mGrantedUriPermissions.valueAt(i); 6284 Iterator<UriPermission> it = perms.values().iterator(); 6285 toploop: 6286 while (it.hasNext()) { 6287 UriPermission perm = it.next(); 6288 Uri targetUri = perm.uri; 6289 if (!authority.equals(targetUri.getAuthority())) { 6290 continue; 6291 } 6292 List<String> targetSegments = targetUri.getPathSegments(); 6293 if (targetSegments == null) { 6294 continue; 6295 } 6296 if (targetSegments.size() < NS) { 6297 continue; 6298 } 6299 for (int j=0; j<NS; j++) { 6300 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6301 continue toploop; 6302 } 6303 } 6304 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6305 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6306 persistChanged |= perm.clearModes(modeFlags, true); 6307 if (perm.modeFlags == 0) { 6308 it.remove(); 6309 } 6310 } 6311 if (perms.size() == 0) { 6312 mGrantedUriPermissions.remove( 6313 mGrantedUriPermissions.keyAt(i)); 6314 N--; 6315 i--; 6316 } 6317 } 6318 } 6319 6320 if (persistChanged) { 6321 schedulePersistUriGrants(); 6322 } 6323 } 6324 6325 @Override 6326 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6327 int modeFlags) { 6328 enforceNotIsolatedCaller("revokeUriPermission"); 6329 synchronized(this) { 6330 final ProcessRecord r = getRecordForAppLocked(caller); 6331 if (r == null) { 6332 throw new SecurityException("Unable to find app for caller " 6333 + caller 6334 + " when revoking permission to uri " + uri); 6335 } 6336 if (uri == null) { 6337 Slog.w(TAG, "revokeUriPermission: null uri"); 6338 return; 6339 } 6340 6341 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6342 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6343 if (modeFlags == 0) { 6344 return; 6345 } 6346 6347 final IPackageManager pm = AppGlobals.getPackageManager(); 6348 final String authority = uri.getAuthority(); 6349 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6350 if (pi == null) { 6351 Slog.w(TAG, "No content provider found for permission revoke: " 6352 + uri.toSafeString()); 6353 return; 6354 } 6355 6356 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6357 } 6358 } 6359 6360 /** 6361 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6362 * given package. 6363 * 6364 * @param packageName Package name to match, or {@code null} to apply to all 6365 * packages. 6366 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6367 * to all users. 6368 * @param persistable If persistable grants should be removed. 6369 */ 6370 private void removeUriPermissionsForPackageLocked( 6371 String packageName, int userHandle, boolean persistable) { 6372 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6373 throw new IllegalArgumentException("Must narrow by either package or user"); 6374 } 6375 6376 boolean persistChanged = false; 6377 6378 final int size = mGrantedUriPermissions.size(); 6379 for (int i = 0; i < size; i++) { 6380 // Only inspect grants matching user 6381 if (userHandle == UserHandle.USER_ALL 6382 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6383 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6384 .values().iterator(); 6385 while (it.hasNext()) { 6386 final UriPermission perm = it.next(); 6387 6388 // Only inspect grants matching package 6389 if (packageName == null || perm.sourcePkg.equals(packageName) 6390 || perm.targetPkg.equals(packageName)) { 6391 persistChanged |= perm.clearModes(~0, persistable); 6392 6393 // Only remove when no modes remain; any persisted grants 6394 // will keep this alive. 6395 if (perm.modeFlags == 0) { 6396 it.remove(); 6397 } 6398 } 6399 } 6400 } 6401 } 6402 6403 if (persistChanged) { 6404 schedulePersistUriGrants(); 6405 } 6406 } 6407 6408 @Override 6409 public IBinder newUriPermissionOwner(String name) { 6410 enforceNotIsolatedCaller("newUriPermissionOwner"); 6411 synchronized(this) { 6412 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6413 return owner.getExternalTokenLocked(); 6414 } 6415 } 6416 6417 @Override 6418 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6419 Uri uri, int modeFlags) { 6420 synchronized(this) { 6421 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6422 if (owner == null) { 6423 throw new IllegalArgumentException("Unknown owner: " + token); 6424 } 6425 if (fromUid != Binder.getCallingUid()) { 6426 if (Binder.getCallingUid() != Process.myUid()) { 6427 // Only system code can grant URI permissions on behalf 6428 // of other users. 6429 throw new SecurityException("nice try"); 6430 } 6431 } 6432 if (targetPkg == null) { 6433 throw new IllegalArgumentException("null target"); 6434 } 6435 if (uri == null) { 6436 throw new IllegalArgumentException("null uri"); 6437 } 6438 6439 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6440 } 6441 } 6442 6443 @Override 6444 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6445 synchronized(this) { 6446 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6447 if (owner == null) { 6448 throw new IllegalArgumentException("Unknown owner: " + token); 6449 } 6450 6451 if (uri == null) { 6452 owner.removeUriPermissionsLocked(mode); 6453 } else { 6454 owner.removeUriPermissionLocked(uri, mode); 6455 } 6456 } 6457 } 6458 6459 private void schedulePersistUriGrants() { 6460 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6461 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6462 10 * DateUtils.SECOND_IN_MILLIS); 6463 } 6464 } 6465 6466 private void writeGrantedUriPermissions() { 6467 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6468 6469 // Snapshot permissions so we can persist without lock 6470 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6471 synchronized (this) { 6472 final int size = mGrantedUriPermissions.size(); 6473 for (int i = 0 ; i < size; i++) { 6474 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6475 if (perm.persistedModeFlags != 0) { 6476 persist.add(perm.snapshot()); 6477 } 6478 } 6479 } 6480 } 6481 6482 FileOutputStream fos = null; 6483 try { 6484 fos = mGrantFile.startWrite(); 6485 6486 XmlSerializer out = new FastXmlSerializer(); 6487 out.setOutput(fos, "utf-8"); 6488 out.startDocument(null, true); 6489 out.startTag(null, TAG_URI_GRANTS); 6490 for (UriPermission.Snapshot perm : persist) { 6491 out.startTag(null, TAG_URI_GRANT); 6492 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6493 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6494 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6495 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6496 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6497 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6498 out.endTag(null, TAG_URI_GRANT); 6499 } 6500 out.endTag(null, TAG_URI_GRANTS); 6501 out.endDocument(); 6502 6503 mGrantFile.finishWrite(fos); 6504 } catch (IOException e) { 6505 if (fos != null) { 6506 mGrantFile.failWrite(fos); 6507 } 6508 } 6509 } 6510 6511 private void readGrantedUriPermissionsLocked() { 6512 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6513 6514 final long now = System.currentTimeMillis(); 6515 6516 FileInputStream fis = null; 6517 try { 6518 fis = mGrantFile.openRead(); 6519 final XmlPullParser in = Xml.newPullParser(); 6520 in.setInput(fis, null); 6521 6522 int type; 6523 while ((type = in.next()) != END_DOCUMENT) { 6524 final String tag = in.getName(); 6525 if (type == START_TAG) { 6526 if (TAG_URI_GRANT.equals(tag)) { 6527 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6528 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6529 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6530 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6531 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6532 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6533 6534 // Sanity check that provider still belongs to source package 6535 final ProviderInfo pi = getProviderInfoLocked( 6536 uri.getAuthority(), userHandle); 6537 if (pi != null && sourcePkg.equals(pi.packageName)) { 6538 int targetUid = -1; 6539 try { 6540 targetUid = AppGlobals.getPackageManager() 6541 .getPackageUid(targetPkg, userHandle); 6542 } catch (RemoteException e) { 6543 } 6544 if (targetUid != -1) { 6545 final UriPermission perm = findOrCreateUriPermissionLocked( 6546 sourcePkg, targetPkg, targetUid, uri); 6547 perm.initPersistedModes(modeFlags, createdTime); 6548 } 6549 } else { 6550 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6551 + " but instead found " + pi); 6552 } 6553 } 6554 } 6555 } 6556 } catch (FileNotFoundException e) { 6557 // Missing grants is okay 6558 } catch (IOException e) { 6559 Log.wtf(TAG, "Failed reading Uri grants", e); 6560 } catch (XmlPullParserException e) { 6561 Log.wtf(TAG, "Failed reading Uri grants", e); 6562 } finally { 6563 IoUtils.closeQuietly(fis); 6564 } 6565 } 6566 6567 @Override 6568 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6569 enforceNotIsolatedCaller("takePersistableUriPermission"); 6570 6571 Preconditions.checkFlagsArgument(modeFlags, 6572 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6573 6574 synchronized (this) { 6575 final int callingUid = Binder.getCallingUid(); 6576 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6577 if (perm == null) { 6578 throw new SecurityException("No permission grant found for UID " + callingUid 6579 + " and Uri " + uri.toSafeString()); 6580 } 6581 6582 boolean persistChanged = perm.takePersistableModes(modeFlags); 6583 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6584 6585 if (persistChanged) { 6586 schedulePersistUriGrants(); 6587 } 6588 } 6589 } 6590 6591 @Override 6592 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6593 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6594 6595 Preconditions.checkFlagsArgument(modeFlags, 6596 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6597 6598 synchronized (this) { 6599 final int callingUid = Binder.getCallingUid(); 6600 6601 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6602 if (perm == null) { 6603 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6604 + uri.toSafeString()); 6605 return; 6606 } 6607 6608 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6609 removeUriPermissionIfNeededLocked(perm); 6610 if (persistChanged) { 6611 schedulePersistUriGrants(); 6612 } 6613 } 6614 } 6615 6616 /** 6617 * Prune any older {@link UriPermission} for the given UID until outstanding 6618 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6619 * 6620 * @return if any mutations occured that require persisting. 6621 */ 6622 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6623 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6624 if (perms == null) return false; 6625 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6626 6627 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6628 for (UriPermission perm : perms.values()) { 6629 if (perm.persistedModeFlags != 0) { 6630 persisted.add(perm); 6631 } 6632 } 6633 6634 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6635 if (trimCount <= 0) return false; 6636 6637 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6638 for (int i = 0; i < trimCount; i++) { 6639 final UriPermission perm = persisted.get(i); 6640 6641 if (DEBUG_URI_PERMISSION) { 6642 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6643 } 6644 6645 perm.releasePersistableModes(~0); 6646 removeUriPermissionIfNeededLocked(perm); 6647 } 6648 6649 return true; 6650 } 6651 6652 @Override 6653 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6654 String packageName, boolean incoming) { 6655 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6656 Preconditions.checkNotNull(packageName, "packageName"); 6657 6658 final int callingUid = Binder.getCallingUid(); 6659 final IPackageManager pm = AppGlobals.getPackageManager(); 6660 try { 6661 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6662 if (packageUid != callingUid) { 6663 throw new SecurityException( 6664 "Package " + packageName + " does not belong to calling UID " + callingUid); 6665 } 6666 } catch (RemoteException e) { 6667 throw new SecurityException("Failed to verify package name ownership"); 6668 } 6669 6670 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6671 synchronized (this) { 6672 if (incoming) { 6673 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6674 if (perms == null) { 6675 Slog.w(TAG, "No permission grants found for " + packageName); 6676 } else { 6677 final int size = perms.size(); 6678 for (int i = 0; i < size; i++) { 6679 final UriPermission perm = perms.valueAt(i); 6680 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6681 result.add(perm.buildPersistedPublicApiObject()); 6682 } 6683 } 6684 } 6685 } else { 6686 final int size = mGrantedUriPermissions.size(); 6687 for (int i = 0; i < size; i++) { 6688 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6689 final int permsSize = perms.size(); 6690 for (int j = 0; j < permsSize; j++) { 6691 final UriPermission perm = perms.valueAt(j); 6692 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6693 result.add(perm.buildPersistedPublicApiObject()); 6694 } 6695 } 6696 } 6697 } 6698 } 6699 return new ParceledListSlice<android.content.UriPermission>(result); 6700 } 6701 6702 @Override 6703 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6704 synchronized (this) { 6705 ProcessRecord app = 6706 who != null ? getRecordForAppLocked(who) : null; 6707 if (app == null) return; 6708 6709 Message msg = Message.obtain(); 6710 msg.what = WAIT_FOR_DEBUGGER_MSG; 6711 msg.obj = app; 6712 msg.arg1 = waiting ? 1 : 0; 6713 mHandler.sendMessage(msg); 6714 } 6715 } 6716 6717 @Override 6718 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6719 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6720 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6721 outInfo.availMem = Process.getFreeMemory(); 6722 outInfo.totalMem = Process.getTotalMemory(); 6723 outInfo.threshold = homeAppMem; 6724 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6725 outInfo.hiddenAppThreshold = cachedAppMem; 6726 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6727 ProcessList.SERVICE_ADJ); 6728 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6729 ProcessList.VISIBLE_APP_ADJ); 6730 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6731 ProcessList.FOREGROUND_APP_ADJ); 6732 } 6733 6734 // ========================================================= 6735 // TASK MANAGEMENT 6736 // ========================================================= 6737 6738 @Override 6739 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6740 IThumbnailReceiver receiver) { 6741 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6742 6743 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6744 ActivityRecord topRecord = null; 6745 6746 synchronized(this) { 6747 if (localLOGV) Slog.v( 6748 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6749 + ", receiver=" + receiver); 6750 6751 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6752 != PackageManager.PERMISSION_GRANTED) { 6753 if (receiver != null) { 6754 // If the caller wants to wait for pending thumbnails, 6755 // it ain't gonna get them. 6756 try { 6757 receiver.finished(); 6758 } catch (RemoteException ex) { 6759 } 6760 } 6761 String msg = "Permission Denial: getTasks() from pid=" 6762 + Binder.getCallingPid() 6763 + ", uid=" + Binder.getCallingUid() 6764 + " requires " + android.Manifest.permission.GET_TASKS; 6765 Slog.w(TAG, msg); 6766 throw new SecurityException(msg); 6767 } 6768 6769 // TODO: Improve with MRU list from all ActivityStacks. 6770 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6771 6772 if (!pending.pendingRecords.isEmpty()) { 6773 mPendingThumbnails.add(pending); 6774 } 6775 } 6776 6777 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6778 6779 if (topRecord != null) { 6780 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6781 try { 6782 IApplicationThread topThumbnail = topRecord.app.thread; 6783 topThumbnail.requestThumbnail(topRecord.appToken); 6784 } catch (Exception e) { 6785 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6786 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6787 } 6788 } 6789 6790 if (pending == null && receiver != null) { 6791 // In this case all thumbnails were available and the client 6792 // is being asked to be told when the remaining ones come in... 6793 // which is unusually, since the top-most currently running 6794 // activity should never have a canned thumbnail! Oh well. 6795 try { 6796 receiver.finished(); 6797 } catch (RemoteException ex) { 6798 } 6799 } 6800 6801 return list; 6802 } 6803 6804 TaskRecord getMostRecentTask() { 6805 return mRecentTasks.get(0); 6806 } 6807 6808 @Override 6809 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6810 int flags, int userId) { 6811 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6812 false, true, "getRecentTasks", null); 6813 6814 synchronized (this) { 6815 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6816 "getRecentTasks()"); 6817 final boolean detailed = checkCallingPermission( 6818 android.Manifest.permission.GET_DETAILED_TASKS) 6819 == PackageManager.PERMISSION_GRANTED; 6820 6821 IPackageManager pm = AppGlobals.getPackageManager(); 6822 6823 final int N = mRecentTasks.size(); 6824 ArrayList<ActivityManager.RecentTaskInfo> res 6825 = new ArrayList<ActivityManager.RecentTaskInfo>( 6826 maxNum < N ? maxNum : N); 6827 for (int i=0; i<N && maxNum > 0; i++) { 6828 TaskRecord tr = mRecentTasks.get(i); 6829 // Only add calling user's recent tasks 6830 if (tr.userId != userId) continue; 6831 // Return the entry if desired by the caller. We always return 6832 // the first entry, because callers always expect this to be the 6833 // foreground app. We may filter others if the caller has 6834 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6835 // we should exclude the entry. 6836 6837 if (i == 0 6838 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6839 || (tr.intent == null) 6840 || ((tr.intent.getFlags() 6841 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6842 ActivityManager.RecentTaskInfo rti 6843 = new ActivityManager.RecentTaskInfo(); 6844 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6845 rti.persistentId = tr.taskId; 6846 rti.baseIntent = new Intent( 6847 tr.intent != null ? tr.intent : tr.affinityIntent); 6848 if (!detailed) { 6849 rti.baseIntent.replaceExtras((Bundle)null); 6850 } 6851 rti.origActivity = tr.origActivity; 6852 rti.description = tr.lastDescription; 6853 rti.stackId = tr.stack.mStackId; 6854 6855 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6856 // Check whether this activity is currently available. 6857 try { 6858 if (rti.origActivity != null) { 6859 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6860 == null) { 6861 continue; 6862 } 6863 } else if (rti.baseIntent != null) { 6864 if (pm.queryIntentActivities(rti.baseIntent, 6865 null, 0, userId) == null) { 6866 continue; 6867 } 6868 } 6869 } catch (RemoteException e) { 6870 // Will never happen. 6871 } 6872 } 6873 6874 res.add(rti); 6875 maxNum--; 6876 } 6877 } 6878 return res; 6879 } 6880 } 6881 6882 private TaskRecord recentTaskForIdLocked(int id) { 6883 final int N = mRecentTasks.size(); 6884 for (int i=0; i<N; i++) { 6885 TaskRecord tr = mRecentTasks.get(i); 6886 if (tr.taskId == id) { 6887 return tr; 6888 } 6889 } 6890 return null; 6891 } 6892 6893 @Override 6894 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6895 synchronized (this) { 6896 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6897 "getTaskThumbnails()"); 6898 TaskRecord tr = recentTaskForIdLocked(id); 6899 if (tr != null) { 6900 return tr.getTaskThumbnailsLocked(); 6901 } 6902 } 6903 return null; 6904 } 6905 6906 @Override 6907 public Bitmap getTaskTopThumbnail(int id) { 6908 synchronized (this) { 6909 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6910 "getTaskTopThumbnail()"); 6911 TaskRecord tr = recentTaskForIdLocked(id); 6912 if (tr != null) { 6913 return tr.getTaskTopThumbnailLocked(); 6914 } 6915 } 6916 return null; 6917 } 6918 6919 @Override 6920 public boolean removeSubTask(int taskId, int subTaskIndex) { 6921 synchronized (this) { 6922 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6923 "removeSubTask()"); 6924 long ident = Binder.clearCallingIdentity(); 6925 try { 6926 TaskRecord tr = recentTaskForIdLocked(taskId); 6927 if (tr != null) { 6928 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6929 } 6930 return false; 6931 } finally { 6932 Binder.restoreCallingIdentity(ident); 6933 } 6934 } 6935 } 6936 6937 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6938 if (!pr.killedByAm) { 6939 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6940 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6941 pr.processName, pr.setAdj, reason); 6942 pr.killedByAm = true; 6943 Process.killProcessQuiet(pr.pid); 6944 } 6945 } 6946 6947 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6948 tr.disposeThumbnail(); 6949 mRecentTasks.remove(tr); 6950 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6951 Intent baseIntent = new Intent( 6952 tr.intent != null ? tr.intent : tr.affinityIntent); 6953 ComponentName component = baseIntent.getComponent(); 6954 if (component == null) { 6955 Slog.w(TAG, "Now component for base intent of task: " + tr); 6956 return; 6957 } 6958 6959 // Find any running services associated with this app. 6960 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6961 6962 if (killProcesses) { 6963 // Find any running processes associated with this app. 6964 final String pkg = component.getPackageName(); 6965 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6966 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 6967 for (int i=0; i<pmap.size(); i++) { 6968 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 6969 for (int j=0; j<uids.size(); j++) { 6970 ProcessRecord proc = uids.valueAt(j); 6971 if (proc.userId != tr.userId) { 6972 continue; 6973 } 6974 if (!proc.pkgList.containsKey(pkg)) { 6975 continue; 6976 } 6977 procs.add(proc); 6978 } 6979 } 6980 6981 // Kill the running processes. 6982 for (int i=0; i<procs.size(); i++) { 6983 ProcessRecord pr = procs.get(i); 6984 if (pr == mHomeProcess) { 6985 // Don't kill the home process along with tasks from the same package. 6986 continue; 6987 } 6988 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 6989 killUnneededProcessLocked(pr, "remove task"); 6990 } else { 6991 pr.waitingToKill = "remove task"; 6992 } 6993 } 6994 } 6995 } 6996 6997 @Override 6998 public boolean removeTask(int taskId, int flags) { 6999 synchronized (this) { 7000 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7001 "removeTask()"); 7002 long ident = Binder.clearCallingIdentity(); 7003 try { 7004 TaskRecord tr = recentTaskForIdLocked(taskId); 7005 if (tr != null) { 7006 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 7007 if (r != null) { 7008 cleanUpRemovedTaskLocked(tr, flags); 7009 return true; 7010 } 7011 if (tr.mActivities.size() == 0) { 7012 // Caller is just removing a recent task that is 7013 // not actively running. That is easy! 7014 cleanUpRemovedTaskLocked(tr, flags); 7015 return true; 7016 } 7017 Slog.w(TAG, "removeTask: task " + taskId 7018 + " does not have activities to remove, " 7019 + " but numActivities=" + tr.numActivities 7020 + ": " + tr); 7021 } 7022 } finally { 7023 Binder.restoreCallingIdentity(ident); 7024 } 7025 } 7026 return false; 7027 } 7028 7029 /** 7030 * TODO: Add mController hook 7031 */ 7032 @Override 7033 public void moveTaskToFront(int task, int flags, Bundle options) { 7034 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7035 "moveTaskToFront()"); 7036 7037 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task); 7038 synchronized(this) { 7039 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7040 Binder.getCallingUid(), "Task to front")) { 7041 ActivityOptions.abort(options); 7042 return; 7043 } 7044 final long origId = Binder.clearCallingIdentity(); 7045 try { 7046 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7047 } finally { 7048 Binder.restoreCallingIdentity(origId); 7049 } 7050 ActivityOptions.abort(options); 7051 } 7052 } 7053 7054 @Override 7055 public void moveTaskToBack(int taskId) { 7056 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7057 "moveTaskToBack()"); 7058 7059 synchronized(this) { 7060 TaskRecord tr = recentTaskForIdLocked(taskId); 7061 if (tr != null) { 7062 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7063 ActivityStack stack = tr.stack; 7064 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7065 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7066 Binder.getCallingUid(), "Task to back")) { 7067 return; 7068 } 7069 } 7070 final long origId = Binder.clearCallingIdentity(); 7071 try { 7072 stack.moveTaskToBackLocked(taskId, null); 7073 } finally { 7074 Binder.restoreCallingIdentity(origId); 7075 } 7076 } 7077 } 7078 } 7079 7080 /** 7081 * Moves an activity, and all of the other activities within the same task, to the bottom 7082 * of the history stack. The activity's order within the task is unchanged. 7083 * 7084 * @param token A reference to the activity we wish to move 7085 * @param nonRoot If false then this only works if the activity is the root 7086 * of a task; if true it will work for any activity in a task. 7087 * @return Returns true if the move completed, false if not. 7088 */ 7089 @Override 7090 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7091 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7092 synchronized(this) { 7093 final long origId = Binder.clearCallingIdentity(); 7094 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7095 if (taskId >= 0) { 7096 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7097 } 7098 Binder.restoreCallingIdentity(origId); 7099 } 7100 return false; 7101 } 7102 7103 @Override 7104 public void moveTaskBackwards(int task) { 7105 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7106 "moveTaskBackwards()"); 7107 7108 synchronized(this) { 7109 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7110 Binder.getCallingUid(), "Task backwards")) { 7111 return; 7112 } 7113 final long origId = Binder.clearCallingIdentity(); 7114 moveTaskBackwardsLocked(task); 7115 Binder.restoreCallingIdentity(origId); 7116 } 7117 } 7118 7119 private final void moveTaskBackwardsLocked(int task) { 7120 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7121 } 7122 7123 @Override 7124 public IBinder getHomeActivityToken() throws RemoteException { 7125 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7126 "getHomeActivityToken()"); 7127 synchronized (this) { 7128 return mStackSupervisor.getHomeActivityToken(); 7129 } 7130 } 7131 7132 @Override 7133 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7134 IActivityContainerCallback callback) throws RemoteException { 7135 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7136 "createActivityContainer()"); 7137 synchronized (this) { 7138 if (parentActivityToken == null) { 7139 throw new IllegalArgumentException("parent token must not be null"); 7140 } 7141 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7142 if (r == null) { 7143 return null; 7144 } 7145 return mStackSupervisor.createActivityContainer(r, callback); 7146 } 7147 } 7148 7149 @Override 7150 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7151 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7152 "deleteActivityContainer()"); 7153 synchronized (this) { 7154 mStackSupervisor.deleteActivityContainer(container); 7155 } 7156 } 7157 7158 @Override 7159 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7160 throws RemoteException { 7161 synchronized (this) { 7162 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7163 if (stack != null) { 7164 return stack.mActivityContainer; 7165 } 7166 return null; 7167 } 7168 } 7169 7170 @Override 7171 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7172 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7173 "moveTaskToStack()"); 7174 if (stackId == HOME_STACK_ID) { 7175 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7176 new RuntimeException("here").fillInStackTrace()); 7177 } 7178 synchronized (this) { 7179 long ident = Binder.clearCallingIdentity(); 7180 try { 7181 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7182 + stackId + " toTop=" + toTop); 7183 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7184 } finally { 7185 Binder.restoreCallingIdentity(ident); 7186 } 7187 } 7188 } 7189 7190 @Override 7191 public void resizeStack(int stackBoxId, Rect bounds) { 7192 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7193 "resizeStackBox()"); 7194 long ident = Binder.clearCallingIdentity(); 7195 try { 7196 mWindowManager.resizeStack(stackBoxId, bounds); 7197 } finally { 7198 Binder.restoreCallingIdentity(ident); 7199 } 7200 } 7201 7202 @Override 7203 public List<StackInfo> getAllStackInfos() { 7204 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7205 "getAllStackInfos()"); 7206 long ident = Binder.clearCallingIdentity(); 7207 try { 7208 synchronized (this) { 7209 return mStackSupervisor.getAllStackInfosLocked(); 7210 } 7211 } finally { 7212 Binder.restoreCallingIdentity(ident); 7213 } 7214 } 7215 7216 @Override 7217 public StackInfo getStackInfo(int stackId) { 7218 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7219 "getStackInfo()"); 7220 long ident = Binder.clearCallingIdentity(); 7221 try { 7222 synchronized (this) { 7223 return mStackSupervisor.getStackInfoLocked(stackId); 7224 } 7225 } finally { 7226 Binder.restoreCallingIdentity(ident); 7227 } 7228 } 7229 7230 @Override 7231 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7232 synchronized(this) { 7233 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7234 } 7235 } 7236 7237 // ========================================================= 7238 // THUMBNAILS 7239 // ========================================================= 7240 7241 public void reportThumbnail(IBinder token, 7242 Bitmap thumbnail, CharSequence description) { 7243 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7244 final long origId = Binder.clearCallingIdentity(); 7245 sendPendingThumbnail(null, token, thumbnail, description, true); 7246 Binder.restoreCallingIdentity(origId); 7247 } 7248 7249 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7250 Bitmap thumbnail, CharSequence description, boolean always) { 7251 TaskRecord task; 7252 ArrayList<PendingThumbnailsRecord> receivers = null; 7253 7254 //System.out.println("Send pending thumbnail: " + r); 7255 7256 synchronized(this) { 7257 if (r == null) { 7258 r = ActivityRecord.isInStackLocked(token); 7259 if (r == null) { 7260 return; 7261 } 7262 } 7263 if (thumbnail == null && r.thumbHolder != null) { 7264 thumbnail = r.thumbHolder.lastThumbnail; 7265 description = r.thumbHolder.lastDescription; 7266 } 7267 if (thumbnail == null && !always) { 7268 // If there is no thumbnail, and this entry is not actually 7269 // going away, then abort for now and pick up the next 7270 // thumbnail we get. 7271 return; 7272 } 7273 task = r.task; 7274 7275 int N = mPendingThumbnails.size(); 7276 int i=0; 7277 while (i<N) { 7278 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7279 //System.out.println("Looking in " + pr.pendingRecords); 7280 if (pr.pendingRecords.remove(r)) { 7281 if (receivers == null) { 7282 receivers = new ArrayList<PendingThumbnailsRecord>(); 7283 } 7284 receivers.add(pr); 7285 if (pr.pendingRecords.size() == 0) { 7286 pr.finished = true; 7287 mPendingThumbnails.remove(i); 7288 N--; 7289 continue; 7290 } 7291 } 7292 i++; 7293 } 7294 } 7295 7296 if (receivers != null) { 7297 final int N = receivers.size(); 7298 for (int i=0; i<N; i++) { 7299 try { 7300 PendingThumbnailsRecord pr = receivers.get(i); 7301 pr.receiver.newThumbnail( 7302 task != null ? task.taskId : -1, thumbnail, description); 7303 if (pr.finished) { 7304 pr.receiver.finished(); 7305 } 7306 } catch (Exception e) { 7307 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7308 } 7309 } 7310 } 7311 } 7312 7313 // ========================================================= 7314 // CONTENT PROVIDERS 7315 // ========================================================= 7316 7317 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7318 List<ProviderInfo> providers = null; 7319 try { 7320 providers = AppGlobals.getPackageManager(). 7321 queryContentProviders(app.processName, app.uid, 7322 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7323 } catch (RemoteException ex) { 7324 } 7325 if (DEBUG_MU) 7326 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7327 int userId = app.userId; 7328 if (providers != null) { 7329 int N = providers.size(); 7330 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7331 for (int i=0; i<N; i++) { 7332 ProviderInfo cpi = 7333 (ProviderInfo)providers.get(i); 7334 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7335 cpi.name, cpi.flags); 7336 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7337 // This is a singleton provider, but a user besides the 7338 // default user is asking to initialize a process it runs 7339 // in... well, no, it doesn't actually run in this process, 7340 // it runs in the process of the default user. Get rid of it. 7341 providers.remove(i); 7342 N--; 7343 i--; 7344 continue; 7345 } 7346 7347 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7348 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7349 if (cpr == null) { 7350 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7351 mProviderMap.putProviderByClass(comp, cpr); 7352 } 7353 if (DEBUG_MU) 7354 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7355 app.pubProviders.put(cpi.name, cpr); 7356 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7357 // Don't add this if it is a platform component that is marked 7358 // to run in multiple processes, because this is actually 7359 // part of the framework so doesn't make sense to track as a 7360 // separate apk in the process. 7361 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7362 } 7363 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7364 } 7365 } 7366 return providers; 7367 } 7368 7369 /** 7370 * Check if {@link ProcessRecord} has a possible chance at accessing the 7371 * given {@link ProviderInfo}. Final permission checking is always done 7372 * in {@link ContentProvider}. 7373 */ 7374 private final String checkContentProviderPermissionLocked( 7375 ProviderInfo cpi, ProcessRecord r) { 7376 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7377 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7378 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7379 cpi.applicationInfo.uid, cpi.exported) 7380 == PackageManager.PERMISSION_GRANTED) { 7381 return null; 7382 } 7383 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7384 cpi.applicationInfo.uid, cpi.exported) 7385 == PackageManager.PERMISSION_GRANTED) { 7386 return null; 7387 } 7388 7389 PathPermission[] pps = cpi.pathPermissions; 7390 if (pps != null) { 7391 int i = pps.length; 7392 while (i > 0) { 7393 i--; 7394 PathPermission pp = pps[i]; 7395 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7396 cpi.applicationInfo.uid, cpi.exported) 7397 == PackageManager.PERMISSION_GRANTED) { 7398 return null; 7399 } 7400 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7401 cpi.applicationInfo.uid, cpi.exported) 7402 == PackageManager.PERMISSION_GRANTED) { 7403 return null; 7404 } 7405 } 7406 } 7407 7408 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7409 if (perms != null) { 7410 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7411 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7412 return null; 7413 } 7414 } 7415 } 7416 7417 String msg; 7418 if (!cpi.exported) { 7419 msg = "Permission Denial: opening provider " + cpi.name 7420 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7421 + ", uid=" + callingUid + ") that is not exported from uid " 7422 + cpi.applicationInfo.uid; 7423 } else { 7424 msg = "Permission Denial: opening provider " + cpi.name 7425 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7426 + ", uid=" + callingUid + ") requires " 7427 + cpi.readPermission + " or " + cpi.writePermission; 7428 } 7429 Slog.w(TAG, msg); 7430 return msg; 7431 } 7432 7433 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7434 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7435 if (r != null) { 7436 for (int i=0; i<r.conProviders.size(); i++) { 7437 ContentProviderConnection conn = r.conProviders.get(i); 7438 if (conn.provider == cpr) { 7439 if (DEBUG_PROVIDER) Slog.v(TAG, 7440 "Adding provider requested by " 7441 + r.processName + " from process " 7442 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7443 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7444 if (stable) { 7445 conn.stableCount++; 7446 conn.numStableIncs++; 7447 } else { 7448 conn.unstableCount++; 7449 conn.numUnstableIncs++; 7450 } 7451 return conn; 7452 } 7453 } 7454 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7455 if (stable) { 7456 conn.stableCount = 1; 7457 conn.numStableIncs = 1; 7458 } else { 7459 conn.unstableCount = 1; 7460 conn.numUnstableIncs = 1; 7461 } 7462 cpr.connections.add(conn); 7463 r.conProviders.add(conn); 7464 return conn; 7465 } 7466 cpr.addExternalProcessHandleLocked(externalProcessToken); 7467 return null; 7468 } 7469 7470 boolean decProviderCountLocked(ContentProviderConnection conn, 7471 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7472 if (conn != null) { 7473 cpr = conn.provider; 7474 if (DEBUG_PROVIDER) Slog.v(TAG, 7475 "Removing provider requested by " 7476 + conn.client.processName + " from process " 7477 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7478 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7479 if (stable) { 7480 conn.stableCount--; 7481 } else { 7482 conn.unstableCount--; 7483 } 7484 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7485 cpr.connections.remove(conn); 7486 conn.client.conProviders.remove(conn); 7487 return true; 7488 } 7489 return false; 7490 } 7491 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7492 return false; 7493 } 7494 7495 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7496 String name, IBinder token, boolean stable, int userId) { 7497 ContentProviderRecord cpr; 7498 ContentProviderConnection conn = null; 7499 ProviderInfo cpi = null; 7500 7501 synchronized(this) { 7502 ProcessRecord r = null; 7503 if (caller != null) { 7504 r = getRecordForAppLocked(caller); 7505 if (r == null) { 7506 throw new SecurityException( 7507 "Unable to find app for caller " + caller 7508 + " (pid=" + Binder.getCallingPid() 7509 + ") when getting content provider " + name); 7510 } 7511 } 7512 7513 // First check if this content provider has been published... 7514 cpr = mProviderMap.getProviderByName(name, userId); 7515 boolean providerRunning = cpr != null; 7516 if (providerRunning) { 7517 cpi = cpr.info; 7518 String msg; 7519 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7520 throw new SecurityException(msg); 7521 } 7522 7523 if (r != null && cpr.canRunHere(r)) { 7524 // This provider has been published or is in the process 7525 // of being published... but it is also allowed to run 7526 // in the caller's process, so don't make a connection 7527 // and just let the caller instantiate its own instance. 7528 ContentProviderHolder holder = cpr.newHolder(null); 7529 // don't give caller the provider object, it needs 7530 // to make its own. 7531 holder.provider = null; 7532 return holder; 7533 } 7534 7535 final long origId = Binder.clearCallingIdentity(); 7536 7537 // In this case the provider instance already exists, so we can 7538 // return it right away. 7539 conn = incProviderCountLocked(r, cpr, token, stable); 7540 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7541 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7542 // If this is a perceptible app accessing the provider, 7543 // make sure to count it as being accessed and thus 7544 // back up on the LRU list. This is good because 7545 // content providers are often expensive to start. 7546 updateLruProcessLocked(cpr.proc, false, null); 7547 } 7548 } 7549 7550 if (cpr.proc != null) { 7551 if (false) { 7552 if (cpr.name.flattenToShortString().equals( 7553 "com.android.providers.calendar/.CalendarProvider2")) { 7554 Slog.v(TAG, "****************** KILLING " 7555 + cpr.name.flattenToShortString()); 7556 Process.killProcess(cpr.proc.pid); 7557 } 7558 } 7559 boolean success = updateOomAdjLocked(cpr.proc); 7560 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7561 // NOTE: there is still a race here where a signal could be 7562 // pending on the process even though we managed to update its 7563 // adj level. Not sure what to do about this, but at least 7564 // the race is now smaller. 7565 if (!success) { 7566 // Uh oh... it looks like the provider's process 7567 // has been killed on us. We need to wait for a new 7568 // process to be started, and make sure its death 7569 // doesn't kill our process. 7570 Slog.i(TAG, 7571 "Existing provider " + cpr.name.flattenToShortString() 7572 + " is crashing; detaching " + r); 7573 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7574 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7575 if (!lastRef) { 7576 // This wasn't the last ref our process had on 7577 // the provider... we have now been killed, bail. 7578 return null; 7579 } 7580 providerRunning = false; 7581 conn = null; 7582 } 7583 } 7584 7585 Binder.restoreCallingIdentity(origId); 7586 } 7587 7588 boolean singleton; 7589 if (!providerRunning) { 7590 try { 7591 cpi = AppGlobals.getPackageManager(). 7592 resolveContentProvider(name, 7593 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7594 } catch (RemoteException ex) { 7595 } 7596 if (cpi == null) { 7597 return null; 7598 } 7599 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7600 cpi.name, cpi.flags); 7601 if (singleton) { 7602 userId = 0; 7603 } 7604 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7605 7606 String msg; 7607 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7608 throw new SecurityException(msg); 7609 } 7610 7611 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7612 && !cpi.processName.equals("system")) { 7613 // If this content provider does not run in the system 7614 // process, and the system is not yet ready to run other 7615 // processes, then fail fast instead of hanging. 7616 throw new IllegalArgumentException( 7617 "Attempt to launch content provider before system ready"); 7618 } 7619 7620 // Make sure that the user who owns this provider is started. If not, 7621 // we don't want to allow it to run. 7622 if (mStartedUsers.get(userId) == null) { 7623 Slog.w(TAG, "Unable to launch app " 7624 + cpi.applicationInfo.packageName + "/" 7625 + cpi.applicationInfo.uid + " for provider " 7626 + name + ": user " + userId + " is stopped"); 7627 return null; 7628 } 7629 7630 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7631 cpr = mProviderMap.getProviderByClass(comp, userId); 7632 final boolean firstClass = cpr == null; 7633 if (firstClass) { 7634 try { 7635 ApplicationInfo ai = 7636 AppGlobals.getPackageManager(). 7637 getApplicationInfo( 7638 cpi.applicationInfo.packageName, 7639 STOCK_PM_FLAGS, userId); 7640 if (ai == null) { 7641 Slog.w(TAG, "No package info for content provider " 7642 + cpi.name); 7643 return null; 7644 } 7645 ai = getAppInfoForUser(ai, userId); 7646 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7647 } catch (RemoteException ex) { 7648 // pm is in same process, this will never happen. 7649 } 7650 } 7651 7652 if (r != null && cpr.canRunHere(r)) { 7653 // If this is a multiprocess provider, then just return its 7654 // info and allow the caller to instantiate it. Only do 7655 // this if the provider is the same user as the caller's 7656 // process, or can run as root (so can be in any process). 7657 return cpr.newHolder(null); 7658 } 7659 7660 if (DEBUG_PROVIDER) { 7661 RuntimeException e = new RuntimeException("here"); 7662 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7663 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7664 } 7665 7666 // This is single process, and our app is now connecting to it. 7667 // See if we are already in the process of launching this 7668 // provider. 7669 final int N = mLaunchingProviders.size(); 7670 int i; 7671 for (i=0; i<N; i++) { 7672 if (mLaunchingProviders.get(i) == cpr) { 7673 break; 7674 } 7675 } 7676 7677 // If the provider is not already being launched, then get it 7678 // started. 7679 if (i >= N) { 7680 final long origId = Binder.clearCallingIdentity(); 7681 7682 try { 7683 // Content provider is now in use, its package can't be stopped. 7684 try { 7685 AppGlobals.getPackageManager().setPackageStoppedState( 7686 cpr.appInfo.packageName, false, userId); 7687 } catch (RemoteException e) { 7688 } catch (IllegalArgumentException e) { 7689 Slog.w(TAG, "Failed trying to unstop package " 7690 + cpr.appInfo.packageName + ": " + e); 7691 } 7692 7693 // Use existing process if already started 7694 ProcessRecord proc = getProcessRecordLocked( 7695 cpi.processName, cpr.appInfo.uid, false); 7696 if (proc != null && proc.thread != null) { 7697 if (DEBUG_PROVIDER) { 7698 Slog.d(TAG, "Installing in existing process " + proc); 7699 } 7700 proc.pubProviders.put(cpi.name, cpr); 7701 try { 7702 proc.thread.scheduleInstallProvider(cpi); 7703 } catch (RemoteException e) { 7704 } 7705 } else { 7706 proc = startProcessLocked(cpi.processName, 7707 cpr.appInfo, false, 0, "content provider", 7708 new ComponentName(cpi.applicationInfo.packageName, 7709 cpi.name), false, false, false); 7710 if (proc == null) { 7711 Slog.w(TAG, "Unable to launch app " 7712 + cpi.applicationInfo.packageName + "/" 7713 + cpi.applicationInfo.uid + " for provider " 7714 + name + ": process is bad"); 7715 return null; 7716 } 7717 } 7718 cpr.launchingApp = proc; 7719 mLaunchingProviders.add(cpr); 7720 } finally { 7721 Binder.restoreCallingIdentity(origId); 7722 } 7723 } 7724 7725 // Make sure the provider is published (the same provider class 7726 // may be published under multiple names). 7727 if (firstClass) { 7728 mProviderMap.putProviderByClass(comp, cpr); 7729 } 7730 7731 mProviderMap.putProviderByName(name, cpr); 7732 conn = incProviderCountLocked(r, cpr, token, stable); 7733 if (conn != null) { 7734 conn.waiting = true; 7735 } 7736 } 7737 } 7738 7739 // Wait for the provider to be published... 7740 synchronized (cpr) { 7741 while (cpr.provider == null) { 7742 if (cpr.launchingApp == null) { 7743 Slog.w(TAG, "Unable to launch app " 7744 + cpi.applicationInfo.packageName + "/" 7745 + cpi.applicationInfo.uid + " for provider " 7746 + name + ": launching app became null"); 7747 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7748 UserHandle.getUserId(cpi.applicationInfo.uid), 7749 cpi.applicationInfo.packageName, 7750 cpi.applicationInfo.uid, name); 7751 return null; 7752 } 7753 try { 7754 if (DEBUG_MU) { 7755 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7756 + cpr.launchingApp); 7757 } 7758 if (conn != null) { 7759 conn.waiting = true; 7760 } 7761 cpr.wait(); 7762 } catch (InterruptedException ex) { 7763 } finally { 7764 if (conn != null) { 7765 conn.waiting = false; 7766 } 7767 } 7768 } 7769 } 7770 return cpr != null ? cpr.newHolder(conn) : null; 7771 } 7772 7773 public final ContentProviderHolder getContentProvider( 7774 IApplicationThread caller, String name, int userId, boolean stable) { 7775 enforceNotIsolatedCaller("getContentProvider"); 7776 if (caller == null) { 7777 String msg = "null IApplicationThread when getting content provider " 7778 + name; 7779 Slog.w(TAG, msg); 7780 throw new SecurityException(msg); 7781 } 7782 7783 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7784 false, true, "getContentProvider", null); 7785 return getContentProviderImpl(caller, name, null, stable, userId); 7786 } 7787 7788 public ContentProviderHolder getContentProviderExternal( 7789 String name, int userId, IBinder token) { 7790 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7791 "Do not have permission in call getContentProviderExternal()"); 7792 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7793 false, true, "getContentProvider", null); 7794 return getContentProviderExternalUnchecked(name, token, userId); 7795 } 7796 7797 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7798 IBinder token, int userId) { 7799 return getContentProviderImpl(null, name, token, true, userId); 7800 } 7801 7802 /** 7803 * Drop a content provider from a ProcessRecord's bookkeeping 7804 */ 7805 public void removeContentProvider(IBinder connection, boolean stable) { 7806 enforceNotIsolatedCaller("removeContentProvider"); 7807 long ident = Binder.clearCallingIdentity(); 7808 try { 7809 synchronized (this) { 7810 ContentProviderConnection conn; 7811 try { 7812 conn = (ContentProviderConnection)connection; 7813 } catch (ClassCastException e) { 7814 String msg ="removeContentProvider: " + connection 7815 + " not a ContentProviderConnection"; 7816 Slog.w(TAG, msg); 7817 throw new IllegalArgumentException(msg); 7818 } 7819 if (conn == null) { 7820 throw new NullPointerException("connection is null"); 7821 } 7822 if (decProviderCountLocked(conn, null, null, stable)) { 7823 updateOomAdjLocked(); 7824 } 7825 } 7826 } finally { 7827 Binder.restoreCallingIdentity(ident); 7828 } 7829 } 7830 7831 public void removeContentProviderExternal(String name, IBinder token) { 7832 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7833 "Do not have permission in call removeContentProviderExternal()"); 7834 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7835 } 7836 7837 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7838 synchronized (this) { 7839 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7840 if(cpr == null) { 7841 //remove from mProvidersByClass 7842 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7843 return; 7844 } 7845 7846 //update content provider record entry info 7847 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7848 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7849 if (localCpr.hasExternalProcessHandles()) { 7850 if (localCpr.removeExternalProcessHandleLocked(token)) { 7851 updateOomAdjLocked(); 7852 } else { 7853 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7854 + " with no external reference for token: " 7855 + token + "."); 7856 } 7857 } else { 7858 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7859 + " with no external references."); 7860 } 7861 } 7862 } 7863 7864 public final void publishContentProviders(IApplicationThread caller, 7865 List<ContentProviderHolder> providers) { 7866 if (providers == null) { 7867 return; 7868 } 7869 7870 enforceNotIsolatedCaller("publishContentProviders"); 7871 synchronized (this) { 7872 final ProcessRecord r = getRecordForAppLocked(caller); 7873 if (DEBUG_MU) 7874 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 7875 if (r == null) { 7876 throw new SecurityException( 7877 "Unable to find app for caller " + caller 7878 + " (pid=" + Binder.getCallingPid() 7879 + ") when publishing content providers"); 7880 } 7881 7882 final long origId = Binder.clearCallingIdentity(); 7883 7884 final int N = providers.size(); 7885 for (int i=0; i<N; i++) { 7886 ContentProviderHolder src = providers.get(i); 7887 if (src == null || src.info == null || src.provider == null) { 7888 continue; 7889 } 7890 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 7891 if (DEBUG_MU) 7892 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 7893 if (dst != null) { 7894 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 7895 mProviderMap.putProviderByClass(comp, dst); 7896 String names[] = dst.info.authority.split(";"); 7897 for (int j = 0; j < names.length; j++) { 7898 mProviderMap.putProviderByName(names[j], dst); 7899 } 7900 7901 int NL = mLaunchingProviders.size(); 7902 int j; 7903 for (j=0; j<NL; j++) { 7904 if (mLaunchingProviders.get(j) == dst) { 7905 mLaunchingProviders.remove(j); 7906 j--; 7907 NL--; 7908 } 7909 } 7910 synchronized (dst) { 7911 dst.provider = src.provider; 7912 dst.proc = r; 7913 dst.notifyAll(); 7914 } 7915 updateOomAdjLocked(r); 7916 } 7917 } 7918 7919 Binder.restoreCallingIdentity(origId); 7920 } 7921 } 7922 7923 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 7924 ContentProviderConnection conn; 7925 try { 7926 conn = (ContentProviderConnection)connection; 7927 } catch (ClassCastException e) { 7928 String msg ="refContentProvider: " + connection 7929 + " not a ContentProviderConnection"; 7930 Slog.w(TAG, msg); 7931 throw new IllegalArgumentException(msg); 7932 } 7933 if (conn == null) { 7934 throw new NullPointerException("connection is null"); 7935 } 7936 7937 synchronized (this) { 7938 if (stable > 0) { 7939 conn.numStableIncs += stable; 7940 } 7941 stable = conn.stableCount + stable; 7942 if (stable < 0) { 7943 throw new IllegalStateException("stableCount < 0: " + stable); 7944 } 7945 7946 if (unstable > 0) { 7947 conn.numUnstableIncs += unstable; 7948 } 7949 unstable = conn.unstableCount + unstable; 7950 if (unstable < 0) { 7951 throw new IllegalStateException("unstableCount < 0: " + unstable); 7952 } 7953 7954 if ((stable+unstable) <= 0) { 7955 throw new IllegalStateException("ref counts can't go to zero here: stable=" 7956 + stable + " unstable=" + unstable); 7957 } 7958 conn.stableCount = stable; 7959 conn.unstableCount = unstable; 7960 return !conn.dead; 7961 } 7962 } 7963 7964 public void unstableProviderDied(IBinder connection) { 7965 ContentProviderConnection conn; 7966 try { 7967 conn = (ContentProviderConnection)connection; 7968 } catch (ClassCastException e) { 7969 String msg ="refContentProvider: " + connection 7970 + " not a ContentProviderConnection"; 7971 Slog.w(TAG, msg); 7972 throw new IllegalArgumentException(msg); 7973 } 7974 if (conn == null) { 7975 throw new NullPointerException("connection is null"); 7976 } 7977 7978 // Safely retrieve the content provider associated with the connection. 7979 IContentProvider provider; 7980 synchronized (this) { 7981 provider = conn.provider.provider; 7982 } 7983 7984 if (provider == null) { 7985 // Um, yeah, we're way ahead of you. 7986 return; 7987 } 7988 7989 // Make sure the caller is being honest with us. 7990 if (provider.asBinder().pingBinder()) { 7991 // Er, no, still looks good to us. 7992 synchronized (this) { 7993 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 7994 + " says " + conn + " died, but we don't agree"); 7995 return; 7996 } 7997 } 7998 7999 // Well look at that! It's dead! 8000 synchronized (this) { 8001 if (conn.provider.provider != provider) { 8002 // But something changed... good enough. 8003 return; 8004 } 8005 8006 ProcessRecord proc = conn.provider.proc; 8007 if (proc == null || proc.thread == null) { 8008 // Seems like the process is already cleaned up. 8009 return; 8010 } 8011 8012 // As far as we're concerned, this is just like receiving a 8013 // death notification... just a bit prematurely. 8014 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8015 + ") early provider death"); 8016 final long ident = Binder.clearCallingIdentity(); 8017 try { 8018 appDiedLocked(proc, proc.pid, proc.thread); 8019 } finally { 8020 Binder.restoreCallingIdentity(ident); 8021 } 8022 } 8023 } 8024 8025 @Override 8026 public void appNotRespondingViaProvider(IBinder connection) { 8027 enforceCallingPermission( 8028 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8029 8030 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8031 if (conn == null) { 8032 Slog.w(TAG, "ContentProviderConnection is null"); 8033 return; 8034 } 8035 8036 final ProcessRecord host = conn.provider.proc; 8037 if (host == null) { 8038 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8039 return; 8040 } 8041 8042 final long token = Binder.clearCallingIdentity(); 8043 try { 8044 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8045 } finally { 8046 Binder.restoreCallingIdentity(token); 8047 } 8048 } 8049 8050 public final void installSystemProviders() { 8051 List<ProviderInfo> providers; 8052 synchronized (this) { 8053 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8054 providers = generateApplicationProvidersLocked(app); 8055 if (providers != null) { 8056 for (int i=providers.size()-1; i>=0; i--) { 8057 ProviderInfo pi = (ProviderInfo)providers.get(i); 8058 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8059 Slog.w(TAG, "Not installing system proc provider " + pi.name 8060 + ": not system .apk"); 8061 providers.remove(i); 8062 } 8063 } 8064 } 8065 } 8066 if (providers != null) { 8067 mSystemThread.installSystemProviders(providers); 8068 } 8069 8070 mCoreSettingsObserver = new CoreSettingsObserver(this); 8071 8072 mUsageStatsService.monitorPackages(); 8073 } 8074 8075 /** 8076 * Allows app to retrieve the MIME type of a URI without having permission 8077 * to access its content provider. 8078 * 8079 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8080 * 8081 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8082 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8083 */ 8084 public String getProviderMimeType(Uri uri, int userId) { 8085 enforceNotIsolatedCaller("getProviderMimeType"); 8086 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8087 userId, false, true, "getProviderMimeType", null); 8088 final String name = uri.getAuthority(); 8089 final long ident = Binder.clearCallingIdentity(); 8090 ContentProviderHolder holder = null; 8091 8092 try { 8093 holder = getContentProviderExternalUnchecked(name, null, userId); 8094 if (holder != null) { 8095 return holder.provider.getType(uri); 8096 } 8097 } catch (RemoteException e) { 8098 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8099 return null; 8100 } finally { 8101 if (holder != null) { 8102 removeContentProviderExternalUnchecked(name, null, userId); 8103 } 8104 Binder.restoreCallingIdentity(ident); 8105 } 8106 8107 return null; 8108 } 8109 8110 // ========================================================= 8111 // GLOBAL MANAGEMENT 8112 // ========================================================= 8113 8114 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8115 boolean isolated) { 8116 String proc = customProcess != null ? customProcess : info.processName; 8117 BatteryStatsImpl.Uid.Proc ps = null; 8118 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8119 int uid = info.uid; 8120 if (isolated) { 8121 int userId = UserHandle.getUserId(uid); 8122 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8123 while (true) { 8124 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8125 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8126 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8127 } 8128 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8129 mNextIsolatedProcessUid++; 8130 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8131 // No process for this uid, use it. 8132 break; 8133 } 8134 stepsLeft--; 8135 if (stepsLeft <= 0) { 8136 return null; 8137 } 8138 } 8139 } 8140 return new ProcessRecord(stats, info, proc, uid); 8141 } 8142 8143 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8144 ProcessRecord app; 8145 if (!isolated) { 8146 app = getProcessRecordLocked(info.processName, info.uid, true); 8147 } else { 8148 app = null; 8149 } 8150 8151 if (app == null) { 8152 app = newProcessRecordLocked(info, null, isolated); 8153 mProcessNames.put(info.processName, app.uid, app); 8154 if (isolated) { 8155 mIsolatedProcesses.put(app.uid, app); 8156 } 8157 updateLruProcessLocked(app, false, null); 8158 updateOomAdjLocked(); 8159 } 8160 8161 // This package really, really can not be stopped. 8162 try { 8163 AppGlobals.getPackageManager().setPackageStoppedState( 8164 info.packageName, false, UserHandle.getUserId(app.uid)); 8165 } catch (RemoteException e) { 8166 } catch (IllegalArgumentException e) { 8167 Slog.w(TAG, "Failed trying to unstop package " 8168 + info.packageName + ": " + e); 8169 } 8170 8171 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8172 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8173 app.persistent = true; 8174 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8175 } 8176 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8177 mPersistentStartingProcesses.add(app); 8178 startProcessLocked(app, "added application", app.processName); 8179 } 8180 8181 return app; 8182 } 8183 8184 public void unhandledBack() { 8185 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8186 "unhandledBack()"); 8187 8188 synchronized(this) { 8189 final long origId = Binder.clearCallingIdentity(); 8190 try { 8191 getFocusedStack().unhandledBackLocked(); 8192 } finally { 8193 Binder.restoreCallingIdentity(origId); 8194 } 8195 } 8196 } 8197 8198 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8199 enforceNotIsolatedCaller("openContentUri"); 8200 final int userId = UserHandle.getCallingUserId(); 8201 String name = uri.getAuthority(); 8202 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8203 ParcelFileDescriptor pfd = null; 8204 if (cph != null) { 8205 // We record the binder invoker's uid in thread-local storage before 8206 // going to the content provider to open the file. Later, in the code 8207 // that handles all permissions checks, we look for this uid and use 8208 // that rather than the Activity Manager's own uid. The effect is that 8209 // we do the check against the caller's permissions even though it looks 8210 // to the content provider like the Activity Manager itself is making 8211 // the request. 8212 sCallerIdentity.set(new Identity( 8213 Binder.getCallingPid(), Binder.getCallingUid())); 8214 try { 8215 pfd = cph.provider.openFile(null, uri, "r", null); 8216 } catch (FileNotFoundException e) { 8217 // do nothing; pfd will be returned null 8218 } finally { 8219 // Ensure that whatever happens, we clean up the identity state 8220 sCallerIdentity.remove(); 8221 } 8222 8223 // We've got the fd now, so we're done with the provider. 8224 removeContentProviderExternalUnchecked(name, null, userId); 8225 } else { 8226 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8227 } 8228 return pfd; 8229 } 8230 8231 // Actually is sleeping or shutting down or whatever else in the future 8232 // is an inactive state. 8233 public boolean isSleepingOrShuttingDown() { 8234 return mSleeping || mShuttingDown; 8235 } 8236 8237 public void goingToSleep() { 8238 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8239 != PackageManager.PERMISSION_GRANTED) { 8240 throw new SecurityException("Requires permission " 8241 + android.Manifest.permission.DEVICE_POWER); 8242 } 8243 8244 synchronized(this) { 8245 mWentToSleep = true; 8246 updateEventDispatchingLocked(); 8247 8248 if (!mSleeping) { 8249 mSleeping = true; 8250 mStackSupervisor.goingToSleepLocked(); 8251 8252 // Initialize the wake times of all processes. 8253 checkExcessivePowerUsageLocked(false); 8254 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8255 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8256 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8257 } 8258 } 8259 } 8260 8261 @Override 8262 public boolean shutdown(int timeout) { 8263 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8264 != PackageManager.PERMISSION_GRANTED) { 8265 throw new SecurityException("Requires permission " 8266 + android.Manifest.permission.SHUTDOWN); 8267 } 8268 8269 boolean timedout = false; 8270 8271 synchronized(this) { 8272 mShuttingDown = true; 8273 updateEventDispatchingLocked(); 8274 timedout = mStackSupervisor.shutdownLocked(timeout); 8275 } 8276 8277 mAppOpsService.shutdown(); 8278 mUsageStatsService.shutdown(); 8279 mBatteryStatsService.shutdown(); 8280 synchronized (this) { 8281 mProcessStats.shutdownLocked(); 8282 } 8283 8284 return timedout; 8285 } 8286 8287 public final void activitySlept(IBinder token) { 8288 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8289 8290 final long origId = Binder.clearCallingIdentity(); 8291 8292 synchronized (this) { 8293 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8294 if (r != null) { 8295 mStackSupervisor.activitySleptLocked(r); 8296 } 8297 } 8298 8299 Binder.restoreCallingIdentity(origId); 8300 } 8301 8302 void logLockScreen(String msg) { 8303 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8304 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8305 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8306 mStackSupervisor.mDismissKeyguardOnNextActivity); 8307 } 8308 8309 private void comeOutOfSleepIfNeededLocked() { 8310 if (!mWentToSleep && !mLockScreenShown) { 8311 if (mSleeping) { 8312 mSleeping = false; 8313 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8314 } 8315 } 8316 } 8317 8318 public void wakingUp() { 8319 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8320 != PackageManager.PERMISSION_GRANTED) { 8321 throw new SecurityException("Requires permission " 8322 + android.Manifest.permission.DEVICE_POWER); 8323 } 8324 8325 synchronized(this) { 8326 mWentToSleep = false; 8327 updateEventDispatchingLocked(); 8328 comeOutOfSleepIfNeededLocked(); 8329 } 8330 } 8331 8332 private void updateEventDispatchingLocked() { 8333 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8334 } 8335 8336 public void setLockScreenShown(boolean shown) { 8337 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8338 != PackageManager.PERMISSION_GRANTED) { 8339 throw new SecurityException("Requires permission " 8340 + android.Manifest.permission.DEVICE_POWER); 8341 } 8342 8343 synchronized(this) { 8344 long ident = Binder.clearCallingIdentity(); 8345 try { 8346 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8347 mLockScreenShown = shown; 8348 comeOutOfSleepIfNeededLocked(); 8349 } finally { 8350 Binder.restoreCallingIdentity(ident); 8351 } 8352 } 8353 } 8354 8355 public void stopAppSwitches() { 8356 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8357 != PackageManager.PERMISSION_GRANTED) { 8358 throw new SecurityException("Requires permission " 8359 + android.Manifest.permission.STOP_APP_SWITCHES); 8360 } 8361 8362 synchronized(this) { 8363 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8364 + APP_SWITCH_DELAY_TIME; 8365 mDidAppSwitch = false; 8366 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8367 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8368 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8369 } 8370 } 8371 8372 public void resumeAppSwitches() { 8373 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8374 != PackageManager.PERMISSION_GRANTED) { 8375 throw new SecurityException("Requires permission " 8376 + android.Manifest.permission.STOP_APP_SWITCHES); 8377 } 8378 8379 synchronized(this) { 8380 // Note that we don't execute any pending app switches... we will 8381 // let those wait until either the timeout, or the next start 8382 // activity request. 8383 mAppSwitchesAllowedTime = 0; 8384 } 8385 } 8386 8387 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8388 String name) { 8389 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8390 return true; 8391 } 8392 8393 final int perm = checkComponentPermission( 8394 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8395 callingUid, -1, true); 8396 if (perm == PackageManager.PERMISSION_GRANTED) { 8397 return true; 8398 } 8399 8400 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8401 return false; 8402 } 8403 8404 public void setDebugApp(String packageName, boolean waitForDebugger, 8405 boolean persistent) { 8406 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8407 "setDebugApp()"); 8408 8409 long ident = Binder.clearCallingIdentity(); 8410 try { 8411 // Note that this is not really thread safe if there are multiple 8412 // callers into it at the same time, but that's not a situation we 8413 // care about. 8414 if (persistent) { 8415 final ContentResolver resolver = mContext.getContentResolver(); 8416 Settings.Global.putString( 8417 resolver, Settings.Global.DEBUG_APP, 8418 packageName); 8419 Settings.Global.putInt( 8420 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8421 waitForDebugger ? 1 : 0); 8422 } 8423 8424 synchronized (this) { 8425 if (!persistent) { 8426 mOrigDebugApp = mDebugApp; 8427 mOrigWaitForDebugger = mWaitForDebugger; 8428 } 8429 mDebugApp = packageName; 8430 mWaitForDebugger = waitForDebugger; 8431 mDebugTransient = !persistent; 8432 if (packageName != null) { 8433 forceStopPackageLocked(packageName, -1, false, false, true, true, 8434 false, UserHandle.USER_ALL, "set debug app"); 8435 } 8436 } 8437 } finally { 8438 Binder.restoreCallingIdentity(ident); 8439 } 8440 } 8441 8442 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8443 synchronized (this) { 8444 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8445 if (!isDebuggable) { 8446 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8447 throw new SecurityException("Process not debuggable: " + app.packageName); 8448 } 8449 } 8450 8451 mOpenGlTraceApp = processName; 8452 } 8453 } 8454 8455 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8456 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8457 synchronized (this) { 8458 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8459 if (!isDebuggable) { 8460 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8461 throw new SecurityException("Process not debuggable: " + app.packageName); 8462 } 8463 } 8464 mProfileApp = processName; 8465 mProfileFile = profileFile; 8466 if (mProfileFd != null) { 8467 try { 8468 mProfileFd.close(); 8469 } catch (IOException e) { 8470 } 8471 mProfileFd = null; 8472 } 8473 mProfileFd = profileFd; 8474 mProfileType = 0; 8475 mAutoStopProfiler = autoStopProfiler; 8476 } 8477 } 8478 8479 @Override 8480 public void setAlwaysFinish(boolean enabled) { 8481 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8482 "setAlwaysFinish()"); 8483 8484 Settings.Global.putInt( 8485 mContext.getContentResolver(), 8486 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8487 8488 synchronized (this) { 8489 mAlwaysFinishActivities = enabled; 8490 } 8491 } 8492 8493 @Override 8494 public void setActivityController(IActivityController controller) { 8495 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8496 "setActivityController()"); 8497 synchronized (this) { 8498 mController = controller; 8499 Watchdog.getInstance().setActivityController(controller); 8500 } 8501 } 8502 8503 @Override 8504 public void setUserIsMonkey(boolean userIsMonkey) { 8505 synchronized (this) { 8506 synchronized (mPidsSelfLocked) { 8507 final int callingPid = Binder.getCallingPid(); 8508 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8509 if (precessRecord == null) { 8510 throw new SecurityException("Unknown process: " + callingPid); 8511 } 8512 if (precessRecord.instrumentationUiAutomationConnection == null) { 8513 throw new SecurityException("Only an instrumentation process " 8514 + "with a UiAutomation can call setUserIsMonkey"); 8515 } 8516 } 8517 mUserIsMonkey = userIsMonkey; 8518 } 8519 } 8520 8521 @Override 8522 public boolean isUserAMonkey() { 8523 synchronized (this) { 8524 // If there is a controller also implies the user is a monkey. 8525 return (mUserIsMonkey || mController != null); 8526 } 8527 } 8528 8529 public void requestBugReport() { 8530 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8531 SystemProperties.set("ctl.start", "bugreport"); 8532 } 8533 8534 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8535 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8536 } 8537 8538 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8539 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8540 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8541 } 8542 return KEY_DISPATCHING_TIMEOUT; 8543 } 8544 8545 @Override 8546 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8547 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8548 != PackageManager.PERMISSION_GRANTED) { 8549 throw new SecurityException("Requires permission " 8550 + android.Manifest.permission.FILTER_EVENTS); 8551 } 8552 ProcessRecord proc; 8553 long timeout; 8554 synchronized (this) { 8555 synchronized (mPidsSelfLocked) { 8556 proc = mPidsSelfLocked.get(pid); 8557 } 8558 timeout = getInputDispatchingTimeoutLocked(proc); 8559 } 8560 8561 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8562 return -1; 8563 } 8564 8565 return timeout; 8566 } 8567 8568 /** 8569 * Handle input dispatching timeouts. 8570 * Returns whether input dispatching should be aborted or not. 8571 */ 8572 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8573 final ActivityRecord activity, final ActivityRecord parent, 8574 final boolean aboveSystem, String reason) { 8575 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8576 != PackageManager.PERMISSION_GRANTED) { 8577 throw new SecurityException("Requires permission " 8578 + android.Manifest.permission.FILTER_EVENTS); 8579 } 8580 8581 final String annotation; 8582 if (reason == null) { 8583 annotation = "Input dispatching timed out"; 8584 } else { 8585 annotation = "Input dispatching timed out (" + reason + ")"; 8586 } 8587 8588 if (proc != null) { 8589 synchronized (this) { 8590 if (proc.debugging) { 8591 return false; 8592 } 8593 8594 if (mDidDexOpt) { 8595 // Give more time since we were dexopting. 8596 mDidDexOpt = false; 8597 return false; 8598 } 8599 8600 if (proc.instrumentationClass != null) { 8601 Bundle info = new Bundle(); 8602 info.putString("shortMsg", "keyDispatchingTimedOut"); 8603 info.putString("longMsg", annotation); 8604 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8605 return true; 8606 } 8607 } 8608 mHandler.post(new Runnable() { 8609 @Override 8610 public void run() { 8611 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8612 } 8613 }); 8614 } 8615 8616 return true; 8617 } 8618 8619 public Bundle getAssistContextExtras(int requestType) { 8620 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8621 "getAssistContextExtras()"); 8622 PendingAssistExtras pae; 8623 Bundle extras = new Bundle(); 8624 synchronized (this) { 8625 ActivityRecord activity = getFocusedStack().mResumedActivity; 8626 if (activity == null) { 8627 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8628 return null; 8629 } 8630 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8631 if (activity.app == null || activity.app.thread == null) { 8632 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8633 return extras; 8634 } 8635 if (activity.app.pid == Binder.getCallingPid()) { 8636 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8637 return extras; 8638 } 8639 pae = new PendingAssistExtras(activity); 8640 try { 8641 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8642 requestType); 8643 mPendingAssistExtras.add(pae); 8644 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8645 } catch (RemoteException e) { 8646 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8647 return extras; 8648 } 8649 } 8650 synchronized (pae) { 8651 while (!pae.haveResult) { 8652 try { 8653 pae.wait(); 8654 } catch (InterruptedException e) { 8655 } 8656 } 8657 if (pae.result != null) { 8658 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8659 } 8660 } 8661 synchronized (this) { 8662 mPendingAssistExtras.remove(pae); 8663 mHandler.removeCallbacks(pae); 8664 } 8665 return extras; 8666 } 8667 8668 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8669 PendingAssistExtras pae = (PendingAssistExtras)token; 8670 synchronized (pae) { 8671 pae.result = extras; 8672 pae.haveResult = true; 8673 pae.notifyAll(); 8674 } 8675 } 8676 8677 public void registerProcessObserver(IProcessObserver observer) { 8678 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8679 "registerProcessObserver()"); 8680 synchronized (this) { 8681 mProcessObservers.register(observer); 8682 } 8683 } 8684 8685 @Override 8686 public void unregisterProcessObserver(IProcessObserver observer) { 8687 synchronized (this) { 8688 mProcessObservers.unregister(observer); 8689 } 8690 } 8691 8692 @Override 8693 public boolean convertFromTranslucent(IBinder token) { 8694 final long origId = Binder.clearCallingIdentity(); 8695 try { 8696 synchronized (this) { 8697 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8698 if (r == null) { 8699 return false; 8700 } 8701 if (r.changeWindowTranslucency(true)) { 8702 mWindowManager.setAppFullscreen(token, true); 8703 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8704 return true; 8705 } 8706 return false; 8707 } 8708 } finally { 8709 Binder.restoreCallingIdentity(origId); 8710 } 8711 } 8712 8713 @Override 8714 public boolean convertToTranslucent(IBinder token) { 8715 final long origId = Binder.clearCallingIdentity(); 8716 try { 8717 synchronized (this) { 8718 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8719 if (r == null) { 8720 return false; 8721 } 8722 if (r.changeWindowTranslucency(false)) { 8723 r.task.stack.convertToTranslucent(r); 8724 mWindowManager.setAppFullscreen(token, false); 8725 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8726 return true; 8727 } 8728 return false; 8729 } 8730 } finally { 8731 Binder.restoreCallingIdentity(origId); 8732 } 8733 } 8734 8735 @Override 8736 public void setImmersive(IBinder token, boolean immersive) { 8737 synchronized(this) { 8738 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8739 if (r == null) { 8740 throw new IllegalArgumentException(); 8741 } 8742 r.immersive = immersive; 8743 8744 // update associated state if we're frontmost 8745 if (r == mFocusedActivity) { 8746 if (DEBUG_IMMERSIVE) { 8747 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8748 } 8749 applyUpdateLockStateLocked(r); 8750 } 8751 } 8752 } 8753 8754 @Override 8755 public boolean isImmersive(IBinder token) { 8756 synchronized (this) { 8757 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8758 if (r == null) { 8759 throw new IllegalArgumentException(); 8760 } 8761 return r.immersive; 8762 } 8763 } 8764 8765 public boolean isTopActivityImmersive() { 8766 enforceNotIsolatedCaller("startActivity"); 8767 synchronized (this) { 8768 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8769 return (r != null) ? r.immersive : false; 8770 } 8771 } 8772 8773 public final void enterSafeMode() { 8774 synchronized(this) { 8775 // It only makes sense to do this before the system is ready 8776 // and started launching other packages. 8777 if (!mSystemReady) { 8778 try { 8779 AppGlobals.getPackageManager().enterSafeMode(); 8780 } catch (RemoteException e) { 8781 } 8782 } 8783 } 8784 } 8785 8786 public final void showSafeModeOverlay() { 8787 View v = LayoutInflater.from(mContext).inflate( 8788 com.android.internal.R.layout.safe_mode, null); 8789 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8790 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8791 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8792 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8793 lp.gravity = Gravity.BOTTOM | Gravity.START; 8794 lp.format = v.getBackground().getOpacity(); 8795 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8796 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8797 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8798 ((WindowManager)mContext.getSystemService( 8799 Context.WINDOW_SERVICE)).addView(v, lp); 8800 } 8801 8802 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 8803 if (!(sender instanceof PendingIntentRecord)) { 8804 return; 8805 } 8806 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8807 synchronized (stats) { 8808 if (mBatteryStatsService.isOnBattery()) { 8809 mBatteryStatsService.enforceCallingPermission(); 8810 PendingIntentRecord rec = (PendingIntentRecord)sender; 8811 int MY_UID = Binder.getCallingUid(); 8812 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8813 BatteryStatsImpl.Uid.Pkg pkg = 8814 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 8815 sourcePkg != null ? sourcePkg : rec.key.packageName); 8816 pkg.incWakeupsLocked(); 8817 } 8818 } 8819 } 8820 8821 public boolean killPids(int[] pids, String pReason, boolean secure) { 8822 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8823 throw new SecurityException("killPids only available to the system"); 8824 } 8825 String reason = (pReason == null) ? "Unknown" : pReason; 8826 // XXX Note: don't acquire main activity lock here, because the window 8827 // manager calls in with its locks held. 8828 8829 boolean killed = false; 8830 synchronized (mPidsSelfLocked) { 8831 int[] types = new int[pids.length]; 8832 int worstType = 0; 8833 for (int i=0; i<pids.length; i++) { 8834 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8835 if (proc != null) { 8836 int type = proc.setAdj; 8837 types[i] = type; 8838 if (type > worstType) { 8839 worstType = type; 8840 } 8841 } 8842 } 8843 8844 // If the worst oom_adj is somewhere in the cached proc LRU range, 8845 // then constrain it so we will kill all cached procs. 8846 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8847 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8848 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8849 } 8850 8851 // If this is not a secure call, don't let it kill processes that 8852 // are important. 8853 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8854 worstType = ProcessList.SERVICE_ADJ; 8855 } 8856 8857 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8858 for (int i=0; i<pids.length; i++) { 8859 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8860 if (proc == null) { 8861 continue; 8862 } 8863 int adj = proc.setAdj; 8864 if (adj >= worstType && !proc.killedByAm) { 8865 killUnneededProcessLocked(proc, reason); 8866 killed = true; 8867 } 8868 } 8869 } 8870 return killed; 8871 } 8872 8873 @Override 8874 public void killUid(int uid, String reason) { 8875 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8876 throw new SecurityException("killUid only available to the system"); 8877 } 8878 synchronized (this) { 8879 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 8880 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 8881 reason != null ? reason : "kill uid"); 8882 } 8883 } 8884 8885 @Override 8886 public boolean killProcessesBelowForeground(String reason) { 8887 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8888 throw new SecurityException("killProcessesBelowForeground() only available to system"); 8889 } 8890 8891 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 8892 } 8893 8894 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 8895 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8896 throw new SecurityException("killProcessesBelowAdj() only available to system"); 8897 } 8898 8899 boolean killed = false; 8900 synchronized (mPidsSelfLocked) { 8901 final int size = mPidsSelfLocked.size(); 8902 for (int i = 0; i < size; i++) { 8903 final int pid = mPidsSelfLocked.keyAt(i); 8904 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8905 if (proc == null) continue; 8906 8907 final int adj = proc.setAdj; 8908 if (adj > belowAdj && !proc.killedByAm) { 8909 killUnneededProcessLocked(proc, reason); 8910 killed = true; 8911 } 8912 } 8913 } 8914 return killed; 8915 } 8916 8917 @Override 8918 public void hang(final IBinder who, boolean allowRestart) { 8919 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8920 != PackageManager.PERMISSION_GRANTED) { 8921 throw new SecurityException("Requires permission " 8922 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8923 } 8924 8925 final IBinder.DeathRecipient death = new DeathRecipient() { 8926 @Override 8927 public void binderDied() { 8928 synchronized (this) { 8929 notifyAll(); 8930 } 8931 } 8932 }; 8933 8934 try { 8935 who.linkToDeath(death, 0); 8936 } catch (RemoteException e) { 8937 Slog.w(TAG, "hang: given caller IBinder is already dead."); 8938 return; 8939 } 8940 8941 synchronized (this) { 8942 Watchdog.getInstance().setAllowRestart(allowRestart); 8943 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 8944 synchronized (death) { 8945 while (who.isBinderAlive()) { 8946 try { 8947 death.wait(); 8948 } catch (InterruptedException e) { 8949 } 8950 } 8951 } 8952 Watchdog.getInstance().setAllowRestart(true); 8953 } 8954 } 8955 8956 @Override 8957 public void restart() { 8958 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8959 != PackageManager.PERMISSION_GRANTED) { 8960 throw new SecurityException("Requires permission " 8961 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8962 } 8963 8964 Log.i(TAG, "Sending shutdown broadcast..."); 8965 8966 BroadcastReceiver br = new BroadcastReceiver() { 8967 @Override public void onReceive(Context context, Intent intent) { 8968 // Now the broadcast is done, finish up the low-level shutdown. 8969 Log.i(TAG, "Shutting down activity manager..."); 8970 shutdown(10000); 8971 Log.i(TAG, "Shutdown complete, restarting!"); 8972 Process.killProcess(Process.myPid()); 8973 System.exit(10); 8974 } 8975 }; 8976 8977 // First send the high-level shut down broadcast. 8978 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 8979 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 8980 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 8981 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 8982 mContext.sendOrderedBroadcastAsUser(intent, 8983 UserHandle.ALL, null, br, mHandler, 0, null, null); 8984 */ 8985 br.onReceive(mContext, intent); 8986 } 8987 8988 private long getLowRamTimeSinceIdle(long now) { 8989 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 8990 } 8991 8992 @Override 8993 public void performIdleMaintenance() { 8994 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8995 != PackageManager.PERMISSION_GRANTED) { 8996 throw new SecurityException("Requires permission " 8997 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8998 } 8999 9000 synchronized (this) { 9001 final long now = SystemClock.uptimeMillis(); 9002 final long timeSinceLastIdle = now - mLastIdleTime; 9003 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9004 mLastIdleTime = now; 9005 mLowRamTimeSinceLastIdle = 0; 9006 if (mLowRamStartTime != 0) { 9007 mLowRamStartTime = now; 9008 } 9009 9010 StringBuilder sb = new StringBuilder(128); 9011 sb.append("Idle maintenance over "); 9012 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9013 sb.append(" low RAM for "); 9014 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9015 Slog.i(TAG, sb.toString()); 9016 9017 // If at least 1/3 of our time since the last idle period has been spent 9018 // with RAM low, then we want to kill processes. 9019 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9020 9021 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9022 ProcessRecord proc = mLruProcesses.get(i); 9023 if (proc.notCachedSinceIdle) { 9024 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9025 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9026 if (doKilling && proc.initialIdlePss != 0 9027 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9028 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9029 + " from " + proc.initialIdlePss + ")"); 9030 } 9031 } 9032 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9033 proc.notCachedSinceIdle = true; 9034 proc.initialIdlePss = 0; 9035 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9036 mSleeping, now); 9037 } 9038 } 9039 9040 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9041 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9042 } 9043 } 9044 9045 public final void startRunning(String pkg, String cls, String action, 9046 String data) { 9047 synchronized(this) { 9048 if (mStartRunning) { 9049 return; 9050 } 9051 mStartRunning = true; 9052 mTopComponent = pkg != null && cls != null 9053 ? new ComponentName(pkg, cls) : null; 9054 mTopAction = action != null ? action : Intent.ACTION_MAIN; 9055 mTopData = data; 9056 if (!mSystemReady) { 9057 return; 9058 } 9059 } 9060 9061 systemReady(null); 9062 } 9063 9064 private void retrieveSettings() { 9065 final ContentResolver resolver = mContext.getContentResolver(); 9066 String debugApp = Settings.Global.getString( 9067 resolver, Settings.Global.DEBUG_APP); 9068 boolean waitForDebugger = Settings.Global.getInt( 9069 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9070 boolean alwaysFinishActivities = Settings.Global.getInt( 9071 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9072 boolean forceRtl = Settings.Global.getInt( 9073 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9074 // Transfer any global setting for forcing RTL layout, into a System Property 9075 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9076 9077 Configuration configuration = new Configuration(); 9078 Settings.System.getConfiguration(resolver, configuration); 9079 if (forceRtl) { 9080 // This will take care of setting the correct layout direction flags 9081 configuration.setLayoutDirection(configuration.locale); 9082 } 9083 9084 synchronized (this) { 9085 mDebugApp = mOrigDebugApp = debugApp; 9086 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9087 mAlwaysFinishActivities = alwaysFinishActivities; 9088 // This happens before any activities are started, so we can 9089 // change mConfiguration in-place. 9090 updateConfigurationLocked(configuration, null, false, true); 9091 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9092 } 9093 } 9094 9095 public boolean testIsSystemReady() { 9096 // no need to synchronize(this) just to read & return the value 9097 return mSystemReady; 9098 } 9099 9100 private static File getCalledPreBootReceiversFile() { 9101 File dataDir = Environment.getDataDirectory(); 9102 File systemDir = new File(dataDir, "system"); 9103 File fname = new File(systemDir, "called_pre_boots.dat"); 9104 return fname; 9105 } 9106 9107 static final int LAST_DONE_VERSION = 10000; 9108 9109 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9110 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9111 File file = getCalledPreBootReceiversFile(); 9112 FileInputStream fis = null; 9113 try { 9114 fis = new FileInputStream(file); 9115 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9116 int fvers = dis.readInt(); 9117 if (fvers == LAST_DONE_VERSION) { 9118 String vers = dis.readUTF(); 9119 String codename = dis.readUTF(); 9120 String build = dis.readUTF(); 9121 if (android.os.Build.VERSION.RELEASE.equals(vers) 9122 && android.os.Build.VERSION.CODENAME.equals(codename) 9123 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9124 int num = dis.readInt(); 9125 while (num > 0) { 9126 num--; 9127 String pkg = dis.readUTF(); 9128 String cls = dis.readUTF(); 9129 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9130 } 9131 } 9132 } 9133 } catch (FileNotFoundException e) { 9134 } catch (IOException e) { 9135 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9136 } finally { 9137 if (fis != null) { 9138 try { 9139 fis.close(); 9140 } catch (IOException e) { 9141 } 9142 } 9143 } 9144 return lastDoneReceivers; 9145 } 9146 9147 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9148 File file = getCalledPreBootReceiversFile(); 9149 FileOutputStream fos = null; 9150 DataOutputStream dos = null; 9151 try { 9152 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9153 fos = new FileOutputStream(file); 9154 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9155 dos.writeInt(LAST_DONE_VERSION); 9156 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9157 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9158 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9159 dos.writeInt(list.size()); 9160 for (int i=0; i<list.size(); i++) { 9161 dos.writeUTF(list.get(i).getPackageName()); 9162 dos.writeUTF(list.get(i).getClassName()); 9163 } 9164 } catch (IOException e) { 9165 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9166 file.delete(); 9167 } finally { 9168 FileUtils.sync(fos); 9169 if (dos != null) { 9170 try { 9171 dos.close(); 9172 } catch (IOException e) { 9173 // TODO Auto-generated catch block 9174 e.printStackTrace(); 9175 } 9176 } 9177 } 9178 } 9179 9180 public void systemReady(final Runnable goingCallback) { 9181 synchronized(this) { 9182 if (mSystemReady) { 9183 if (goingCallback != null) goingCallback.run(); 9184 return; 9185 } 9186 9187 // Check to see if there are any update receivers to run. 9188 if (!mDidUpdate) { 9189 if (mWaitingUpdate) { 9190 return; 9191 } 9192 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9193 List<ResolveInfo> ris = null; 9194 try { 9195 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9196 intent, null, 0, 0); 9197 } catch (RemoteException e) { 9198 } 9199 if (ris != null) { 9200 for (int i=ris.size()-1; i>=0; i--) { 9201 if ((ris.get(i).activityInfo.applicationInfo.flags 9202 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9203 ris.remove(i); 9204 } 9205 } 9206 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9207 9208 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9209 9210 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9211 for (int i=0; i<ris.size(); i++) { 9212 ActivityInfo ai = ris.get(i).activityInfo; 9213 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9214 if (lastDoneReceivers.contains(comp)) { 9215 ris.remove(i); 9216 i--; 9217 } 9218 } 9219 9220 final int[] users = getUsersLocked(); 9221 for (int i=0; i<ris.size(); i++) { 9222 ActivityInfo ai = ris.get(i).activityInfo; 9223 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9224 doneReceivers.add(comp); 9225 intent.setComponent(comp); 9226 for (int j=0; j<users.length; j++) { 9227 IIntentReceiver finisher = null; 9228 if (i == ris.size()-1 && j == users.length-1) { 9229 finisher = new IIntentReceiver.Stub() { 9230 public void performReceive(Intent intent, int resultCode, 9231 String data, Bundle extras, boolean ordered, 9232 boolean sticky, int sendingUser) { 9233 // The raw IIntentReceiver interface is called 9234 // with the AM lock held, so redispatch to 9235 // execute our code without the lock. 9236 mHandler.post(new Runnable() { 9237 public void run() { 9238 synchronized (ActivityManagerService.this) { 9239 mDidUpdate = true; 9240 } 9241 writeLastDonePreBootReceivers(doneReceivers); 9242 showBootMessage(mContext.getText( 9243 R.string.android_upgrading_complete), 9244 false); 9245 systemReady(goingCallback); 9246 } 9247 }); 9248 } 9249 }; 9250 } 9251 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9252 + " for user " + users[j]); 9253 broadcastIntentLocked(null, null, intent, null, finisher, 9254 0, null, null, null, AppOpsManager.OP_NONE, 9255 true, false, MY_PID, Process.SYSTEM_UID, 9256 users[j]); 9257 if (finisher != null) { 9258 mWaitingUpdate = true; 9259 } 9260 } 9261 } 9262 } 9263 if (mWaitingUpdate) { 9264 return; 9265 } 9266 mDidUpdate = true; 9267 } 9268 9269 mAppOpsService.systemReady(); 9270 mSystemReady = true; 9271 if (!mStartRunning) { 9272 return; 9273 } 9274 } 9275 9276 ArrayList<ProcessRecord> procsToKill = null; 9277 synchronized(mPidsSelfLocked) { 9278 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9279 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9280 if (!isAllowedWhileBooting(proc.info)){ 9281 if (procsToKill == null) { 9282 procsToKill = new ArrayList<ProcessRecord>(); 9283 } 9284 procsToKill.add(proc); 9285 } 9286 } 9287 } 9288 9289 synchronized(this) { 9290 if (procsToKill != null) { 9291 for (int i=procsToKill.size()-1; i>=0; i--) { 9292 ProcessRecord proc = procsToKill.get(i); 9293 Slog.i(TAG, "Removing system update proc: " + proc); 9294 removeProcessLocked(proc, true, false, "system update done"); 9295 } 9296 } 9297 9298 // Now that we have cleaned up any update processes, we 9299 // are ready to start launching real processes and know that 9300 // we won't trample on them any more. 9301 mProcessesReady = true; 9302 } 9303 9304 Slog.i(TAG, "System now ready"); 9305 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9306 SystemClock.uptimeMillis()); 9307 9308 synchronized(this) { 9309 // Make sure we have no pre-ready processes sitting around. 9310 9311 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9312 ResolveInfo ri = mContext.getPackageManager() 9313 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9314 STOCK_PM_FLAGS); 9315 CharSequence errorMsg = null; 9316 if (ri != null) { 9317 ActivityInfo ai = ri.activityInfo; 9318 ApplicationInfo app = ai.applicationInfo; 9319 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9320 mTopAction = Intent.ACTION_FACTORY_TEST; 9321 mTopData = null; 9322 mTopComponent = new ComponentName(app.packageName, 9323 ai.name); 9324 } else { 9325 errorMsg = mContext.getResources().getText( 9326 com.android.internal.R.string.factorytest_not_system); 9327 } 9328 } else { 9329 errorMsg = mContext.getResources().getText( 9330 com.android.internal.R.string.factorytest_no_action); 9331 } 9332 if (errorMsg != null) { 9333 mTopAction = null; 9334 mTopData = null; 9335 mTopComponent = null; 9336 Message msg = Message.obtain(); 9337 msg.what = SHOW_FACTORY_ERROR_MSG; 9338 msg.getData().putCharSequence("msg", errorMsg); 9339 mHandler.sendMessage(msg); 9340 } 9341 } 9342 } 9343 9344 retrieveSettings(); 9345 9346 synchronized (this) { 9347 readGrantedUriPermissionsLocked(); 9348 } 9349 9350 if (goingCallback != null) goingCallback.run(); 9351 9352 synchronized (this) { 9353 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9354 try { 9355 List apps = AppGlobals.getPackageManager(). 9356 getPersistentApplications(STOCK_PM_FLAGS); 9357 if (apps != null) { 9358 int N = apps.size(); 9359 int i; 9360 for (i=0; i<N; i++) { 9361 ApplicationInfo info 9362 = (ApplicationInfo)apps.get(i); 9363 if (info != null && 9364 !info.packageName.equals("android")) { 9365 addAppLocked(info, false); 9366 } 9367 } 9368 } 9369 } catch (RemoteException ex) { 9370 // pm is in same process, this will never happen. 9371 } 9372 } 9373 9374 // Start up initial activity. 9375 mBooting = true; 9376 9377 try { 9378 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9379 Message msg = Message.obtain(); 9380 msg.what = SHOW_UID_ERROR_MSG; 9381 mHandler.sendMessage(msg); 9382 } 9383 } catch (RemoteException e) { 9384 } 9385 9386 long ident = Binder.clearCallingIdentity(); 9387 try { 9388 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9389 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9390 | Intent.FLAG_RECEIVER_FOREGROUND); 9391 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9392 broadcastIntentLocked(null, null, intent, 9393 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9394 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9395 intent = new Intent(Intent.ACTION_USER_STARTING); 9396 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9397 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9398 broadcastIntentLocked(null, null, intent, 9399 null, new IIntentReceiver.Stub() { 9400 @Override 9401 public void performReceive(Intent intent, int resultCode, String data, 9402 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9403 throws RemoteException { 9404 } 9405 }, 0, null, null, 9406 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9407 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9408 } finally { 9409 Binder.restoreCallingIdentity(ident); 9410 } 9411 mStackSupervisor.resumeTopActivitiesLocked(); 9412 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9413 } 9414 } 9415 9416 private boolean makeAppCrashingLocked(ProcessRecord app, 9417 String shortMsg, String longMsg, String stackTrace) { 9418 app.crashing = true; 9419 app.crashingReport = generateProcessError(app, 9420 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9421 startAppProblemLocked(app); 9422 app.stopFreezingAllLocked(); 9423 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9424 } 9425 9426 private void makeAppNotRespondingLocked(ProcessRecord app, 9427 String activity, String shortMsg, String longMsg) { 9428 app.notResponding = true; 9429 app.notRespondingReport = generateProcessError(app, 9430 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9431 activity, shortMsg, longMsg, null); 9432 startAppProblemLocked(app); 9433 app.stopFreezingAllLocked(); 9434 } 9435 9436 /** 9437 * Generate a process error record, suitable for attachment to a ProcessRecord. 9438 * 9439 * @param app The ProcessRecord in which the error occurred. 9440 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9441 * ActivityManager.AppErrorStateInfo 9442 * @param activity The activity associated with the crash, if known. 9443 * @param shortMsg Short message describing the crash. 9444 * @param longMsg Long message describing the crash. 9445 * @param stackTrace Full crash stack trace, may be null. 9446 * 9447 * @return Returns a fully-formed AppErrorStateInfo record. 9448 */ 9449 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9450 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9451 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9452 9453 report.condition = condition; 9454 report.processName = app.processName; 9455 report.pid = app.pid; 9456 report.uid = app.info.uid; 9457 report.tag = activity; 9458 report.shortMsg = shortMsg; 9459 report.longMsg = longMsg; 9460 report.stackTrace = stackTrace; 9461 9462 return report; 9463 } 9464 9465 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9466 synchronized (this) { 9467 app.crashing = false; 9468 app.crashingReport = null; 9469 app.notResponding = false; 9470 app.notRespondingReport = null; 9471 if (app.anrDialog == fromDialog) { 9472 app.anrDialog = null; 9473 } 9474 if (app.waitDialog == fromDialog) { 9475 app.waitDialog = null; 9476 } 9477 if (app.pid > 0 && app.pid != MY_PID) { 9478 handleAppCrashLocked(app, null, null, null); 9479 killUnneededProcessLocked(app, "user request after error"); 9480 } 9481 } 9482 } 9483 9484 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9485 String stackTrace) { 9486 long now = SystemClock.uptimeMillis(); 9487 9488 Long crashTime; 9489 if (!app.isolated) { 9490 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9491 } else { 9492 crashTime = null; 9493 } 9494 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9495 // This process loses! 9496 Slog.w(TAG, "Process " + app.info.processName 9497 + " has crashed too many times: killing!"); 9498 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9499 app.userId, app.info.processName, app.uid); 9500 mStackSupervisor.handleAppCrashLocked(app); 9501 if (!app.persistent) { 9502 // We don't want to start this process again until the user 9503 // explicitly does so... but for persistent process, we really 9504 // need to keep it running. If a persistent process is actually 9505 // repeatedly crashing, then badness for everyone. 9506 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9507 app.info.processName); 9508 if (!app.isolated) { 9509 // XXX We don't have a way to mark isolated processes 9510 // as bad, since they don't have a peristent identity. 9511 mBadProcesses.put(app.info.processName, app.uid, 9512 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9513 mProcessCrashTimes.remove(app.info.processName, app.uid); 9514 } 9515 app.bad = true; 9516 app.removed = true; 9517 // Don't let services in this process be restarted and potentially 9518 // annoy the user repeatedly. Unless it is persistent, since those 9519 // processes run critical code. 9520 removeProcessLocked(app, false, false, "crash"); 9521 mStackSupervisor.resumeTopActivitiesLocked(); 9522 return false; 9523 } 9524 mStackSupervisor.resumeTopActivitiesLocked(); 9525 } else { 9526 mStackSupervisor.finishTopRunningActivityLocked(app); 9527 } 9528 9529 // Bump up the crash count of any services currently running in the proc. 9530 for (int i=app.services.size()-1; i>=0; i--) { 9531 // Any services running in the application need to be placed 9532 // back in the pending list. 9533 ServiceRecord sr = app.services.valueAt(i); 9534 sr.crashCount++; 9535 } 9536 9537 // If the crashing process is what we consider to be the "home process" and it has been 9538 // replaced by a third-party app, clear the package preferred activities from packages 9539 // with a home activity running in the process to prevent a repeatedly crashing app 9540 // from blocking the user to manually clear the list. 9541 final ArrayList<ActivityRecord> activities = app.activities; 9542 if (app == mHomeProcess && activities.size() > 0 9543 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9544 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9545 final ActivityRecord r = activities.get(activityNdx); 9546 if (r.isHomeActivity()) { 9547 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9548 try { 9549 ActivityThread.getPackageManager() 9550 .clearPackagePreferredActivities(r.packageName); 9551 } catch (RemoteException c) { 9552 // pm is in same process, this will never happen. 9553 } 9554 } 9555 } 9556 } 9557 9558 if (!app.isolated) { 9559 // XXX Can't keep track of crash times for isolated processes, 9560 // because they don't have a perisistent identity. 9561 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9562 } 9563 9564 return true; 9565 } 9566 9567 void startAppProblemLocked(ProcessRecord app) { 9568 if (app.userId == mCurrentUserId) { 9569 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9570 mContext, app.info.packageName, app.info.flags); 9571 } else { 9572 // If this app is not running under the current user, then we 9573 // can't give it a report button because that would require 9574 // launching the report UI under a different user. 9575 app.errorReportReceiver = null; 9576 } 9577 skipCurrentReceiverLocked(app); 9578 } 9579 9580 void skipCurrentReceiverLocked(ProcessRecord app) { 9581 for (BroadcastQueue queue : mBroadcastQueues) { 9582 queue.skipCurrentReceiverLocked(app); 9583 } 9584 } 9585 9586 /** 9587 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9588 * The application process will exit immediately after this call returns. 9589 * @param app object of the crashing app, null for the system server 9590 * @param crashInfo describing the exception 9591 */ 9592 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9593 ProcessRecord r = findAppProcess(app, "Crash"); 9594 final String processName = app == null ? "system_server" 9595 : (r == null ? "unknown" : r.processName); 9596 9597 handleApplicationCrashInner("crash", r, processName, crashInfo); 9598 } 9599 9600 /* Native crash reporting uses this inner version because it needs to be somewhat 9601 * decoupled from the AM-managed cleanup lifecycle 9602 */ 9603 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9604 ApplicationErrorReport.CrashInfo crashInfo) { 9605 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9606 UserHandle.getUserId(Binder.getCallingUid()), processName, 9607 r == null ? -1 : r.info.flags, 9608 crashInfo.exceptionClassName, 9609 crashInfo.exceptionMessage, 9610 crashInfo.throwFileName, 9611 crashInfo.throwLineNumber); 9612 9613 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9614 9615 crashApplication(r, crashInfo); 9616 } 9617 9618 public void handleApplicationStrictModeViolation( 9619 IBinder app, 9620 int violationMask, 9621 StrictMode.ViolationInfo info) { 9622 ProcessRecord r = findAppProcess(app, "StrictMode"); 9623 if (r == null) { 9624 return; 9625 } 9626 9627 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9628 Integer stackFingerprint = info.hashCode(); 9629 boolean logIt = true; 9630 synchronized (mAlreadyLoggedViolatedStacks) { 9631 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9632 logIt = false; 9633 // TODO: sub-sample into EventLog for these, with 9634 // the info.durationMillis? Then we'd get 9635 // the relative pain numbers, without logging all 9636 // the stack traces repeatedly. We'd want to do 9637 // likewise in the client code, which also does 9638 // dup suppression, before the Binder call. 9639 } else { 9640 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9641 mAlreadyLoggedViolatedStacks.clear(); 9642 } 9643 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9644 } 9645 } 9646 if (logIt) { 9647 logStrictModeViolationToDropBox(r, info); 9648 } 9649 } 9650 9651 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9652 AppErrorResult result = new AppErrorResult(); 9653 synchronized (this) { 9654 final long origId = Binder.clearCallingIdentity(); 9655 9656 Message msg = Message.obtain(); 9657 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9658 HashMap<String, Object> data = new HashMap<String, Object>(); 9659 data.put("result", result); 9660 data.put("app", r); 9661 data.put("violationMask", violationMask); 9662 data.put("info", info); 9663 msg.obj = data; 9664 mHandler.sendMessage(msg); 9665 9666 Binder.restoreCallingIdentity(origId); 9667 } 9668 int res = result.get(); 9669 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9670 } 9671 } 9672 9673 // Depending on the policy in effect, there could be a bunch of 9674 // these in quick succession so we try to batch these together to 9675 // minimize disk writes, number of dropbox entries, and maximize 9676 // compression, by having more fewer, larger records. 9677 private void logStrictModeViolationToDropBox( 9678 ProcessRecord process, 9679 StrictMode.ViolationInfo info) { 9680 if (info == null) { 9681 return; 9682 } 9683 final boolean isSystemApp = process == null || 9684 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9685 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9686 final String processName = process == null ? "unknown" : process.processName; 9687 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9688 final DropBoxManager dbox = (DropBoxManager) 9689 mContext.getSystemService(Context.DROPBOX_SERVICE); 9690 9691 // Exit early if the dropbox isn't configured to accept this report type. 9692 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9693 9694 boolean bufferWasEmpty; 9695 boolean needsFlush; 9696 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9697 synchronized (sb) { 9698 bufferWasEmpty = sb.length() == 0; 9699 appendDropBoxProcessHeaders(process, processName, sb); 9700 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9701 sb.append("System-App: ").append(isSystemApp).append("\n"); 9702 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9703 if (info.violationNumThisLoop != 0) { 9704 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9705 } 9706 if (info.numAnimationsRunning != 0) { 9707 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9708 } 9709 if (info.broadcastIntentAction != null) { 9710 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9711 } 9712 if (info.durationMillis != -1) { 9713 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9714 } 9715 if (info.numInstances != -1) { 9716 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9717 } 9718 if (info.tags != null) { 9719 for (String tag : info.tags) { 9720 sb.append("Span-Tag: ").append(tag).append("\n"); 9721 } 9722 } 9723 sb.append("\n"); 9724 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9725 sb.append(info.crashInfo.stackTrace); 9726 } 9727 sb.append("\n"); 9728 9729 // Only buffer up to ~64k. Various logging bits truncate 9730 // things at 128k. 9731 needsFlush = (sb.length() > 64 * 1024); 9732 } 9733 9734 // Flush immediately if the buffer's grown too large, or this 9735 // is a non-system app. Non-system apps are isolated with a 9736 // different tag & policy and not batched. 9737 // 9738 // Batching is useful during internal testing with 9739 // StrictMode settings turned up high. Without batching, 9740 // thousands of separate files could be created on boot. 9741 if (!isSystemApp || needsFlush) { 9742 new Thread("Error dump: " + dropboxTag) { 9743 @Override 9744 public void run() { 9745 String report; 9746 synchronized (sb) { 9747 report = sb.toString(); 9748 sb.delete(0, sb.length()); 9749 sb.trimToSize(); 9750 } 9751 if (report.length() != 0) { 9752 dbox.addText(dropboxTag, report); 9753 } 9754 } 9755 }.start(); 9756 return; 9757 } 9758 9759 // System app batching: 9760 if (!bufferWasEmpty) { 9761 // An existing dropbox-writing thread is outstanding, so 9762 // we don't need to start it up. The existing thread will 9763 // catch the buffer appends we just did. 9764 return; 9765 } 9766 9767 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9768 // (After this point, we shouldn't access AMS internal data structures.) 9769 new Thread("Error dump: " + dropboxTag) { 9770 @Override 9771 public void run() { 9772 // 5 second sleep to let stacks arrive and be batched together 9773 try { 9774 Thread.sleep(5000); // 5 seconds 9775 } catch (InterruptedException e) {} 9776 9777 String errorReport; 9778 synchronized (mStrictModeBuffer) { 9779 errorReport = mStrictModeBuffer.toString(); 9780 if (errorReport.length() == 0) { 9781 return; 9782 } 9783 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9784 mStrictModeBuffer.trimToSize(); 9785 } 9786 dbox.addText(dropboxTag, errorReport); 9787 } 9788 }.start(); 9789 } 9790 9791 /** 9792 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9793 * @param app object of the crashing app, null for the system server 9794 * @param tag reported by the caller 9795 * @param crashInfo describing the context of the error 9796 * @return true if the process should exit immediately (WTF is fatal) 9797 */ 9798 public boolean handleApplicationWtf(IBinder app, String tag, 9799 ApplicationErrorReport.CrashInfo crashInfo) { 9800 ProcessRecord r = findAppProcess(app, "WTF"); 9801 final String processName = app == null ? "system_server" 9802 : (r == null ? "unknown" : r.processName); 9803 9804 EventLog.writeEvent(EventLogTags.AM_WTF, 9805 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9806 processName, 9807 r == null ? -1 : r.info.flags, 9808 tag, crashInfo.exceptionMessage); 9809 9810 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9811 9812 if (r != null && r.pid != Process.myPid() && 9813 Settings.Global.getInt(mContext.getContentResolver(), 9814 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9815 crashApplication(r, crashInfo); 9816 return true; 9817 } else { 9818 return false; 9819 } 9820 } 9821 9822 /** 9823 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9824 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9825 */ 9826 private ProcessRecord findAppProcess(IBinder app, String reason) { 9827 if (app == null) { 9828 return null; 9829 } 9830 9831 synchronized (this) { 9832 final int NP = mProcessNames.getMap().size(); 9833 for (int ip=0; ip<NP; ip++) { 9834 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9835 final int NA = apps.size(); 9836 for (int ia=0; ia<NA; ia++) { 9837 ProcessRecord p = apps.valueAt(ia); 9838 if (p.thread != null && p.thread.asBinder() == app) { 9839 return p; 9840 } 9841 } 9842 } 9843 9844 Slog.w(TAG, "Can't find mystery application for " + reason 9845 + " from pid=" + Binder.getCallingPid() 9846 + " uid=" + Binder.getCallingUid() + ": " + app); 9847 return null; 9848 } 9849 } 9850 9851 /** 9852 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9853 * to append various headers to the dropbox log text. 9854 */ 9855 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9856 StringBuilder sb) { 9857 // Watchdog thread ends up invoking this function (with 9858 // a null ProcessRecord) to add the stack file to dropbox. 9859 // Do not acquire a lock on this (am) in such cases, as it 9860 // could cause a potential deadlock, if and when watchdog 9861 // is invoked due to unavailability of lock on am and it 9862 // would prevent watchdog from killing system_server. 9863 if (process == null) { 9864 sb.append("Process: ").append(processName).append("\n"); 9865 return; 9866 } 9867 // Note: ProcessRecord 'process' is guarded by the service 9868 // instance. (notably process.pkgList, which could otherwise change 9869 // concurrently during execution of this method) 9870 synchronized (this) { 9871 sb.append("Process: ").append(processName).append("\n"); 9872 int flags = process.info.flags; 9873 IPackageManager pm = AppGlobals.getPackageManager(); 9874 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 9875 for (int ip=0; ip<process.pkgList.size(); ip++) { 9876 String pkg = process.pkgList.keyAt(ip); 9877 sb.append("Package: ").append(pkg); 9878 try { 9879 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 9880 if (pi != null) { 9881 sb.append(" v").append(pi.versionCode); 9882 if (pi.versionName != null) { 9883 sb.append(" (").append(pi.versionName).append(")"); 9884 } 9885 } 9886 } catch (RemoteException e) { 9887 Slog.e(TAG, "Error getting package info: " + pkg, e); 9888 } 9889 sb.append("\n"); 9890 } 9891 } 9892 } 9893 9894 private static String processClass(ProcessRecord process) { 9895 if (process == null || process.pid == MY_PID) { 9896 return "system_server"; 9897 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9898 return "system_app"; 9899 } else { 9900 return "data_app"; 9901 } 9902 } 9903 9904 /** 9905 * Write a description of an error (crash, WTF, ANR) to the drop box. 9906 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 9907 * @param process which caused the error, null means the system server 9908 * @param activity which triggered the error, null if unknown 9909 * @param parent activity related to the error, null if unknown 9910 * @param subject line related to the error, null if absent 9911 * @param report in long form describing the error, null if absent 9912 * @param logFile to include in the report, null if none 9913 * @param crashInfo giving an application stack trace, null if absent 9914 */ 9915 public void addErrorToDropBox(String eventType, 9916 ProcessRecord process, String processName, ActivityRecord activity, 9917 ActivityRecord parent, String subject, 9918 final String report, final File logFile, 9919 final ApplicationErrorReport.CrashInfo crashInfo) { 9920 // NOTE -- this must never acquire the ActivityManagerService lock, 9921 // otherwise the watchdog may be prevented from resetting the system. 9922 9923 final String dropboxTag = processClass(process) + "_" + eventType; 9924 final DropBoxManager dbox = (DropBoxManager) 9925 mContext.getSystemService(Context.DROPBOX_SERVICE); 9926 9927 // Exit early if the dropbox isn't configured to accept this report type. 9928 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9929 9930 final StringBuilder sb = new StringBuilder(1024); 9931 appendDropBoxProcessHeaders(process, processName, sb); 9932 if (activity != null) { 9933 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 9934 } 9935 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 9936 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 9937 } 9938 if (parent != null && parent != activity) { 9939 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 9940 } 9941 if (subject != null) { 9942 sb.append("Subject: ").append(subject).append("\n"); 9943 } 9944 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9945 if (Debug.isDebuggerConnected()) { 9946 sb.append("Debugger: Connected\n"); 9947 } 9948 sb.append("\n"); 9949 9950 // Do the rest in a worker thread to avoid blocking the caller on I/O 9951 // (After this point, we shouldn't access AMS internal data structures.) 9952 Thread worker = new Thread("Error dump: " + dropboxTag) { 9953 @Override 9954 public void run() { 9955 if (report != null) { 9956 sb.append(report); 9957 } 9958 if (logFile != null) { 9959 try { 9960 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 9961 "\n\n[[TRUNCATED]]")); 9962 } catch (IOException e) { 9963 Slog.e(TAG, "Error reading " + logFile, e); 9964 } 9965 } 9966 if (crashInfo != null && crashInfo.stackTrace != null) { 9967 sb.append(crashInfo.stackTrace); 9968 } 9969 9970 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 9971 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 9972 if (lines > 0) { 9973 sb.append("\n"); 9974 9975 // Merge several logcat streams, and take the last N lines 9976 InputStreamReader input = null; 9977 try { 9978 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 9979 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 9980 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 9981 9982 try { logcat.getOutputStream().close(); } catch (IOException e) {} 9983 try { logcat.getErrorStream().close(); } catch (IOException e) {} 9984 input = new InputStreamReader(logcat.getInputStream()); 9985 9986 int num; 9987 char[] buf = new char[8192]; 9988 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 9989 } catch (IOException e) { 9990 Slog.e(TAG, "Error running logcat", e); 9991 } finally { 9992 if (input != null) try { input.close(); } catch (IOException e) {} 9993 } 9994 } 9995 9996 dbox.addText(dropboxTag, sb.toString()); 9997 } 9998 }; 9999 10000 if (process == null) { 10001 // If process is null, we are being called from some internal code 10002 // and may be about to die -- run this synchronously. 10003 worker.run(); 10004 } else { 10005 worker.start(); 10006 } 10007 } 10008 10009 /** 10010 * Bring up the "unexpected error" dialog box for a crashing app. 10011 * Deal with edge cases (intercepts from instrumented applications, 10012 * ActivityController, error intent receivers, that sort of thing). 10013 * @param r the application crashing 10014 * @param crashInfo describing the failure 10015 */ 10016 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10017 long timeMillis = System.currentTimeMillis(); 10018 String shortMsg = crashInfo.exceptionClassName; 10019 String longMsg = crashInfo.exceptionMessage; 10020 String stackTrace = crashInfo.stackTrace; 10021 if (shortMsg != null && longMsg != null) { 10022 longMsg = shortMsg + ": " + longMsg; 10023 } else if (shortMsg != null) { 10024 longMsg = shortMsg; 10025 } 10026 10027 AppErrorResult result = new AppErrorResult(); 10028 synchronized (this) { 10029 if (mController != null) { 10030 try { 10031 String name = r != null ? r.processName : null; 10032 int pid = r != null ? r.pid : Binder.getCallingPid(); 10033 if (!mController.appCrashed(name, pid, 10034 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10035 Slog.w(TAG, "Force-killing crashed app " + name 10036 + " at watcher's request"); 10037 Process.killProcess(pid); 10038 return; 10039 } 10040 } catch (RemoteException e) { 10041 mController = null; 10042 Watchdog.getInstance().setActivityController(null); 10043 } 10044 } 10045 10046 final long origId = Binder.clearCallingIdentity(); 10047 10048 // If this process is running instrumentation, finish it. 10049 if (r != null && r.instrumentationClass != null) { 10050 Slog.w(TAG, "Error in app " + r.processName 10051 + " running instrumentation " + r.instrumentationClass + ":"); 10052 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10053 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10054 Bundle info = new Bundle(); 10055 info.putString("shortMsg", shortMsg); 10056 info.putString("longMsg", longMsg); 10057 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10058 Binder.restoreCallingIdentity(origId); 10059 return; 10060 } 10061 10062 // If we can't identify the process or it's already exceeded its crash quota, 10063 // quit right away without showing a crash dialog. 10064 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10065 Binder.restoreCallingIdentity(origId); 10066 return; 10067 } 10068 10069 Message msg = Message.obtain(); 10070 msg.what = SHOW_ERROR_MSG; 10071 HashMap data = new HashMap(); 10072 data.put("result", result); 10073 data.put("app", r); 10074 msg.obj = data; 10075 mHandler.sendMessage(msg); 10076 10077 Binder.restoreCallingIdentity(origId); 10078 } 10079 10080 int res = result.get(); 10081 10082 Intent appErrorIntent = null; 10083 synchronized (this) { 10084 if (r != null && !r.isolated) { 10085 // XXX Can't keep track of crash time for isolated processes, 10086 // since they don't have a persistent identity. 10087 mProcessCrashTimes.put(r.info.processName, r.uid, 10088 SystemClock.uptimeMillis()); 10089 } 10090 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10091 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10092 } 10093 } 10094 10095 if (appErrorIntent != null) { 10096 try { 10097 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10098 } catch (ActivityNotFoundException e) { 10099 Slog.w(TAG, "bug report receiver dissappeared", e); 10100 } 10101 } 10102 } 10103 10104 Intent createAppErrorIntentLocked(ProcessRecord r, 10105 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10106 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10107 if (report == null) { 10108 return null; 10109 } 10110 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10111 result.setComponent(r.errorReportReceiver); 10112 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10113 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10114 return result; 10115 } 10116 10117 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10118 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10119 if (r.errorReportReceiver == null) { 10120 return null; 10121 } 10122 10123 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10124 return null; 10125 } 10126 10127 ApplicationErrorReport report = new ApplicationErrorReport(); 10128 report.packageName = r.info.packageName; 10129 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10130 report.processName = r.processName; 10131 report.time = timeMillis; 10132 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10133 10134 if (r.crashing || r.forceCrashReport) { 10135 report.type = ApplicationErrorReport.TYPE_CRASH; 10136 report.crashInfo = crashInfo; 10137 } else if (r.notResponding) { 10138 report.type = ApplicationErrorReport.TYPE_ANR; 10139 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10140 10141 report.anrInfo.activity = r.notRespondingReport.tag; 10142 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10143 report.anrInfo.info = r.notRespondingReport.longMsg; 10144 } 10145 10146 return report; 10147 } 10148 10149 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10150 enforceNotIsolatedCaller("getProcessesInErrorState"); 10151 // assume our apps are happy - lazy create the list 10152 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10153 10154 final boolean allUsers = ActivityManager.checkUidPermission( 10155 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10156 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10157 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10158 10159 synchronized (this) { 10160 10161 // iterate across all processes 10162 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10163 ProcessRecord app = mLruProcesses.get(i); 10164 if (!allUsers && app.userId != userId) { 10165 continue; 10166 } 10167 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10168 // This one's in trouble, so we'll generate a report for it 10169 // crashes are higher priority (in case there's a crash *and* an anr) 10170 ActivityManager.ProcessErrorStateInfo report = null; 10171 if (app.crashing) { 10172 report = app.crashingReport; 10173 } else if (app.notResponding) { 10174 report = app.notRespondingReport; 10175 } 10176 10177 if (report != null) { 10178 if (errList == null) { 10179 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10180 } 10181 errList.add(report); 10182 } else { 10183 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10184 " crashing = " + app.crashing + 10185 " notResponding = " + app.notResponding); 10186 } 10187 } 10188 } 10189 } 10190 10191 return errList; 10192 } 10193 10194 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10195 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10196 if (currApp != null) { 10197 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10198 } 10199 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10200 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10201 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10202 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10203 if (currApp != null) { 10204 currApp.lru = 0; 10205 } 10206 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10207 } else if (adj >= ProcessList.SERVICE_ADJ) { 10208 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10209 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10210 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10211 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10212 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10213 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10214 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10215 } else { 10216 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10217 } 10218 } 10219 10220 private void fillInProcMemInfo(ProcessRecord app, 10221 ActivityManager.RunningAppProcessInfo outInfo) { 10222 outInfo.pid = app.pid; 10223 outInfo.uid = app.info.uid; 10224 if (mHeavyWeightProcess == app) { 10225 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10226 } 10227 if (app.persistent) { 10228 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10229 } 10230 if (app.activities.size() > 0) { 10231 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10232 } 10233 outInfo.lastTrimLevel = app.trimMemoryLevel; 10234 int adj = app.curAdj; 10235 outInfo.importance = oomAdjToImportance(adj, outInfo); 10236 outInfo.importanceReasonCode = app.adjTypeCode; 10237 } 10238 10239 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10240 enforceNotIsolatedCaller("getRunningAppProcesses"); 10241 // Lazy instantiation of list 10242 List<ActivityManager.RunningAppProcessInfo> runList = null; 10243 final boolean allUsers = ActivityManager.checkUidPermission( 10244 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10245 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10246 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10247 synchronized (this) { 10248 // Iterate across all processes 10249 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10250 ProcessRecord app = mLruProcesses.get(i); 10251 if (!allUsers && app.userId != userId) { 10252 continue; 10253 } 10254 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10255 // Generate process state info for running application 10256 ActivityManager.RunningAppProcessInfo currApp = 10257 new ActivityManager.RunningAppProcessInfo(app.processName, 10258 app.pid, app.getPackageList()); 10259 fillInProcMemInfo(app, currApp); 10260 if (app.adjSource instanceof ProcessRecord) { 10261 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10262 currApp.importanceReasonImportance = oomAdjToImportance( 10263 app.adjSourceOom, null); 10264 } else if (app.adjSource instanceof ActivityRecord) { 10265 ActivityRecord r = (ActivityRecord)app.adjSource; 10266 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10267 } 10268 if (app.adjTarget instanceof ComponentName) { 10269 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10270 } 10271 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10272 // + " lru=" + currApp.lru); 10273 if (runList == null) { 10274 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10275 } 10276 runList.add(currApp); 10277 } 10278 } 10279 } 10280 return runList; 10281 } 10282 10283 public List<ApplicationInfo> getRunningExternalApplications() { 10284 enforceNotIsolatedCaller("getRunningExternalApplications"); 10285 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10286 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10287 if (runningApps != null && runningApps.size() > 0) { 10288 Set<String> extList = new HashSet<String>(); 10289 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10290 if (app.pkgList != null) { 10291 for (String pkg : app.pkgList) { 10292 extList.add(pkg); 10293 } 10294 } 10295 } 10296 IPackageManager pm = AppGlobals.getPackageManager(); 10297 for (String pkg : extList) { 10298 try { 10299 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10300 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10301 retList.add(info); 10302 } 10303 } catch (RemoteException e) { 10304 } 10305 } 10306 } 10307 return retList; 10308 } 10309 10310 @Override 10311 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10312 enforceNotIsolatedCaller("getMyMemoryState"); 10313 synchronized (this) { 10314 ProcessRecord proc; 10315 synchronized (mPidsSelfLocked) { 10316 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10317 } 10318 fillInProcMemInfo(proc, outInfo); 10319 } 10320 } 10321 10322 @Override 10323 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10324 if (checkCallingPermission(android.Manifest.permission.DUMP) 10325 != PackageManager.PERMISSION_GRANTED) { 10326 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10327 + Binder.getCallingPid() 10328 + ", uid=" + Binder.getCallingUid() 10329 + " without permission " 10330 + android.Manifest.permission.DUMP); 10331 return; 10332 } 10333 10334 boolean dumpAll = false; 10335 boolean dumpClient = false; 10336 String dumpPackage = null; 10337 10338 int opti = 0; 10339 while (opti < args.length) { 10340 String opt = args[opti]; 10341 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10342 break; 10343 } 10344 opti++; 10345 if ("-a".equals(opt)) { 10346 dumpAll = true; 10347 } else if ("-c".equals(opt)) { 10348 dumpClient = true; 10349 } else if ("-h".equals(opt)) { 10350 pw.println("Activity manager dump options:"); 10351 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10352 pw.println(" cmd may be one of:"); 10353 pw.println(" a[ctivities]: activity stack state"); 10354 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10355 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10356 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10357 pw.println(" o[om]: out of memory management"); 10358 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10359 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10360 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10361 pw.println(" service [COMP_SPEC]: service client-side state"); 10362 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10363 pw.println(" all: dump all activities"); 10364 pw.println(" top: dump the top activity"); 10365 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10366 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10367 pw.println(" a partial substring in a component name, a"); 10368 pw.println(" hex object identifier."); 10369 pw.println(" -a: include all available server state."); 10370 pw.println(" -c: include client state."); 10371 return; 10372 } else { 10373 pw.println("Unknown argument: " + opt + "; use -h for help"); 10374 } 10375 } 10376 10377 long origId = Binder.clearCallingIdentity(); 10378 boolean more = false; 10379 // Is the caller requesting to dump a particular piece of data? 10380 if (opti < args.length) { 10381 String cmd = args[opti]; 10382 opti++; 10383 if ("activities".equals(cmd) || "a".equals(cmd)) { 10384 synchronized (this) { 10385 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10386 } 10387 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10388 String[] newArgs; 10389 String name; 10390 if (opti >= args.length) { 10391 name = null; 10392 newArgs = EMPTY_STRING_ARRAY; 10393 } else { 10394 name = args[opti]; 10395 opti++; 10396 newArgs = new String[args.length - opti]; 10397 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10398 args.length - opti); 10399 } 10400 synchronized (this) { 10401 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10402 } 10403 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10404 String[] newArgs; 10405 String name; 10406 if (opti >= args.length) { 10407 name = null; 10408 newArgs = EMPTY_STRING_ARRAY; 10409 } else { 10410 name = args[opti]; 10411 opti++; 10412 newArgs = new String[args.length - opti]; 10413 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10414 args.length - opti); 10415 } 10416 synchronized (this) { 10417 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10418 } 10419 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10420 String[] newArgs; 10421 String name; 10422 if (opti >= args.length) { 10423 name = null; 10424 newArgs = EMPTY_STRING_ARRAY; 10425 } else { 10426 name = args[opti]; 10427 opti++; 10428 newArgs = new String[args.length - opti]; 10429 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10430 args.length - opti); 10431 } 10432 synchronized (this) { 10433 dumpProcessesLocked(fd, pw, args, opti, true, name); 10434 } 10435 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10436 synchronized (this) { 10437 dumpOomLocked(fd, pw, args, opti, true); 10438 } 10439 } else if ("provider".equals(cmd)) { 10440 String[] newArgs; 10441 String name; 10442 if (opti >= args.length) { 10443 name = null; 10444 newArgs = EMPTY_STRING_ARRAY; 10445 } else { 10446 name = args[opti]; 10447 opti++; 10448 newArgs = new String[args.length - opti]; 10449 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10450 } 10451 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10452 pw.println("No providers match: " + name); 10453 pw.println("Use -h for help."); 10454 } 10455 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10456 synchronized (this) { 10457 dumpProvidersLocked(fd, pw, args, opti, true, null); 10458 } 10459 } else if ("service".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 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10473 pw.println("No services match: " + name); 10474 pw.println("Use -h for help."); 10475 } 10476 } else if ("package".equals(cmd)) { 10477 String[] newArgs; 10478 if (opti >= args.length) { 10479 pw.println("package: no package name specified"); 10480 pw.println("Use -h for help."); 10481 } else { 10482 dumpPackage = args[opti]; 10483 opti++; 10484 newArgs = new String[args.length - opti]; 10485 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10486 args.length - opti); 10487 args = newArgs; 10488 opti = 0; 10489 more = true; 10490 } 10491 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10492 synchronized (this) { 10493 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10494 } 10495 } else { 10496 // Dumping a single activity? 10497 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10498 pw.println("Bad activity command, or no activities match: " + cmd); 10499 pw.println("Use -h for help."); 10500 } 10501 } 10502 if (!more) { 10503 Binder.restoreCallingIdentity(origId); 10504 return; 10505 } 10506 } 10507 10508 // No piece of data specified, dump everything. 10509 synchronized (this) { 10510 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10511 pw.println(); 10512 if (dumpAll) { 10513 pw.println("-------------------------------------------------------------------------------"); 10514 } 10515 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10516 pw.println(); 10517 if (dumpAll) { 10518 pw.println("-------------------------------------------------------------------------------"); 10519 } 10520 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10521 pw.println(); 10522 if (dumpAll) { 10523 pw.println("-------------------------------------------------------------------------------"); 10524 } 10525 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10526 pw.println(); 10527 if (dumpAll) { 10528 pw.println("-------------------------------------------------------------------------------"); 10529 } 10530 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10531 pw.println(); 10532 if (dumpAll) { 10533 pw.println("-------------------------------------------------------------------------------"); 10534 } 10535 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10536 } 10537 Binder.restoreCallingIdentity(origId); 10538 } 10539 10540 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10541 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10542 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10543 10544 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10545 dumpPackage); 10546 boolean needSep = printedAnything; 10547 10548 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10549 dumpPackage, needSep, " mFocusedActivity: "); 10550 if (printed) { 10551 printedAnything = true; 10552 needSep = false; 10553 } 10554 10555 if (dumpPackage == null) { 10556 if (needSep) { 10557 pw.println(); 10558 } 10559 needSep = true; 10560 printedAnything = true; 10561 mStackSupervisor.dump(pw, " "); 10562 } 10563 10564 if (mRecentTasks.size() > 0) { 10565 boolean printedHeader = false; 10566 10567 final int N = mRecentTasks.size(); 10568 for (int i=0; i<N; i++) { 10569 TaskRecord tr = mRecentTasks.get(i); 10570 if (dumpPackage != null) { 10571 if (tr.realActivity == null || 10572 !dumpPackage.equals(tr.realActivity)) { 10573 continue; 10574 } 10575 } 10576 if (!printedHeader) { 10577 if (needSep) { 10578 pw.println(); 10579 } 10580 pw.println(" Recent tasks:"); 10581 printedHeader = true; 10582 printedAnything = true; 10583 } 10584 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10585 pw.println(tr); 10586 if (dumpAll) { 10587 mRecentTasks.get(i).dump(pw, " "); 10588 } 10589 } 10590 } 10591 10592 if (!printedAnything) { 10593 pw.println(" (nothing)"); 10594 } 10595 } 10596 10597 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10598 int opti, boolean dumpAll, String dumpPackage) { 10599 boolean needSep = false; 10600 boolean printedAnything = false; 10601 int numPers = 0; 10602 10603 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10604 10605 if (dumpAll) { 10606 final int NP = mProcessNames.getMap().size(); 10607 for (int ip=0; ip<NP; ip++) { 10608 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10609 final int NA = procs.size(); 10610 for (int ia=0; ia<NA; ia++) { 10611 ProcessRecord r = procs.valueAt(ia); 10612 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10613 continue; 10614 } 10615 if (!needSep) { 10616 pw.println(" All known processes:"); 10617 needSep = true; 10618 printedAnything = true; 10619 } 10620 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10621 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10622 pw.print(" "); pw.println(r); 10623 r.dump(pw, " "); 10624 if (r.persistent) { 10625 numPers++; 10626 } 10627 } 10628 } 10629 } 10630 10631 if (mIsolatedProcesses.size() > 0) { 10632 boolean printed = false; 10633 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10634 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10635 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10636 continue; 10637 } 10638 if (!printed) { 10639 if (needSep) { 10640 pw.println(); 10641 } 10642 pw.println(" Isolated process list (sorted by uid):"); 10643 printedAnything = true; 10644 printed = true; 10645 needSep = true; 10646 } 10647 pw.println(String.format("%sIsolated #%2d: %s", 10648 " ", i, r.toString())); 10649 } 10650 } 10651 10652 if (mLruProcesses.size() > 0) { 10653 if (needSep) { 10654 pw.println(); 10655 } 10656 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10657 pw.print(" total, non-act at "); 10658 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10659 pw.print(", non-svc at "); 10660 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10661 pw.println("):"); 10662 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10663 needSep = true; 10664 printedAnything = true; 10665 } 10666 10667 if (dumpAll || dumpPackage != null) { 10668 synchronized (mPidsSelfLocked) { 10669 boolean printed = false; 10670 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10671 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10672 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10673 continue; 10674 } 10675 if (!printed) { 10676 if (needSep) pw.println(); 10677 needSep = true; 10678 pw.println(" PID mappings:"); 10679 printed = true; 10680 printedAnything = true; 10681 } 10682 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10683 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10684 } 10685 } 10686 } 10687 10688 if (mForegroundProcesses.size() > 0) { 10689 synchronized (mPidsSelfLocked) { 10690 boolean printed = false; 10691 for (int i=0; i<mForegroundProcesses.size(); i++) { 10692 ProcessRecord r = mPidsSelfLocked.get( 10693 mForegroundProcesses.valueAt(i).pid); 10694 if (dumpPackage != null && (r == null 10695 || !r.pkgList.containsKey(dumpPackage))) { 10696 continue; 10697 } 10698 if (!printed) { 10699 if (needSep) pw.println(); 10700 needSep = true; 10701 pw.println(" Foreground Processes:"); 10702 printed = true; 10703 printedAnything = true; 10704 } 10705 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10706 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10707 } 10708 } 10709 } 10710 10711 if (mPersistentStartingProcesses.size() > 0) { 10712 if (needSep) pw.println(); 10713 needSep = true; 10714 printedAnything = true; 10715 pw.println(" Persisent processes that are starting:"); 10716 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10717 "Starting Norm", "Restarting PERS", dumpPackage); 10718 } 10719 10720 if (mRemovedProcesses.size() > 0) { 10721 if (needSep) pw.println(); 10722 needSep = true; 10723 printedAnything = true; 10724 pw.println(" Processes that are being removed:"); 10725 dumpProcessList(pw, this, mRemovedProcesses, " ", 10726 "Removed Norm", "Removed PERS", dumpPackage); 10727 } 10728 10729 if (mProcessesOnHold.size() > 0) { 10730 if (needSep) pw.println(); 10731 needSep = true; 10732 printedAnything = true; 10733 pw.println(" Processes that are on old until the system is ready:"); 10734 dumpProcessList(pw, this, mProcessesOnHold, " ", 10735 "OnHold Norm", "OnHold PERS", dumpPackage); 10736 } 10737 10738 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10739 10740 if (mProcessCrashTimes.getMap().size() > 0) { 10741 boolean printed = false; 10742 long now = SystemClock.uptimeMillis(); 10743 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10744 final int NP = pmap.size(); 10745 for (int ip=0; ip<NP; ip++) { 10746 String pname = pmap.keyAt(ip); 10747 SparseArray<Long> uids = pmap.valueAt(ip); 10748 final int N = uids.size(); 10749 for (int i=0; i<N; i++) { 10750 int puid = uids.keyAt(i); 10751 ProcessRecord r = mProcessNames.get(pname, puid); 10752 if (dumpPackage != null && (r == null 10753 || !r.pkgList.containsKey(dumpPackage))) { 10754 continue; 10755 } 10756 if (!printed) { 10757 if (needSep) pw.println(); 10758 needSep = true; 10759 pw.println(" Time since processes crashed:"); 10760 printed = true; 10761 printedAnything = true; 10762 } 10763 pw.print(" Process "); pw.print(pname); 10764 pw.print(" uid "); pw.print(puid); 10765 pw.print(": last crashed "); 10766 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10767 pw.println(" ago"); 10768 } 10769 } 10770 } 10771 10772 if (mBadProcesses.getMap().size() > 0) { 10773 boolean printed = false; 10774 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10775 final int NP = pmap.size(); 10776 for (int ip=0; ip<NP; ip++) { 10777 String pname = pmap.keyAt(ip); 10778 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10779 final int N = uids.size(); 10780 for (int i=0; i<N; i++) { 10781 int puid = uids.keyAt(i); 10782 ProcessRecord r = mProcessNames.get(pname, puid); 10783 if (dumpPackage != null && (r == null 10784 || !r.pkgList.containsKey(dumpPackage))) { 10785 continue; 10786 } 10787 if (!printed) { 10788 if (needSep) pw.println(); 10789 needSep = true; 10790 pw.println(" Bad processes:"); 10791 printedAnything = true; 10792 } 10793 BadProcessInfo info = uids.valueAt(i); 10794 pw.print(" Bad process "); pw.print(pname); 10795 pw.print(" uid "); pw.print(puid); 10796 pw.print(": crashed at time "); pw.println(info.time); 10797 if (info.shortMsg != null) { 10798 pw.print(" Short msg: "); pw.println(info.shortMsg); 10799 } 10800 if (info.longMsg != null) { 10801 pw.print(" Long msg: "); pw.println(info.longMsg); 10802 } 10803 if (info.stack != null) { 10804 pw.println(" Stack:"); 10805 int lastPos = 0; 10806 for (int pos=0; pos<info.stack.length(); pos++) { 10807 if (info.stack.charAt(pos) == '\n') { 10808 pw.print(" "); 10809 pw.write(info.stack, lastPos, pos-lastPos); 10810 pw.println(); 10811 lastPos = pos+1; 10812 } 10813 } 10814 if (lastPos < info.stack.length()) { 10815 pw.print(" "); 10816 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10817 pw.println(); 10818 } 10819 } 10820 } 10821 } 10822 } 10823 10824 if (dumpPackage == null) { 10825 pw.println(); 10826 needSep = false; 10827 pw.println(" mStartedUsers:"); 10828 for (int i=0; i<mStartedUsers.size(); i++) { 10829 UserStartedState uss = mStartedUsers.valueAt(i); 10830 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10831 pw.print(": "); uss.dump("", pw); 10832 } 10833 pw.print(" mStartedUserArray: ["); 10834 for (int i=0; i<mStartedUserArray.length; i++) { 10835 if (i > 0) pw.print(", "); 10836 pw.print(mStartedUserArray[i]); 10837 } 10838 pw.println("]"); 10839 pw.print(" mUserLru: ["); 10840 for (int i=0; i<mUserLru.size(); i++) { 10841 if (i > 0) pw.print(", "); 10842 pw.print(mUserLru.get(i)); 10843 } 10844 pw.println("]"); 10845 if (dumpAll) { 10846 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10847 } 10848 } 10849 if (mHomeProcess != null && (dumpPackage == null 10850 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10851 if (needSep) { 10852 pw.println(); 10853 needSep = false; 10854 } 10855 pw.println(" mHomeProcess: " + mHomeProcess); 10856 } 10857 if (mPreviousProcess != null && (dumpPackage == null 10858 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 10859 if (needSep) { 10860 pw.println(); 10861 needSep = false; 10862 } 10863 pw.println(" mPreviousProcess: " + mPreviousProcess); 10864 } 10865 if (dumpAll) { 10866 StringBuilder sb = new StringBuilder(128); 10867 sb.append(" mPreviousProcessVisibleTime: "); 10868 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 10869 pw.println(sb); 10870 } 10871 if (mHeavyWeightProcess != null && (dumpPackage == null 10872 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 10873 if (needSep) { 10874 pw.println(); 10875 needSep = false; 10876 } 10877 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10878 } 10879 if (dumpPackage == null) { 10880 pw.println(" mConfiguration: " + mConfiguration); 10881 } 10882 if (dumpAll) { 10883 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 10884 if (mCompatModePackages.getPackages().size() > 0) { 10885 boolean printed = false; 10886 for (Map.Entry<String, Integer> entry 10887 : mCompatModePackages.getPackages().entrySet()) { 10888 String pkg = entry.getKey(); 10889 int mode = entry.getValue(); 10890 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 10891 continue; 10892 } 10893 if (!printed) { 10894 pw.println(" mScreenCompatPackages:"); 10895 printed = true; 10896 } 10897 pw.print(" "); pw.print(pkg); pw.print(": "); 10898 pw.print(mode); pw.println(); 10899 } 10900 } 10901 } 10902 if (dumpPackage == null) { 10903 if (mSleeping || mWentToSleep || mLockScreenShown) { 10904 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 10905 + " mLockScreenShown " + mLockScreenShown); 10906 } 10907 if (mShuttingDown) { 10908 pw.println(" mShuttingDown=" + mShuttingDown); 10909 } 10910 } 10911 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 10912 || mOrigWaitForDebugger) { 10913 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 10914 || dumpPackage.equals(mOrigDebugApp)) { 10915 if (needSep) { 10916 pw.println(); 10917 needSep = false; 10918 } 10919 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 10920 + " mDebugTransient=" + mDebugTransient 10921 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 10922 } 10923 } 10924 if (mOpenGlTraceApp != null) { 10925 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 10926 if (needSep) { 10927 pw.println(); 10928 needSep = false; 10929 } 10930 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 10931 } 10932 } 10933 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 10934 || mProfileFd != null) { 10935 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 10936 if (needSep) { 10937 pw.println(); 10938 needSep = false; 10939 } 10940 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 10941 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 10942 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 10943 + mAutoStopProfiler); 10944 } 10945 } 10946 if (dumpPackage == null) { 10947 if (mAlwaysFinishActivities || mController != null) { 10948 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 10949 + " mController=" + mController); 10950 } 10951 if (dumpAll) { 10952 pw.println(" Total persistent processes: " + numPers); 10953 pw.println(" mStartRunning=" + mStartRunning 10954 + " mProcessesReady=" + mProcessesReady 10955 + " mSystemReady=" + mSystemReady); 10956 pw.println(" mBooting=" + mBooting 10957 + " mBooted=" + mBooted 10958 + " mFactoryTest=" + mFactoryTest); 10959 pw.print(" mLastPowerCheckRealtime="); 10960 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 10961 pw.println(""); 10962 pw.print(" mLastPowerCheckUptime="); 10963 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 10964 pw.println(""); 10965 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 10966 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 10967 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 10968 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 10969 + " (" + mLruProcesses.size() + " total)" 10970 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 10971 + " mNumServiceProcs=" + mNumServiceProcs 10972 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 10973 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 10974 + " mLastMemoryLevel" + mLastMemoryLevel 10975 + " mLastNumProcesses" + mLastNumProcesses); 10976 long now = SystemClock.uptimeMillis(); 10977 pw.print(" mLastIdleTime="); 10978 TimeUtils.formatDuration(now, mLastIdleTime, pw); 10979 pw.print(" mLowRamSinceLastIdle="); 10980 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 10981 pw.println(); 10982 } 10983 } 10984 10985 if (!printedAnything) { 10986 pw.println(" (nothing)"); 10987 } 10988 } 10989 10990 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 10991 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 10992 if (mProcessesToGc.size() > 0) { 10993 boolean printed = false; 10994 long now = SystemClock.uptimeMillis(); 10995 for (int i=0; i<mProcessesToGc.size(); i++) { 10996 ProcessRecord proc = mProcessesToGc.get(i); 10997 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 10998 continue; 10999 } 11000 if (!printed) { 11001 if (needSep) pw.println(); 11002 needSep = true; 11003 pw.println(" Processes that are waiting to GC:"); 11004 printed = true; 11005 } 11006 pw.print(" Process "); pw.println(proc); 11007 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11008 pw.print(", last gced="); 11009 pw.print(now-proc.lastRequestedGc); 11010 pw.print(" ms ago, last lowMem="); 11011 pw.print(now-proc.lastLowMemory); 11012 pw.println(" ms ago"); 11013 11014 } 11015 } 11016 return needSep; 11017 } 11018 11019 void printOomLevel(PrintWriter pw, String name, int adj) { 11020 pw.print(" "); 11021 if (adj >= 0) { 11022 pw.print(' '); 11023 if (adj < 10) pw.print(' '); 11024 } else { 11025 if (adj > -10) pw.print(' '); 11026 } 11027 pw.print(adj); 11028 pw.print(": "); 11029 pw.print(name); 11030 pw.print(" ("); 11031 pw.print(mProcessList.getMemLevel(adj)/1024); 11032 pw.println(" kB)"); 11033 } 11034 11035 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11036 int opti, boolean dumpAll) { 11037 boolean needSep = false; 11038 11039 if (mLruProcesses.size() > 0) { 11040 if (needSep) pw.println(); 11041 needSep = true; 11042 pw.println(" OOM levels:"); 11043 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11044 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11045 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11046 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11047 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11048 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11049 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11050 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11051 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11052 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11053 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11054 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11055 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11056 11057 if (needSep) pw.println(); 11058 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11059 pw.print(" total, non-act at "); 11060 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11061 pw.print(", non-svc at "); 11062 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11063 pw.println("):"); 11064 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11065 needSep = true; 11066 } 11067 11068 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11069 11070 pw.println(); 11071 pw.println(" mHomeProcess: " + mHomeProcess); 11072 pw.println(" mPreviousProcess: " + mPreviousProcess); 11073 if (mHeavyWeightProcess != null) { 11074 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11075 } 11076 11077 return true; 11078 } 11079 11080 /** 11081 * There are three ways to call this: 11082 * - no provider specified: dump all the providers 11083 * - a flattened component name that matched an existing provider was specified as the 11084 * first arg: dump that one provider 11085 * - the first arg isn't the flattened component name of an existing provider: 11086 * dump all providers whose component contains the first arg as a substring 11087 */ 11088 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11089 int opti, boolean dumpAll) { 11090 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11091 } 11092 11093 static class ItemMatcher { 11094 ArrayList<ComponentName> components; 11095 ArrayList<String> strings; 11096 ArrayList<Integer> objects; 11097 boolean all; 11098 11099 ItemMatcher() { 11100 all = true; 11101 } 11102 11103 void build(String name) { 11104 ComponentName componentName = ComponentName.unflattenFromString(name); 11105 if (componentName != null) { 11106 if (components == null) { 11107 components = new ArrayList<ComponentName>(); 11108 } 11109 components.add(componentName); 11110 all = false; 11111 } else { 11112 int objectId = 0; 11113 // Not a '/' separated full component name; maybe an object ID? 11114 try { 11115 objectId = Integer.parseInt(name, 16); 11116 if (objects == null) { 11117 objects = new ArrayList<Integer>(); 11118 } 11119 objects.add(objectId); 11120 all = false; 11121 } catch (RuntimeException e) { 11122 // Not an integer; just do string match. 11123 if (strings == null) { 11124 strings = new ArrayList<String>(); 11125 } 11126 strings.add(name); 11127 all = false; 11128 } 11129 } 11130 } 11131 11132 int build(String[] args, int opti) { 11133 for (; opti<args.length; opti++) { 11134 String name = args[opti]; 11135 if ("--".equals(name)) { 11136 return opti+1; 11137 } 11138 build(name); 11139 } 11140 return opti; 11141 } 11142 11143 boolean match(Object object, ComponentName comp) { 11144 if (all) { 11145 return true; 11146 } 11147 if (components != null) { 11148 for (int i=0; i<components.size(); i++) { 11149 if (components.get(i).equals(comp)) { 11150 return true; 11151 } 11152 } 11153 } 11154 if (objects != null) { 11155 for (int i=0; i<objects.size(); i++) { 11156 if (System.identityHashCode(object) == objects.get(i)) { 11157 return true; 11158 } 11159 } 11160 } 11161 if (strings != null) { 11162 String flat = comp.flattenToString(); 11163 for (int i=0; i<strings.size(); i++) { 11164 if (flat.contains(strings.get(i))) { 11165 return true; 11166 } 11167 } 11168 } 11169 return false; 11170 } 11171 } 11172 11173 /** 11174 * There are three things that cmd can be: 11175 * - a flattened component name that matches an existing activity 11176 * - the cmd arg isn't the flattened component name of an existing activity: 11177 * dump all activity whose component contains the cmd as a substring 11178 * - A hex number of the ActivityRecord object instance. 11179 */ 11180 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11181 int opti, boolean dumpAll) { 11182 ArrayList<ActivityRecord> activities; 11183 11184 synchronized (this) { 11185 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11186 } 11187 11188 if (activities.size() <= 0) { 11189 return false; 11190 } 11191 11192 String[] newArgs = new String[args.length - opti]; 11193 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11194 11195 TaskRecord lastTask = null; 11196 boolean needSep = false; 11197 for (int i=activities.size()-1; i>=0; i--) { 11198 ActivityRecord r = activities.get(i); 11199 if (needSep) { 11200 pw.println(); 11201 } 11202 needSep = true; 11203 synchronized (this) { 11204 if (lastTask != r.task) { 11205 lastTask = r.task; 11206 pw.print("TASK "); pw.print(lastTask.affinity); 11207 pw.print(" id="); pw.println(lastTask.taskId); 11208 if (dumpAll) { 11209 lastTask.dump(pw, " "); 11210 } 11211 } 11212 } 11213 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11214 } 11215 return true; 11216 } 11217 11218 /** 11219 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11220 * there is a thread associated with the activity. 11221 */ 11222 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11223 final ActivityRecord r, String[] args, boolean dumpAll) { 11224 String innerPrefix = prefix + " "; 11225 synchronized (this) { 11226 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11227 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11228 pw.print(" pid="); 11229 if (r.app != null) pw.println(r.app.pid); 11230 else pw.println("(not running)"); 11231 if (dumpAll) { 11232 r.dump(pw, innerPrefix); 11233 } 11234 } 11235 if (r.app != null && r.app.thread != null) { 11236 // flush anything that is already in the PrintWriter since the thread is going 11237 // to write to the file descriptor directly 11238 pw.flush(); 11239 try { 11240 TransferPipe tp = new TransferPipe(); 11241 try { 11242 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11243 r.appToken, innerPrefix, args); 11244 tp.go(fd); 11245 } finally { 11246 tp.kill(); 11247 } 11248 } catch (IOException e) { 11249 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11250 } catch (RemoteException e) { 11251 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11252 } 11253 } 11254 } 11255 11256 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11257 int opti, boolean dumpAll, String dumpPackage) { 11258 boolean needSep = false; 11259 boolean onlyHistory = false; 11260 boolean printedAnything = false; 11261 11262 if ("history".equals(dumpPackage)) { 11263 if (opti < args.length && "-s".equals(args[opti])) { 11264 dumpAll = false; 11265 } 11266 onlyHistory = true; 11267 dumpPackage = null; 11268 } 11269 11270 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11271 if (!onlyHistory && dumpAll) { 11272 if (mRegisteredReceivers.size() > 0) { 11273 boolean printed = false; 11274 Iterator it = mRegisteredReceivers.values().iterator(); 11275 while (it.hasNext()) { 11276 ReceiverList r = (ReceiverList)it.next(); 11277 if (dumpPackage != null && (r.app == null || 11278 !dumpPackage.equals(r.app.info.packageName))) { 11279 continue; 11280 } 11281 if (!printed) { 11282 pw.println(" Registered Receivers:"); 11283 needSep = true; 11284 printed = true; 11285 printedAnything = true; 11286 } 11287 pw.print(" * "); pw.println(r); 11288 r.dump(pw, " "); 11289 } 11290 } 11291 11292 if (mReceiverResolver.dump(pw, needSep ? 11293 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11294 " ", dumpPackage, false)) { 11295 needSep = true; 11296 printedAnything = true; 11297 } 11298 } 11299 11300 for (BroadcastQueue q : mBroadcastQueues) { 11301 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11302 printedAnything |= needSep; 11303 } 11304 11305 needSep = true; 11306 11307 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11308 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11309 if (needSep) { 11310 pw.println(); 11311 } 11312 needSep = true; 11313 printedAnything = true; 11314 pw.print(" Sticky broadcasts for user "); 11315 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11316 StringBuilder sb = new StringBuilder(128); 11317 for (Map.Entry<String, ArrayList<Intent>> ent 11318 : mStickyBroadcasts.valueAt(user).entrySet()) { 11319 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11320 if (dumpAll) { 11321 pw.println(":"); 11322 ArrayList<Intent> intents = ent.getValue(); 11323 final int N = intents.size(); 11324 for (int i=0; i<N; i++) { 11325 sb.setLength(0); 11326 sb.append(" Intent: "); 11327 intents.get(i).toShortString(sb, false, true, false, false); 11328 pw.println(sb.toString()); 11329 Bundle bundle = intents.get(i).getExtras(); 11330 if (bundle != null) { 11331 pw.print(" "); 11332 pw.println(bundle.toString()); 11333 } 11334 } 11335 } else { 11336 pw.println(""); 11337 } 11338 } 11339 } 11340 } 11341 11342 if (!onlyHistory && dumpAll) { 11343 pw.println(); 11344 for (BroadcastQueue queue : mBroadcastQueues) { 11345 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11346 + queue.mBroadcastsScheduled); 11347 } 11348 pw.println(" mHandler:"); 11349 mHandler.dump(new PrintWriterPrinter(pw), " "); 11350 needSep = true; 11351 printedAnything = true; 11352 } 11353 11354 if (!printedAnything) { 11355 pw.println(" (nothing)"); 11356 } 11357 } 11358 11359 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11360 int opti, boolean dumpAll, String dumpPackage) { 11361 boolean needSep; 11362 boolean printedAnything = false; 11363 11364 ItemMatcher matcher = new ItemMatcher(); 11365 matcher.build(args, opti); 11366 11367 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11368 11369 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11370 printedAnything |= needSep; 11371 11372 if (mLaunchingProviders.size() > 0) { 11373 boolean printed = false; 11374 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11375 ContentProviderRecord r = mLaunchingProviders.get(i); 11376 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11377 continue; 11378 } 11379 if (!printed) { 11380 if (needSep) pw.println(); 11381 needSep = true; 11382 pw.println(" Launching content providers:"); 11383 printed = true; 11384 printedAnything = true; 11385 } 11386 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11387 pw.println(r); 11388 } 11389 } 11390 11391 if (mGrantedUriPermissions.size() > 0) { 11392 boolean printed = false; 11393 int dumpUid = -2; 11394 if (dumpPackage != null) { 11395 try { 11396 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11397 } catch (NameNotFoundException e) { 11398 dumpUid = -1; 11399 } 11400 } 11401 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11402 int uid = mGrantedUriPermissions.keyAt(i); 11403 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11404 continue; 11405 } 11406 ArrayMap<Uri, UriPermission> perms 11407 = mGrantedUriPermissions.valueAt(i); 11408 if (!printed) { 11409 if (needSep) pw.println(); 11410 needSep = true; 11411 pw.println(" Granted Uri Permissions:"); 11412 printed = true; 11413 printedAnything = true; 11414 } 11415 pw.print(" * UID "); pw.print(uid); 11416 pw.println(" holds:"); 11417 for (UriPermission perm : perms.values()) { 11418 pw.print(" "); pw.println(perm); 11419 if (dumpAll) { 11420 perm.dump(pw, " "); 11421 } 11422 } 11423 } 11424 } 11425 11426 if (!printedAnything) { 11427 pw.println(" (nothing)"); 11428 } 11429 } 11430 11431 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11432 int opti, boolean dumpAll, String dumpPackage) { 11433 boolean printed = false; 11434 11435 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11436 11437 if (mIntentSenderRecords.size() > 0) { 11438 Iterator<WeakReference<PendingIntentRecord>> it 11439 = mIntentSenderRecords.values().iterator(); 11440 while (it.hasNext()) { 11441 WeakReference<PendingIntentRecord> ref = it.next(); 11442 PendingIntentRecord rec = ref != null ? ref.get(): null; 11443 if (dumpPackage != null && (rec == null 11444 || !dumpPackage.equals(rec.key.packageName))) { 11445 continue; 11446 } 11447 printed = true; 11448 if (rec != null) { 11449 pw.print(" * "); pw.println(rec); 11450 if (dumpAll) { 11451 rec.dump(pw, " "); 11452 } 11453 } else { 11454 pw.print(" * "); pw.println(ref); 11455 } 11456 } 11457 } 11458 11459 if (!printed) { 11460 pw.println(" (nothing)"); 11461 } 11462 } 11463 11464 private static final int dumpProcessList(PrintWriter pw, 11465 ActivityManagerService service, List list, 11466 String prefix, String normalLabel, String persistentLabel, 11467 String dumpPackage) { 11468 int numPers = 0; 11469 final int N = list.size()-1; 11470 for (int i=N; i>=0; i--) { 11471 ProcessRecord r = (ProcessRecord)list.get(i); 11472 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11473 continue; 11474 } 11475 pw.println(String.format("%s%s #%2d: %s", 11476 prefix, (r.persistent ? persistentLabel : normalLabel), 11477 i, r.toString())); 11478 if (r.persistent) { 11479 numPers++; 11480 } 11481 } 11482 return numPers; 11483 } 11484 11485 private static final boolean dumpProcessOomList(PrintWriter pw, 11486 ActivityManagerService service, List<ProcessRecord> origList, 11487 String prefix, String normalLabel, String persistentLabel, 11488 boolean inclDetails, String dumpPackage) { 11489 11490 ArrayList<Pair<ProcessRecord, Integer>> list 11491 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11492 for (int i=0; i<origList.size(); i++) { 11493 ProcessRecord r = origList.get(i); 11494 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11495 continue; 11496 } 11497 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11498 } 11499 11500 if (list.size() <= 0) { 11501 return false; 11502 } 11503 11504 Comparator<Pair<ProcessRecord, Integer>> comparator 11505 = new Comparator<Pair<ProcessRecord, Integer>>() { 11506 @Override 11507 public int compare(Pair<ProcessRecord, Integer> object1, 11508 Pair<ProcessRecord, Integer> object2) { 11509 if (object1.first.setAdj != object2.first.setAdj) { 11510 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11511 } 11512 if (object1.second.intValue() != object2.second.intValue()) { 11513 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11514 } 11515 return 0; 11516 } 11517 }; 11518 11519 Collections.sort(list, comparator); 11520 11521 final long curRealtime = SystemClock.elapsedRealtime(); 11522 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11523 final long curUptime = SystemClock.uptimeMillis(); 11524 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11525 11526 for (int i=list.size()-1; i>=0; i--) { 11527 ProcessRecord r = list.get(i).first; 11528 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11529 char schedGroup; 11530 switch (r.setSchedGroup) { 11531 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11532 schedGroup = 'B'; 11533 break; 11534 case Process.THREAD_GROUP_DEFAULT: 11535 schedGroup = 'F'; 11536 break; 11537 default: 11538 schedGroup = '?'; 11539 break; 11540 } 11541 char foreground; 11542 if (r.foregroundActivities) { 11543 foreground = 'A'; 11544 } else if (r.foregroundServices) { 11545 foreground = 'S'; 11546 } else { 11547 foreground = ' '; 11548 } 11549 String procState = ProcessList.makeProcStateString(r.curProcState); 11550 pw.print(prefix); 11551 pw.print(r.persistent ? persistentLabel : normalLabel); 11552 pw.print(" #"); 11553 int num = (origList.size()-1)-list.get(i).second; 11554 if (num < 10) pw.print(' '); 11555 pw.print(num); 11556 pw.print(": "); 11557 pw.print(oomAdj); 11558 pw.print(' '); 11559 pw.print(schedGroup); 11560 pw.print('/'); 11561 pw.print(foreground); 11562 pw.print('/'); 11563 pw.print(procState); 11564 pw.print(" trm:"); 11565 if (r.trimMemoryLevel < 10) pw.print(' '); 11566 pw.print(r.trimMemoryLevel); 11567 pw.print(' '); 11568 pw.print(r.toShortString()); 11569 pw.print(" ("); 11570 pw.print(r.adjType); 11571 pw.println(')'); 11572 if (r.adjSource != null || r.adjTarget != null) { 11573 pw.print(prefix); 11574 pw.print(" "); 11575 if (r.adjTarget instanceof ComponentName) { 11576 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11577 } else if (r.adjTarget != null) { 11578 pw.print(r.adjTarget.toString()); 11579 } else { 11580 pw.print("{null}"); 11581 } 11582 pw.print("<="); 11583 if (r.adjSource instanceof ProcessRecord) { 11584 pw.print("Proc{"); 11585 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11586 pw.println("}"); 11587 } else if (r.adjSource != null) { 11588 pw.println(r.adjSource.toString()); 11589 } else { 11590 pw.println("{null}"); 11591 } 11592 } 11593 if (inclDetails) { 11594 pw.print(prefix); 11595 pw.print(" "); 11596 pw.print("oom: max="); pw.print(r.maxAdj); 11597 pw.print(" curRaw="); pw.print(r.curRawAdj); 11598 pw.print(" setRaw="); pw.print(r.setRawAdj); 11599 pw.print(" cur="); pw.print(r.curAdj); 11600 pw.print(" set="); pw.println(r.setAdj); 11601 pw.print(prefix); 11602 pw.print(" "); 11603 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11604 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11605 pw.print(" lastPss="); pw.print(r.lastPss); 11606 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11607 pw.print(prefix); 11608 pw.print(" "); 11609 pw.print("keeping="); pw.print(r.keeping); 11610 pw.print(" cached="); pw.print(r.cached); 11611 pw.print(" empty="); pw.print(r.empty); 11612 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11613 11614 if (!r.keeping) { 11615 if (r.lastWakeTime != 0) { 11616 long wtime; 11617 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11618 synchronized (stats) { 11619 wtime = stats.getProcessWakeTime(r.info.uid, 11620 r.pid, curRealtime); 11621 } 11622 long timeUsed = wtime - r.lastWakeTime; 11623 pw.print(prefix); 11624 pw.print(" "); 11625 pw.print("keep awake over "); 11626 TimeUtils.formatDuration(realtimeSince, pw); 11627 pw.print(" used "); 11628 TimeUtils.formatDuration(timeUsed, pw); 11629 pw.print(" ("); 11630 pw.print((timeUsed*100)/realtimeSince); 11631 pw.println("%)"); 11632 } 11633 if (r.lastCpuTime != 0) { 11634 long timeUsed = r.curCpuTime - r.lastCpuTime; 11635 pw.print(prefix); 11636 pw.print(" "); 11637 pw.print("run cpu over "); 11638 TimeUtils.formatDuration(uptimeSince, pw); 11639 pw.print(" used "); 11640 TimeUtils.formatDuration(timeUsed, pw); 11641 pw.print(" ("); 11642 pw.print((timeUsed*100)/uptimeSince); 11643 pw.println("%)"); 11644 } 11645 } 11646 } 11647 } 11648 return true; 11649 } 11650 11651 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11652 ArrayList<ProcessRecord> procs; 11653 synchronized (this) { 11654 if (args != null && args.length > start 11655 && args[start].charAt(0) != '-') { 11656 procs = new ArrayList<ProcessRecord>(); 11657 int pid = -1; 11658 try { 11659 pid = Integer.parseInt(args[start]); 11660 } catch (NumberFormatException e) { 11661 } 11662 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11663 ProcessRecord proc = mLruProcesses.get(i); 11664 if (proc.pid == pid) { 11665 procs.add(proc); 11666 } else if (proc.processName.equals(args[start])) { 11667 procs.add(proc); 11668 } 11669 } 11670 if (procs.size() <= 0) { 11671 return null; 11672 } 11673 } else { 11674 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11675 } 11676 } 11677 return procs; 11678 } 11679 11680 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11681 PrintWriter pw, String[] args) { 11682 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11683 if (procs == null) { 11684 pw.println("No process found for: " + args[0]); 11685 return; 11686 } 11687 11688 long uptime = SystemClock.uptimeMillis(); 11689 long realtime = SystemClock.elapsedRealtime(); 11690 pw.println("Applications Graphics Acceleration Info:"); 11691 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11692 11693 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11694 ProcessRecord r = procs.get(i); 11695 if (r.thread != null) { 11696 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11697 pw.flush(); 11698 try { 11699 TransferPipe tp = new TransferPipe(); 11700 try { 11701 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11702 tp.go(fd); 11703 } finally { 11704 tp.kill(); 11705 } 11706 } catch (IOException e) { 11707 pw.println("Failure while dumping the app: " + r); 11708 pw.flush(); 11709 } catch (RemoteException e) { 11710 pw.println("Got a RemoteException while dumping the app " + r); 11711 pw.flush(); 11712 } 11713 } 11714 } 11715 } 11716 11717 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11718 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11719 if (procs == null) { 11720 pw.println("No process found for: " + args[0]); 11721 return; 11722 } 11723 11724 pw.println("Applications Database Info:"); 11725 11726 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11727 ProcessRecord r = procs.get(i); 11728 if (r.thread != null) { 11729 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11730 pw.flush(); 11731 try { 11732 TransferPipe tp = new TransferPipe(); 11733 try { 11734 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11735 tp.go(fd); 11736 } finally { 11737 tp.kill(); 11738 } 11739 } catch (IOException e) { 11740 pw.println("Failure while dumping the app: " + r); 11741 pw.flush(); 11742 } catch (RemoteException e) { 11743 pw.println("Got a RemoteException while dumping the app " + r); 11744 pw.flush(); 11745 } 11746 } 11747 } 11748 } 11749 11750 final static class MemItem { 11751 final boolean isProc; 11752 final String label; 11753 final String shortLabel; 11754 final long pss; 11755 final int id; 11756 final boolean hasActivities; 11757 ArrayList<MemItem> subitems; 11758 11759 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11760 boolean _hasActivities) { 11761 isProc = true; 11762 label = _label; 11763 shortLabel = _shortLabel; 11764 pss = _pss; 11765 id = _id; 11766 hasActivities = _hasActivities; 11767 } 11768 11769 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11770 isProc = false; 11771 label = _label; 11772 shortLabel = _shortLabel; 11773 pss = _pss; 11774 id = _id; 11775 hasActivities = false; 11776 } 11777 } 11778 11779 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11780 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11781 if (sort && !isCompact) { 11782 Collections.sort(items, new Comparator<MemItem>() { 11783 @Override 11784 public int compare(MemItem lhs, MemItem rhs) { 11785 if (lhs.pss < rhs.pss) { 11786 return 1; 11787 } else if (lhs.pss > rhs.pss) { 11788 return -1; 11789 } 11790 return 0; 11791 } 11792 }); 11793 } 11794 11795 for (int i=0; i<items.size(); i++) { 11796 MemItem mi = items.get(i); 11797 if (!isCompact) { 11798 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11799 } else if (mi.isProc) { 11800 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11801 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11802 pw.println(mi.hasActivities ? ",a" : ",e"); 11803 } else { 11804 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11805 pw.println(mi.pss); 11806 } 11807 if (mi.subitems != null) { 11808 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11809 true, isCompact); 11810 } 11811 } 11812 } 11813 11814 // These are in KB. 11815 static final long[] DUMP_MEM_BUCKETS = new long[] { 11816 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11817 120*1024, 160*1024, 200*1024, 11818 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11819 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11820 }; 11821 11822 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11823 boolean stackLike) { 11824 int start = label.lastIndexOf('.'); 11825 if (start >= 0) start++; 11826 else start = 0; 11827 int end = label.length(); 11828 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11829 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11830 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11831 out.append(bucket); 11832 out.append(stackLike ? "MB." : "MB "); 11833 out.append(label, start, end); 11834 return; 11835 } 11836 } 11837 out.append(memKB/1024); 11838 out.append(stackLike ? "MB." : "MB "); 11839 out.append(label, start, end); 11840 } 11841 11842 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11843 ProcessList.NATIVE_ADJ, 11844 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11845 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11846 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11847 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11848 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11849 }; 11850 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11851 "Native", 11852 "System", "Persistent", "Foreground", 11853 "Visible", "Perceptible", 11854 "Heavy Weight", "Backup", 11855 "A Services", "Home", 11856 "Previous", "B Services", "Cached" 11857 }; 11858 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 11859 "native", 11860 "sys", "pers", "fore", 11861 "vis", "percept", 11862 "heavy", "backup", 11863 "servicea", "home", 11864 "prev", "serviceb", "cached" 11865 }; 11866 11867 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 11868 long realtime, boolean isCheckinRequest, boolean isCompact) { 11869 if (isCheckinRequest || isCompact) { 11870 // short checkin version 11871 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 11872 } else { 11873 pw.println("Applications Memory Usage (kB):"); 11874 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11875 } 11876 } 11877 11878 final void dumpApplicationMemoryUsage(FileDescriptor fd, 11879 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 11880 boolean dumpDetails = false; 11881 boolean dumpFullDetails = false; 11882 boolean dumpDalvik = false; 11883 boolean oomOnly = false; 11884 boolean isCompact = false; 11885 boolean localOnly = false; 11886 11887 int opti = 0; 11888 while (opti < args.length) { 11889 String opt = args[opti]; 11890 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11891 break; 11892 } 11893 opti++; 11894 if ("-a".equals(opt)) { 11895 dumpDetails = true; 11896 dumpFullDetails = true; 11897 dumpDalvik = true; 11898 } else if ("-d".equals(opt)) { 11899 dumpDalvik = true; 11900 } else if ("-c".equals(opt)) { 11901 isCompact = true; 11902 } else if ("--oom".equals(opt)) { 11903 oomOnly = true; 11904 } else if ("--local".equals(opt)) { 11905 localOnly = true; 11906 } else if ("-h".equals(opt)) { 11907 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 11908 pw.println(" -a: include all available information for each process."); 11909 pw.println(" -d: include dalvik details when dumping process details."); 11910 pw.println(" -c: dump in a compact machine-parseable representation."); 11911 pw.println(" --oom: only show processes organized by oom adj."); 11912 pw.println(" --local: only collect details locally, don't call process."); 11913 pw.println("If [process] is specified it can be the name or "); 11914 pw.println("pid of a specific process to dump."); 11915 return; 11916 } else { 11917 pw.println("Unknown argument: " + opt + "; use -h for help"); 11918 } 11919 } 11920 11921 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 11922 long uptime = SystemClock.uptimeMillis(); 11923 long realtime = SystemClock.elapsedRealtime(); 11924 final long[] tmpLong = new long[1]; 11925 11926 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 11927 if (procs == null) { 11928 // No Java processes. Maybe they want to print a native process. 11929 if (args != null && args.length > opti 11930 && args[opti].charAt(0) != '-') { 11931 ArrayList<ProcessCpuTracker.Stats> nativeProcs 11932 = new ArrayList<ProcessCpuTracker.Stats>(); 11933 updateCpuStatsNow(); 11934 int findPid = -1; 11935 try { 11936 findPid = Integer.parseInt(args[opti]); 11937 } catch (NumberFormatException e) { 11938 } 11939 synchronized (mProcessCpuThread) { 11940 final int N = mProcessCpuTracker.countStats(); 11941 for (int i=0; i<N; i++) { 11942 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 11943 if (st.pid == findPid || (st.baseName != null 11944 && st.baseName.equals(args[opti]))) { 11945 nativeProcs.add(st); 11946 } 11947 } 11948 } 11949 if (nativeProcs.size() > 0) { 11950 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 11951 isCompact); 11952 Debug.MemoryInfo mi = null; 11953 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 11954 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 11955 final int pid = r.pid; 11956 if (!isCheckinRequest && dumpDetails) { 11957 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 11958 } 11959 if (mi == null) { 11960 mi = new Debug.MemoryInfo(); 11961 } 11962 if (dumpDetails || (!brief && !oomOnly)) { 11963 Debug.getMemoryInfo(pid, mi); 11964 } else { 11965 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11966 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11967 } 11968 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11969 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 11970 if (isCheckinRequest) { 11971 pw.println(); 11972 } 11973 } 11974 return; 11975 } 11976 } 11977 pw.println("No process found for: " + args[opti]); 11978 return; 11979 } 11980 11981 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 11982 dumpDetails = true; 11983 } 11984 11985 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 11986 11987 String[] innerArgs = new String[args.length-opti]; 11988 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 11989 11990 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 11991 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 11992 long nativePss=0, dalvikPss=0, otherPss=0; 11993 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 11994 11995 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 11996 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 11997 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 11998 11999 long totalPss = 0; 12000 long cachedPss = 0; 12001 12002 Debug.MemoryInfo mi = null; 12003 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12004 final ProcessRecord r = procs.get(i); 12005 final IApplicationThread thread; 12006 final int pid; 12007 final int oomAdj; 12008 final boolean hasActivities; 12009 synchronized (this) { 12010 thread = r.thread; 12011 pid = r.pid; 12012 oomAdj = r.getSetAdjWithServices(); 12013 hasActivities = r.activities.size() > 0; 12014 } 12015 if (thread != null) { 12016 if (!isCheckinRequest && dumpDetails) { 12017 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12018 } 12019 if (mi == null) { 12020 mi = new Debug.MemoryInfo(); 12021 } 12022 if (dumpDetails || (!brief && !oomOnly)) { 12023 Debug.getMemoryInfo(pid, mi); 12024 } else { 12025 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12026 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12027 } 12028 if (dumpDetails) { 12029 if (localOnly) { 12030 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12031 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12032 if (isCheckinRequest) { 12033 pw.println(); 12034 } 12035 } else { 12036 try { 12037 pw.flush(); 12038 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12039 dumpDalvik, innerArgs); 12040 } catch (RemoteException e) { 12041 if (!isCheckinRequest) { 12042 pw.println("Got RemoteException!"); 12043 pw.flush(); 12044 } 12045 } 12046 } 12047 } 12048 12049 final long myTotalPss = mi.getTotalPss(); 12050 final long myTotalUss = mi.getTotalUss(); 12051 12052 synchronized (this) { 12053 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12054 // Record this for posterity if the process has been stable. 12055 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12056 } 12057 } 12058 12059 if (!isCheckinRequest && mi != null) { 12060 totalPss += myTotalPss; 12061 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12062 (hasActivities ? " / activities)" : ")"), 12063 r.processName, myTotalPss, pid, hasActivities); 12064 procMems.add(pssItem); 12065 procMemsMap.put(pid, pssItem); 12066 12067 nativePss += mi.nativePss; 12068 dalvikPss += mi.dalvikPss; 12069 otherPss += mi.otherPss; 12070 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12071 long mem = mi.getOtherPss(j); 12072 miscPss[j] += mem; 12073 otherPss -= mem; 12074 } 12075 12076 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12077 cachedPss += myTotalPss; 12078 } 12079 12080 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12081 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12082 || oomIndex == (oomPss.length-1)) { 12083 oomPss[oomIndex] += myTotalPss; 12084 if (oomProcs[oomIndex] == null) { 12085 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12086 } 12087 oomProcs[oomIndex].add(pssItem); 12088 break; 12089 } 12090 } 12091 } 12092 } 12093 } 12094 12095 if (!isCheckinRequest && procs.size() > 1) { 12096 // If we are showing aggregations, also look for native processes to 12097 // include so that our aggregations are more accurate. 12098 updateCpuStatsNow(); 12099 synchronized (mProcessCpuThread) { 12100 final int N = mProcessCpuTracker.countStats(); 12101 for (int i=0; i<N; i++) { 12102 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12103 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12104 if (mi == null) { 12105 mi = new Debug.MemoryInfo(); 12106 } 12107 if (!brief && !oomOnly) { 12108 Debug.getMemoryInfo(st.pid, mi); 12109 } else { 12110 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12111 mi.nativePrivateDirty = (int)tmpLong[0]; 12112 } 12113 12114 final long myTotalPss = mi.getTotalPss(); 12115 totalPss += myTotalPss; 12116 12117 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12118 st.name, myTotalPss, st.pid, false); 12119 procMems.add(pssItem); 12120 12121 nativePss += mi.nativePss; 12122 dalvikPss += mi.dalvikPss; 12123 otherPss += mi.otherPss; 12124 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12125 long mem = mi.getOtherPss(j); 12126 miscPss[j] += mem; 12127 otherPss -= mem; 12128 } 12129 oomPss[0] += myTotalPss; 12130 if (oomProcs[0] == null) { 12131 oomProcs[0] = new ArrayList<MemItem>(); 12132 } 12133 oomProcs[0].add(pssItem); 12134 } 12135 } 12136 } 12137 12138 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12139 12140 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12141 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12142 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12143 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12144 String label = Debug.MemoryInfo.getOtherLabel(j); 12145 catMems.add(new MemItem(label, label, miscPss[j], j)); 12146 } 12147 12148 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12149 for (int j=0; j<oomPss.length; j++) { 12150 if (oomPss[j] != 0) { 12151 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12152 : DUMP_MEM_OOM_LABEL[j]; 12153 MemItem item = new MemItem(label, label, oomPss[j], 12154 DUMP_MEM_OOM_ADJ[j]); 12155 item.subitems = oomProcs[j]; 12156 oomMems.add(item); 12157 } 12158 } 12159 12160 if (!brief && !oomOnly && !isCompact) { 12161 pw.println(); 12162 pw.println("Total PSS by process:"); 12163 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12164 pw.println(); 12165 } 12166 if (!isCompact) { 12167 pw.println("Total PSS by OOM adjustment:"); 12168 } 12169 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12170 if (!brief && !oomOnly) { 12171 PrintWriter out = categoryPw != null ? categoryPw : pw; 12172 if (!isCompact) { 12173 out.println(); 12174 out.println("Total PSS by category:"); 12175 } 12176 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12177 } 12178 if (!isCompact) { 12179 pw.println(); 12180 } 12181 MemInfoReader memInfo = new MemInfoReader(); 12182 memInfo.readMemInfo(); 12183 if (!brief) { 12184 if (!isCompact) { 12185 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12186 pw.print(" kB (status "); 12187 switch (mLastMemoryLevel) { 12188 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12189 pw.println("normal)"); 12190 break; 12191 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12192 pw.println("moderate)"); 12193 break; 12194 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12195 pw.println("low)"); 12196 break; 12197 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12198 pw.println("critical)"); 12199 break; 12200 default: 12201 pw.print(mLastMemoryLevel); 12202 pw.println(")"); 12203 break; 12204 } 12205 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12206 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12207 pw.print(cachedPss); pw.print(" cached pss + "); 12208 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12209 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12210 } else { 12211 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12212 pw.print(cachedPss + memInfo.getCachedSizeKb() 12213 + memInfo.getFreeSizeKb()); pw.print(","); 12214 pw.println(totalPss - cachedPss); 12215 } 12216 } 12217 if (!isCompact) { 12218 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12219 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12220 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12221 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12222 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12223 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12224 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12225 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12226 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12227 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12228 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12229 } 12230 if (!brief) { 12231 if (memInfo.getZramTotalSizeKb() != 0) { 12232 if (!isCompact) { 12233 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12234 pw.print(" kB physical used for "); 12235 pw.print(memInfo.getSwapTotalSizeKb() 12236 - memInfo.getSwapFreeSizeKb()); 12237 pw.print(" kB in swap ("); 12238 pw.print(memInfo.getSwapTotalSizeKb()); 12239 pw.println(" kB total swap)"); 12240 } else { 12241 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12242 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12243 pw.println(memInfo.getSwapFreeSizeKb()); 12244 } 12245 } 12246 final int[] SINGLE_LONG_FORMAT = new int[] { 12247 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12248 }; 12249 long[] longOut = new long[1]; 12250 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12251 SINGLE_LONG_FORMAT, null, longOut, null); 12252 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12253 longOut[0] = 0; 12254 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12255 SINGLE_LONG_FORMAT, null, longOut, null); 12256 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12257 longOut[0] = 0; 12258 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12259 SINGLE_LONG_FORMAT, null, longOut, null); 12260 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12261 longOut[0] = 0; 12262 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12263 SINGLE_LONG_FORMAT, null, longOut, null); 12264 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12265 if (!isCompact) { 12266 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12267 pw.print(" KSM: "); pw.print(sharing); 12268 pw.print(" kB saved from shared "); 12269 pw.print(shared); pw.println(" kB"); 12270 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12271 pw.print(voltile); pw.println(" kB volatile"); 12272 } 12273 pw.print(" Tuning: "); 12274 pw.print(ActivityManager.staticGetMemoryClass()); 12275 pw.print(" (large "); 12276 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12277 pw.print("), oom "); 12278 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12279 pw.print(" kB"); 12280 pw.print(", restore limit "); 12281 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12282 pw.print(" kB"); 12283 if (ActivityManager.isLowRamDeviceStatic()) { 12284 pw.print(" (low-ram)"); 12285 } 12286 if (ActivityManager.isHighEndGfx()) { 12287 pw.print(" (high-end-gfx)"); 12288 } 12289 pw.println(); 12290 } else { 12291 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12292 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12293 pw.println(voltile); 12294 pw.print("tuning,"); 12295 pw.print(ActivityManager.staticGetMemoryClass()); 12296 pw.print(','); 12297 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12298 pw.print(','); 12299 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12300 if (ActivityManager.isLowRamDeviceStatic()) { 12301 pw.print(",low-ram"); 12302 } 12303 if (ActivityManager.isHighEndGfx()) { 12304 pw.print(",high-end-gfx"); 12305 } 12306 pw.println(); 12307 } 12308 } 12309 } 12310 } 12311 12312 /** 12313 * Searches array of arguments for the specified string 12314 * @param args array of argument strings 12315 * @param value value to search for 12316 * @return true if the value is contained in the array 12317 */ 12318 private static boolean scanArgs(String[] args, String value) { 12319 if (args != null) { 12320 for (String arg : args) { 12321 if (value.equals(arg)) { 12322 return true; 12323 } 12324 } 12325 } 12326 return false; 12327 } 12328 12329 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12330 ContentProviderRecord cpr, boolean always) { 12331 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12332 12333 if (!inLaunching || always) { 12334 synchronized (cpr) { 12335 cpr.launchingApp = null; 12336 cpr.notifyAll(); 12337 } 12338 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12339 String names[] = cpr.info.authority.split(";"); 12340 for (int j = 0; j < names.length; j++) { 12341 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12342 } 12343 } 12344 12345 for (int i=0; i<cpr.connections.size(); i++) { 12346 ContentProviderConnection conn = cpr.connections.get(i); 12347 if (conn.waiting) { 12348 // If this connection is waiting for the provider, then we don't 12349 // need to mess with its process unless we are always removing 12350 // or for some reason the provider is not currently launching. 12351 if (inLaunching && !always) { 12352 continue; 12353 } 12354 } 12355 ProcessRecord capp = conn.client; 12356 conn.dead = true; 12357 if (conn.stableCount > 0) { 12358 if (!capp.persistent && capp.thread != null 12359 && capp.pid != 0 12360 && capp.pid != MY_PID) { 12361 killUnneededProcessLocked(capp, "depends on provider " 12362 + cpr.name.flattenToShortString() 12363 + " in dying proc " + (proc != null ? proc.processName : "??")); 12364 } 12365 } else if (capp.thread != null && conn.provider.provider != null) { 12366 try { 12367 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12368 } catch (RemoteException e) { 12369 } 12370 // In the protocol here, we don't expect the client to correctly 12371 // clean up this connection, we'll just remove it. 12372 cpr.connections.remove(i); 12373 conn.client.conProviders.remove(conn); 12374 } 12375 } 12376 12377 if (inLaunching && always) { 12378 mLaunchingProviders.remove(cpr); 12379 } 12380 return inLaunching; 12381 } 12382 12383 /** 12384 * Main code for cleaning up a process when it has gone away. This is 12385 * called both as a result of the process dying, or directly when stopping 12386 * a process when running in single process mode. 12387 */ 12388 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12389 boolean restarting, boolean allowRestart, int index) { 12390 if (index >= 0) { 12391 removeLruProcessLocked(app); 12392 ProcessList.remove(app.pid); 12393 } 12394 12395 mProcessesToGc.remove(app); 12396 mPendingPssProcesses.remove(app); 12397 12398 // Dismiss any open dialogs. 12399 if (app.crashDialog != null && !app.forceCrashReport) { 12400 app.crashDialog.dismiss(); 12401 app.crashDialog = null; 12402 } 12403 if (app.anrDialog != null) { 12404 app.anrDialog.dismiss(); 12405 app.anrDialog = null; 12406 } 12407 if (app.waitDialog != null) { 12408 app.waitDialog.dismiss(); 12409 app.waitDialog = null; 12410 } 12411 12412 app.crashing = false; 12413 app.notResponding = false; 12414 12415 app.resetPackageList(mProcessStats); 12416 app.unlinkDeathRecipient(); 12417 app.makeInactive(mProcessStats); 12418 app.forcingToForeground = null; 12419 updateProcessForegroundLocked(app, false, false); 12420 app.foregroundActivities = false; 12421 app.hasShownUi = false; 12422 app.hasAboveClient = false; 12423 12424 mServices.killServicesLocked(app, allowRestart); 12425 12426 boolean restart = false; 12427 12428 // Remove published content providers. 12429 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12430 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12431 final boolean always = app.bad || !allowRestart; 12432 if (removeDyingProviderLocked(app, cpr, always) || always) { 12433 // We left the provider in the launching list, need to 12434 // restart it. 12435 restart = true; 12436 } 12437 12438 cpr.provider = null; 12439 cpr.proc = null; 12440 } 12441 app.pubProviders.clear(); 12442 12443 // Take care of any launching providers waiting for this process. 12444 if (checkAppInLaunchingProvidersLocked(app, false)) { 12445 restart = true; 12446 } 12447 12448 // Unregister from connected content providers. 12449 if (!app.conProviders.isEmpty()) { 12450 for (int i=0; i<app.conProviders.size(); i++) { 12451 ContentProviderConnection conn = app.conProviders.get(i); 12452 conn.provider.connections.remove(conn); 12453 } 12454 app.conProviders.clear(); 12455 } 12456 12457 // At this point there may be remaining entries in mLaunchingProviders 12458 // where we were the only one waiting, so they are no longer of use. 12459 // Look for these and clean up if found. 12460 // XXX Commented out for now. Trying to figure out a way to reproduce 12461 // the actual situation to identify what is actually going on. 12462 if (false) { 12463 for (int i=0; i<mLaunchingProviders.size(); i++) { 12464 ContentProviderRecord cpr = (ContentProviderRecord) 12465 mLaunchingProviders.get(i); 12466 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12467 synchronized (cpr) { 12468 cpr.launchingApp = null; 12469 cpr.notifyAll(); 12470 } 12471 } 12472 } 12473 } 12474 12475 skipCurrentReceiverLocked(app); 12476 12477 // Unregister any receivers. 12478 for (int i=app.receivers.size()-1; i>=0; i--) { 12479 removeReceiverLocked(app.receivers.valueAt(i)); 12480 } 12481 app.receivers.clear(); 12482 12483 // If the app is undergoing backup, tell the backup manager about it 12484 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12485 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12486 + mBackupTarget.appInfo + " died during backup"); 12487 try { 12488 IBackupManager bm = IBackupManager.Stub.asInterface( 12489 ServiceManager.getService(Context.BACKUP_SERVICE)); 12490 bm.agentDisconnected(app.info.packageName); 12491 } catch (RemoteException e) { 12492 // can't happen; backup manager is local 12493 } 12494 } 12495 12496 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12497 ProcessChangeItem item = mPendingProcessChanges.get(i); 12498 if (item.pid == app.pid) { 12499 mPendingProcessChanges.remove(i); 12500 mAvailProcessChanges.add(item); 12501 } 12502 } 12503 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12504 12505 // If the caller is restarting this app, then leave it in its 12506 // current lists and let the caller take care of it. 12507 if (restarting) { 12508 return; 12509 } 12510 12511 if (!app.persistent || app.isolated) { 12512 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12513 "Removing non-persistent process during cleanup: " + app); 12514 mProcessNames.remove(app.processName, app.uid); 12515 mIsolatedProcesses.remove(app.uid); 12516 if (mHeavyWeightProcess == app) { 12517 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12518 mHeavyWeightProcess.userId, 0)); 12519 mHeavyWeightProcess = null; 12520 } 12521 } else if (!app.removed) { 12522 // This app is persistent, so we need to keep its record around. 12523 // If it is not already on the pending app list, add it there 12524 // and start a new process for it. 12525 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12526 mPersistentStartingProcesses.add(app); 12527 restart = true; 12528 } 12529 } 12530 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12531 "Clean-up removing on hold: " + app); 12532 mProcessesOnHold.remove(app); 12533 12534 if (app == mHomeProcess) { 12535 mHomeProcess = null; 12536 } 12537 if (app == mPreviousProcess) { 12538 mPreviousProcess = null; 12539 } 12540 12541 if (restart && !app.isolated) { 12542 // We have components that still need to be running in the 12543 // process, so re-launch it. 12544 mProcessNames.put(app.processName, app.uid, app); 12545 startProcessLocked(app, "restart", app.processName); 12546 } else if (app.pid > 0 && app.pid != MY_PID) { 12547 // Goodbye! 12548 boolean removed; 12549 synchronized (mPidsSelfLocked) { 12550 mPidsSelfLocked.remove(app.pid); 12551 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12552 } 12553 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12554 app.processName, app.info.uid); 12555 if (app.isolated) { 12556 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12557 } 12558 app.setPid(0); 12559 } 12560 } 12561 12562 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12563 // Look through the content providers we are waiting to have launched, 12564 // and if any run in this process then either schedule a restart of 12565 // the process or kill the client waiting for it if this process has 12566 // gone bad. 12567 int NL = mLaunchingProviders.size(); 12568 boolean restart = false; 12569 for (int i=0; i<NL; i++) { 12570 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12571 if (cpr.launchingApp == app) { 12572 if (!alwaysBad && !app.bad) { 12573 restart = true; 12574 } else { 12575 removeDyingProviderLocked(app, cpr, true); 12576 // cpr should have been removed from mLaunchingProviders 12577 NL = mLaunchingProviders.size(); 12578 i--; 12579 } 12580 } 12581 } 12582 return restart; 12583 } 12584 12585 // ========================================================= 12586 // SERVICES 12587 // ========================================================= 12588 12589 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12590 int flags) { 12591 enforceNotIsolatedCaller("getServices"); 12592 synchronized (this) { 12593 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12594 } 12595 } 12596 12597 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12598 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12599 synchronized (this) { 12600 return mServices.getRunningServiceControlPanelLocked(name); 12601 } 12602 } 12603 12604 public ComponentName startService(IApplicationThread caller, Intent service, 12605 String resolvedType, int userId) { 12606 enforceNotIsolatedCaller("startService"); 12607 // Refuse possible leaked file descriptors 12608 if (service != null && service.hasFileDescriptors() == true) { 12609 throw new IllegalArgumentException("File descriptors passed in Intent"); 12610 } 12611 12612 if (DEBUG_SERVICE) 12613 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12614 synchronized(this) { 12615 final int callingPid = Binder.getCallingPid(); 12616 final int callingUid = Binder.getCallingUid(); 12617 final long origId = Binder.clearCallingIdentity(); 12618 ComponentName res = mServices.startServiceLocked(caller, service, 12619 resolvedType, callingPid, callingUid, userId); 12620 Binder.restoreCallingIdentity(origId); 12621 return res; 12622 } 12623 } 12624 12625 ComponentName startServiceInPackage(int uid, 12626 Intent service, String resolvedType, int userId) { 12627 synchronized(this) { 12628 if (DEBUG_SERVICE) 12629 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12630 final long origId = Binder.clearCallingIdentity(); 12631 ComponentName res = mServices.startServiceLocked(null, service, 12632 resolvedType, -1, uid, userId); 12633 Binder.restoreCallingIdentity(origId); 12634 return res; 12635 } 12636 } 12637 12638 public int stopService(IApplicationThread caller, Intent service, 12639 String resolvedType, int userId) { 12640 enforceNotIsolatedCaller("stopService"); 12641 // Refuse possible leaked file descriptors 12642 if (service != null && service.hasFileDescriptors() == true) { 12643 throw new IllegalArgumentException("File descriptors passed in Intent"); 12644 } 12645 12646 synchronized(this) { 12647 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12648 } 12649 } 12650 12651 public IBinder peekService(Intent service, String resolvedType) { 12652 enforceNotIsolatedCaller("peekService"); 12653 // Refuse possible leaked file descriptors 12654 if (service != null && service.hasFileDescriptors() == true) { 12655 throw new IllegalArgumentException("File descriptors passed in Intent"); 12656 } 12657 synchronized(this) { 12658 return mServices.peekServiceLocked(service, resolvedType); 12659 } 12660 } 12661 12662 public boolean stopServiceToken(ComponentName className, IBinder token, 12663 int startId) { 12664 synchronized(this) { 12665 return mServices.stopServiceTokenLocked(className, token, startId); 12666 } 12667 } 12668 12669 public void setServiceForeground(ComponentName className, IBinder token, 12670 int id, Notification notification, boolean removeNotification) { 12671 synchronized(this) { 12672 mServices.setServiceForegroundLocked(className, token, id, notification, 12673 removeNotification); 12674 } 12675 } 12676 12677 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12678 boolean requireFull, String name, String callerPackage) { 12679 final int callingUserId = UserHandle.getUserId(callingUid); 12680 if (callingUserId != userId) { 12681 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12682 if ((requireFull || checkComponentPermission( 12683 android.Manifest.permission.INTERACT_ACROSS_USERS, 12684 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12685 && checkComponentPermission( 12686 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12687 callingPid, callingUid, -1, true) 12688 != PackageManager.PERMISSION_GRANTED) { 12689 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12690 // In this case, they would like to just execute as their 12691 // owner user instead of failing. 12692 userId = callingUserId; 12693 } else { 12694 StringBuilder builder = new StringBuilder(128); 12695 builder.append("Permission Denial: "); 12696 builder.append(name); 12697 if (callerPackage != null) { 12698 builder.append(" from "); 12699 builder.append(callerPackage); 12700 } 12701 builder.append(" asks to run as user "); 12702 builder.append(userId); 12703 builder.append(" but is calling from user "); 12704 builder.append(UserHandle.getUserId(callingUid)); 12705 builder.append("; this requires "); 12706 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12707 if (!requireFull) { 12708 builder.append(" or "); 12709 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12710 } 12711 String msg = builder.toString(); 12712 Slog.w(TAG, msg); 12713 throw new SecurityException(msg); 12714 } 12715 } 12716 } 12717 if (userId == UserHandle.USER_CURRENT 12718 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12719 // Note that we may be accessing this outside of a lock... 12720 // shouldn't be a big deal, if this is being called outside 12721 // of a locked context there is intrinsically a race with 12722 // the value the caller will receive and someone else changing it. 12723 userId = mCurrentUserId; 12724 } 12725 if (!allowAll && userId < 0) { 12726 throw new IllegalArgumentException( 12727 "Call does not support special user #" + userId); 12728 } 12729 } 12730 return userId; 12731 } 12732 12733 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12734 String className, int flags) { 12735 boolean result = false; 12736 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12737 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12738 if (ActivityManager.checkUidPermission( 12739 android.Manifest.permission.INTERACT_ACROSS_USERS, 12740 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12741 ComponentName comp = new ComponentName(aInfo.packageName, className); 12742 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12743 + " requests FLAG_SINGLE_USER, but app does not hold " 12744 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12745 Slog.w(TAG, msg); 12746 throw new SecurityException(msg); 12747 } 12748 result = true; 12749 } 12750 } else if (componentProcessName == aInfo.packageName) { 12751 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12752 } else if ("system".equals(componentProcessName)) { 12753 result = true; 12754 } 12755 if (DEBUG_MU) { 12756 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12757 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12758 } 12759 return result; 12760 } 12761 12762 public int bindService(IApplicationThread caller, IBinder token, 12763 Intent service, String resolvedType, 12764 IServiceConnection connection, int flags, int userId) { 12765 enforceNotIsolatedCaller("bindService"); 12766 // Refuse possible leaked file descriptors 12767 if (service != null && service.hasFileDescriptors() == true) { 12768 throw new IllegalArgumentException("File descriptors passed in Intent"); 12769 } 12770 12771 synchronized(this) { 12772 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12773 connection, flags, userId); 12774 } 12775 } 12776 12777 public boolean unbindService(IServiceConnection connection) { 12778 synchronized (this) { 12779 return mServices.unbindServiceLocked(connection); 12780 } 12781 } 12782 12783 public void publishService(IBinder token, Intent intent, IBinder service) { 12784 // Refuse possible leaked file descriptors 12785 if (intent != null && intent.hasFileDescriptors() == true) { 12786 throw new IllegalArgumentException("File descriptors passed in Intent"); 12787 } 12788 12789 synchronized(this) { 12790 if (!(token instanceof ServiceRecord)) { 12791 throw new IllegalArgumentException("Invalid service token"); 12792 } 12793 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12794 } 12795 } 12796 12797 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12798 // Refuse possible leaked file descriptors 12799 if (intent != null && intent.hasFileDescriptors() == true) { 12800 throw new IllegalArgumentException("File descriptors passed in Intent"); 12801 } 12802 12803 synchronized(this) { 12804 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12805 } 12806 } 12807 12808 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12809 synchronized(this) { 12810 if (!(token instanceof ServiceRecord)) { 12811 throw new IllegalArgumentException("Invalid service token"); 12812 } 12813 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12814 } 12815 } 12816 12817 // ========================================================= 12818 // BACKUP AND RESTORE 12819 // ========================================================= 12820 12821 // Cause the target app to be launched if necessary and its backup agent 12822 // instantiated. The backup agent will invoke backupAgentCreated() on the 12823 // activity manager to announce its creation. 12824 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12825 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12826 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12827 12828 synchronized(this) { 12829 // !!! TODO: currently no check here that we're already bound 12830 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12831 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12832 synchronized (stats) { 12833 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12834 } 12835 12836 // Backup agent is now in use, its package can't be stopped. 12837 try { 12838 AppGlobals.getPackageManager().setPackageStoppedState( 12839 app.packageName, false, UserHandle.getUserId(app.uid)); 12840 } catch (RemoteException e) { 12841 } catch (IllegalArgumentException e) { 12842 Slog.w(TAG, "Failed trying to unstop package " 12843 + app.packageName + ": " + e); 12844 } 12845 12846 BackupRecord r = new BackupRecord(ss, app, backupMode); 12847 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12848 ? new ComponentName(app.packageName, app.backupAgentName) 12849 : new ComponentName("android", "FullBackupAgent"); 12850 // startProcessLocked() returns existing proc's record if it's already running 12851 ProcessRecord proc = startProcessLocked(app.processName, app, 12852 false, 0, "backup", hostingName, false, false, false); 12853 if (proc == null) { 12854 Slog.e(TAG, "Unable to start backup agent process " + r); 12855 return false; 12856 } 12857 12858 r.app = proc; 12859 mBackupTarget = r; 12860 mBackupAppName = app.packageName; 12861 12862 // Try not to kill the process during backup 12863 updateOomAdjLocked(proc); 12864 12865 // If the process is already attached, schedule the creation of the backup agent now. 12866 // If it is not yet live, this will be done when it attaches to the framework. 12867 if (proc.thread != null) { 12868 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12869 try { 12870 proc.thread.scheduleCreateBackupAgent(app, 12871 compatibilityInfoForPackageLocked(app), backupMode); 12872 } catch (RemoteException e) { 12873 // Will time out on the backup manager side 12874 } 12875 } else { 12876 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12877 } 12878 // Invariants: at this point, the target app process exists and the application 12879 // is either already running or in the process of coming up. mBackupTarget and 12880 // mBackupAppName describe the app, so that when it binds back to the AM we 12881 // know that it's scheduled for a backup-agent operation. 12882 } 12883 12884 return true; 12885 } 12886 12887 @Override 12888 public void clearPendingBackup() { 12889 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 12890 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 12891 12892 synchronized (this) { 12893 mBackupTarget = null; 12894 mBackupAppName = null; 12895 } 12896 } 12897 12898 // A backup agent has just come up 12899 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12900 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12901 + " = " + agent); 12902 12903 synchronized(this) { 12904 if (!agentPackageName.equals(mBackupAppName)) { 12905 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12906 return; 12907 } 12908 } 12909 12910 long oldIdent = Binder.clearCallingIdentity(); 12911 try { 12912 IBackupManager bm = IBackupManager.Stub.asInterface( 12913 ServiceManager.getService(Context.BACKUP_SERVICE)); 12914 bm.agentConnected(agentPackageName, agent); 12915 } catch (RemoteException e) { 12916 // can't happen; the backup manager service is local 12917 } catch (Exception e) { 12918 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12919 e.printStackTrace(); 12920 } finally { 12921 Binder.restoreCallingIdentity(oldIdent); 12922 } 12923 } 12924 12925 // done with this agent 12926 public void unbindBackupAgent(ApplicationInfo appInfo) { 12927 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12928 if (appInfo == null) { 12929 Slog.w(TAG, "unbind backup agent for null app"); 12930 return; 12931 } 12932 12933 synchronized(this) { 12934 try { 12935 if (mBackupAppName == null) { 12936 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12937 return; 12938 } 12939 12940 if (!mBackupAppName.equals(appInfo.packageName)) { 12941 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12942 return; 12943 } 12944 12945 // Not backing this app up any more; reset its OOM adjustment 12946 final ProcessRecord proc = mBackupTarget.app; 12947 updateOomAdjLocked(proc); 12948 12949 // If the app crashed during backup, 'thread' will be null here 12950 if (proc.thread != null) { 12951 try { 12952 proc.thread.scheduleDestroyBackupAgent(appInfo, 12953 compatibilityInfoForPackageLocked(appInfo)); 12954 } catch (Exception e) { 12955 Slog.e(TAG, "Exception when unbinding backup agent:"); 12956 e.printStackTrace(); 12957 } 12958 } 12959 } finally { 12960 mBackupTarget = null; 12961 mBackupAppName = null; 12962 } 12963 } 12964 } 12965 // ========================================================= 12966 // BROADCASTS 12967 // ========================================================= 12968 12969 private final List getStickiesLocked(String action, IntentFilter filter, 12970 List cur, int userId) { 12971 final ContentResolver resolver = mContext.getContentResolver(); 12972 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12973 if (stickies == null) { 12974 return cur; 12975 } 12976 final ArrayList<Intent> list = stickies.get(action); 12977 if (list == null) { 12978 return cur; 12979 } 12980 int N = list.size(); 12981 for (int i=0; i<N; i++) { 12982 Intent intent = list.get(i); 12983 if (filter.match(resolver, intent, true, TAG) >= 0) { 12984 if (cur == null) { 12985 cur = new ArrayList<Intent>(); 12986 } 12987 cur.add(intent); 12988 } 12989 } 12990 return cur; 12991 } 12992 12993 boolean isPendingBroadcastProcessLocked(int pid) { 12994 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12995 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12996 } 12997 12998 void skipPendingBroadcastLocked(int pid) { 12999 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13000 for (BroadcastQueue queue : mBroadcastQueues) { 13001 queue.skipPendingBroadcastLocked(pid); 13002 } 13003 } 13004 13005 // The app just attached; send any pending broadcasts that it should receive 13006 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13007 boolean didSomething = false; 13008 for (BroadcastQueue queue : mBroadcastQueues) { 13009 didSomething |= queue.sendPendingBroadcastsLocked(app); 13010 } 13011 return didSomething; 13012 } 13013 13014 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13015 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13016 enforceNotIsolatedCaller("registerReceiver"); 13017 int callingUid; 13018 int callingPid; 13019 synchronized(this) { 13020 ProcessRecord callerApp = null; 13021 if (caller != null) { 13022 callerApp = getRecordForAppLocked(caller); 13023 if (callerApp == null) { 13024 throw new SecurityException( 13025 "Unable to find app for caller " + caller 13026 + " (pid=" + Binder.getCallingPid() 13027 + ") when registering receiver " + receiver); 13028 } 13029 if (callerApp.info.uid != Process.SYSTEM_UID && 13030 !callerApp.pkgList.containsKey(callerPackage) && 13031 !"android".equals(callerPackage)) { 13032 throw new SecurityException("Given caller package " + callerPackage 13033 + " is not running in process " + callerApp); 13034 } 13035 callingUid = callerApp.info.uid; 13036 callingPid = callerApp.pid; 13037 } else { 13038 callerPackage = null; 13039 callingUid = Binder.getCallingUid(); 13040 callingPid = Binder.getCallingPid(); 13041 } 13042 13043 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13044 true, true, "registerReceiver", callerPackage); 13045 13046 List allSticky = null; 13047 13048 // Look for any matching sticky broadcasts... 13049 Iterator actions = filter.actionsIterator(); 13050 if (actions != null) { 13051 while (actions.hasNext()) { 13052 String action = (String)actions.next(); 13053 allSticky = getStickiesLocked(action, filter, allSticky, 13054 UserHandle.USER_ALL); 13055 allSticky = getStickiesLocked(action, filter, allSticky, 13056 UserHandle.getUserId(callingUid)); 13057 } 13058 } else { 13059 allSticky = getStickiesLocked(null, filter, allSticky, 13060 UserHandle.USER_ALL); 13061 allSticky = getStickiesLocked(null, filter, allSticky, 13062 UserHandle.getUserId(callingUid)); 13063 } 13064 13065 // The first sticky in the list is returned directly back to 13066 // the client. 13067 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13068 13069 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13070 + ": " + sticky); 13071 13072 if (receiver == null) { 13073 return sticky; 13074 } 13075 13076 ReceiverList rl 13077 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13078 if (rl == null) { 13079 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13080 userId, receiver); 13081 if (rl.app != null) { 13082 rl.app.receivers.add(rl); 13083 } else { 13084 try { 13085 receiver.asBinder().linkToDeath(rl, 0); 13086 } catch (RemoteException e) { 13087 return sticky; 13088 } 13089 rl.linkedToDeath = true; 13090 } 13091 mRegisteredReceivers.put(receiver.asBinder(), rl); 13092 } else if (rl.uid != callingUid) { 13093 throw new IllegalArgumentException( 13094 "Receiver requested to register for uid " + callingUid 13095 + " was previously registered for uid " + rl.uid); 13096 } else if (rl.pid != callingPid) { 13097 throw new IllegalArgumentException( 13098 "Receiver requested to register for pid " + callingPid 13099 + " was previously registered for pid " + rl.pid); 13100 } else if (rl.userId != userId) { 13101 throw new IllegalArgumentException( 13102 "Receiver requested to register for user " + userId 13103 + " was previously registered for user " + rl.userId); 13104 } 13105 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13106 permission, callingUid, userId); 13107 rl.add(bf); 13108 if (!bf.debugCheck()) { 13109 Slog.w(TAG, "==> For Dynamic broadast"); 13110 } 13111 mReceiverResolver.addFilter(bf); 13112 13113 // Enqueue broadcasts for all existing stickies that match 13114 // this filter. 13115 if (allSticky != null) { 13116 ArrayList receivers = new ArrayList(); 13117 receivers.add(bf); 13118 13119 int N = allSticky.size(); 13120 for (int i=0; i<N; i++) { 13121 Intent intent = (Intent)allSticky.get(i); 13122 BroadcastQueue queue = broadcastQueueForIntent(intent); 13123 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13124 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13125 null, null, false, true, true, -1); 13126 queue.enqueueParallelBroadcastLocked(r); 13127 queue.scheduleBroadcastsLocked(); 13128 } 13129 } 13130 13131 return sticky; 13132 } 13133 } 13134 13135 public void unregisterReceiver(IIntentReceiver receiver) { 13136 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13137 13138 final long origId = Binder.clearCallingIdentity(); 13139 try { 13140 boolean doTrim = false; 13141 13142 synchronized(this) { 13143 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13144 if (rl != null) { 13145 if (rl.curBroadcast != null) { 13146 BroadcastRecord r = rl.curBroadcast; 13147 final boolean doNext = finishReceiverLocked( 13148 receiver.asBinder(), r.resultCode, r.resultData, 13149 r.resultExtras, r.resultAbort); 13150 if (doNext) { 13151 doTrim = true; 13152 r.queue.processNextBroadcast(false); 13153 } 13154 } 13155 13156 if (rl.app != null) { 13157 rl.app.receivers.remove(rl); 13158 } 13159 removeReceiverLocked(rl); 13160 if (rl.linkedToDeath) { 13161 rl.linkedToDeath = false; 13162 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13163 } 13164 } 13165 } 13166 13167 // If we actually concluded any broadcasts, we might now be able 13168 // to trim the recipients' apps from our working set 13169 if (doTrim) { 13170 trimApplications(); 13171 return; 13172 } 13173 13174 } finally { 13175 Binder.restoreCallingIdentity(origId); 13176 } 13177 } 13178 13179 void removeReceiverLocked(ReceiverList rl) { 13180 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13181 int N = rl.size(); 13182 for (int i=0; i<N; i++) { 13183 mReceiverResolver.removeFilter(rl.get(i)); 13184 } 13185 } 13186 13187 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13188 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13189 ProcessRecord r = mLruProcesses.get(i); 13190 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13191 try { 13192 r.thread.dispatchPackageBroadcast(cmd, packages); 13193 } catch (RemoteException ex) { 13194 } 13195 } 13196 } 13197 } 13198 13199 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13200 int[] users) { 13201 List<ResolveInfo> receivers = null; 13202 try { 13203 HashSet<ComponentName> singleUserReceivers = null; 13204 boolean scannedFirstReceivers = false; 13205 for (int user : users) { 13206 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13207 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13208 if (user != 0 && newReceivers != null) { 13209 // If this is not the primary user, we need to check for 13210 // any receivers that should be filtered out. 13211 for (int i=0; i<newReceivers.size(); i++) { 13212 ResolveInfo ri = newReceivers.get(i); 13213 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13214 newReceivers.remove(i); 13215 i--; 13216 } 13217 } 13218 } 13219 if (newReceivers != null && newReceivers.size() == 0) { 13220 newReceivers = null; 13221 } 13222 if (receivers == null) { 13223 receivers = newReceivers; 13224 } else if (newReceivers != null) { 13225 // We need to concatenate the additional receivers 13226 // found with what we have do far. This would be easy, 13227 // but we also need to de-dup any receivers that are 13228 // singleUser. 13229 if (!scannedFirstReceivers) { 13230 // Collect any single user receivers we had already retrieved. 13231 scannedFirstReceivers = true; 13232 for (int i=0; i<receivers.size(); i++) { 13233 ResolveInfo ri = receivers.get(i); 13234 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13235 ComponentName cn = new ComponentName( 13236 ri.activityInfo.packageName, ri.activityInfo.name); 13237 if (singleUserReceivers == null) { 13238 singleUserReceivers = new HashSet<ComponentName>(); 13239 } 13240 singleUserReceivers.add(cn); 13241 } 13242 } 13243 } 13244 // Add the new results to the existing results, tracking 13245 // and de-dupping single user receivers. 13246 for (int i=0; i<newReceivers.size(); i++) { 13247 ResolveInfo ri = newReceivers.get(i); 13248 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13249 ComponentName cn = new ComponentName( 13250 ri.activityInfo.packageName, ri.activityInfo.name); 13251 if (singleUserReceivers == null) { 13252 singleUserReceivers = new HashSet<ComponentName>(); 13253 } 13254 if (!singleUserReceivers.contains(cn)) { 13255 singleUserReceivers.add(cn); 13256 receivers.add(ri); 13257 } 13258 } else { 13259 receivers.add(ri); 13260 } 13261 } 13262 } 13263 } 13264 } catch (RemoteException ex) { 13265 // pm is in same process, this will never happen. 13266 } 13267 return receivers; 13268 } 13269 13270 private final int broadcastIntentLocked(ProcessRecord callerApp, 13271 String callerPackage, Intent intent, String resolvedType, 13272 IIntentReceiver resultTo, int resultCode, String resultData, 13273 Bundle map, String requiredPermission, int appOp, 13274 boolean ordered, boolean sticky, int callingPid, int callingUid, 13275 int userId) { 13276 intent = new Intent(intent); 13277 13278 // By default broadcasts do not go to stopped apps. 13279 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13280 13281 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13282 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13283 + " ordered=" + ordered + " userid=" + userId); 13284 if ((resultTo != null) && !ordered) { 13285 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13286 } 13287 13288 userId = handleIncomingUser(callingPid, callingUid, userId, 13289 true, false, "broadcast", callerPackage); 13290 13291 // Make sure that the user who is receiving this broadcast is started. 13292 // If not, we will just skip it. 13293 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13294 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13295 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13296 Slog.w(TAG, "Skipping broadcast of " + intent 13297 + ": user " + userId + " is stopped"); 13298 return ActivityManager.BROADCAST_SUCCESS; 13299 } 13300 } 13301 13302 /* 13303 * Prevent non-system code (defined here to be non-persistent 13304 * processes) from sending protected broadcasts. 13305 */ 13306 int callingAppId = UserHandle.getAppId(callingUid); 13307 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13308 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13309 callingUid == 0) { 13310 // Always okay. 13311 } else if (callerApp == null || !callerApp.persistent) { 13312 try { 13313 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13314 intent.getAction())) { 13315 String msg = "Permission Denial: not allowed to send broadcast " 13316 + intent.getAction() + " from pid=" 13317 + callingPid + ", uid=" + callingUid; 13318 Slog.w(TAG, msg); 13319 throw new SecurityException(msg); 13320 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13321 // Special case for compatibility: we don't want apps to send this, 13322 // but historically it has not been protected and apps may be using it 13323 // to poke their own app widget. So, instead of making it protected, 13324 // just limit it to the caller. 13325 if (callerApp == null) { 13326 String msg = "Permission Denial: not allowed to send broadcast " 13327 + intent.getAction() + " from unknown caller."; 13328 Slog.w(TAG, msg); 13329 throw new SecurityException(msg); 13330 } else if (intent.getComponent() != null) { 13331 // They are good enough to send to an explicit component... verify 13332 // it is being sent to the calling app. 13333 if (!intent.getComponent().getPackageName().equals( 13334 callerApp.info.packageName)) { 13335 String msg = "Permission Denial: not allowed to send broadcast " 13336 + intent.getAction() + " to " 13337 + intent.getComponent().getPackageName() + " from " 13338 + callerApp.info.packageName; 13339 Slog.w(TAG, msg); 13340 throw new SecurityException(msg); 13341 } 13342 } else { 13343 // Limit broadcast to their own package. 13344 intent.setPackage(callerApp.info.packageName); 13345 } 13346 } 13347 } catch (RemoteException e) { 13348 Slog.w(TAG, "Remote exception", e); 13349 return ActivityManager.BROADCAST_SUCCESS; 13350 } 13351 } 13352 13353 // Handle special intents: if this broadcast is from the package 13354 // manager about a package being removed, we need to remove all of 13355 // its activities from the history stack. 13356 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13357 intent.getAction()); 13358 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13359 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13360 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13361 || uidRemoved) { 13362 if (checkComponentPermission( 13363 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13364 callingPid, callingUid, -1, true) 13365 == PackageManager.PERMISSION_GRANTED) { 13366 if (uidRemoved) { 13367 final Bundle intentExtras = intent.getExtras(); 13368 final int uid = intentExtras != null 13369 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13370 if (uid >= 0) { 13371 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13372 synchronized (bs) { 13373 bs.removeUidStatsLocked(uid); 13374 } 13375 mAppOpsService.uidRemoved(uid); 13376 } 13377 } else { 13378 // If resources are unavailable just force stop all 13379 // those packages and flush the attribute cache as well. 13380 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13381 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13382 if (list != null && (list.length > 0)) { 13383 for (String pkg : list) { 13384 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13385 "storage unmount"); 13386 } 13387 sendPackageBroadcastLocked( 13388 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13389 } 13390 } else { 13391 Uri data = intent.getData(); 13392 String ssp; 13393 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13394 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13395 intent.getAction()); 13396 boolean fullUninstall = removed && 13397 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13398 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13399 forceStopPackageLocked(ssp, UserHandle.getAppId( 13400 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13401 false, fullUninstall, userId, 13402 removed ? "pkg removed" : "pkg changed"); 13403 } 13404 if (removed) { 13405 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13406 new String[] {ssp}, userId); 13407 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13408 mAppOpsService.packageRemoved( 13409 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13410 13411 // Remove all permissions granted from/to this package 13412 removeUriPermissionsForPackageLocked(ssp, userId, true); 13413 } 13414 } 13415 } 13416 } 13417 } 13418 } else { 13419 String msg = "Permission Denial: " + intent.getAction() 13420 + " broadcast from " + callerPackage + " (pid=" + callingPid 13421 + ", uid=" + callingUid + ")" 13422 + " requires " 13423 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13424 Slog.w(TAG, msg); 13425 throw new SecurityException(msg); 13426 } 13427 13428 // Special case for adding a package: by default turn on compatibility 13429 // mode. 13430 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13431 Uri data = intent.getData(); 13432 String ssp; 13433 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13434 mCompatModePackages.handlePackageAddedLocked(ssp, 13435 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13436 } 13437 } 13438 13439 /* 13440 * If this is the time zone changed action, queue up a message that will reset the timezone 13441 * of all currently running processes. This message will get queued up before the broadcast 13442 * happens. 13443 */ 13444 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13445 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13446 } 13447 13448 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13449 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13450 } 13451 13452 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13453 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13454 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13455 } 13456 13457 // Add to the sticky list if requested. 13458 if (sticky) { 13459 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13460 callingPid, callingUid) 13461 != PackageManager.PERMISSION_GRANTED) { 13462 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13463 + callingPid + ", uid=" + callingUid 13464 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13465 Slog.w(TAG, msg); 13466 throw new SecurityException(msg); 13467 } 13468 if (requiredPermission != null) { 13469 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13470 + " and enforce permission " + requiredPermission); 13471 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13472 } 13473 if (intent.getComponent() != null) { 13474 throw new SecurityException( 13475 "Sticky broadcasts can't target a specific component"); 13476 } 13477 // We use userId directly here, since the "all" target is maintained 13478 // as a separate set of sticky broadcasts. 13479 if (userId != UserHandle.USER_ALL) { 13480 // But first, if this is not a broadcast to all users, then 13481 // make sure it doesn't conflict with an existing broadcast to 13482 // all users. 13483 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13484 UserHandle.USER_ALL); 13485 if (stickies != null) { 13486 ArrayList<Intent> list = stickies.get(intent.getAction()); 13487 if (list != null) { 13488 int N = list.size(); 13489 int i; 13490 for (i=0; i<N; i++) { 13491 if (intent.filterEquals(list.get(i))) { 13492 throw new IllegalArgumentException( 13493 "Sticky broadcast " + intent + " for user " 13494 + userId + " conflicts with existing global broadcast"); 13495 } 13496 } 13497 } 13498 } 13499 } 13500 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13501 if (stickies == null) { 13502 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13503 mStickyBroadcasts.put(userId, stickies); 13504 } 13505 ArrayList<Intent> list = stickies.get(intent.getAction()); 13506 if (list == null) { 13507 list = new ArrayList<Intent>(); 13508 stickies.put(intent.getAction(), list); 13509 } 13510 int N = list.size(); 13511 int i; 13512 for (i=0; i<N; i++) { 13513 if (intent.filterEquals(list.get(i))) { 13514 // This sticky already exists, replace it. 13515 list.set(i, new Intent(intent)); 13516 break; 13517 } 13518 } 13519 if (i >= N) { 13520 list.add(new Intent(intent)); 13521 } 13522 } 13523 13524 int[] users; 13525 if (userId == UserHandle.USER_ALL) { 13526 // Caller wants broadcast to go to all started users. 13527 users = mStartedUserArray; 13528 } else { 13529 // Caller wants broadcast to go to one specific user. 13530 users = new int[] {userId}; 13531 } 13532 13533 // Figure out who all will receive this broadcast. 13534 List receivers = null; 13535 List<BroadcastFilter> registeredReceivers = null; 13536 // Need to resolve the intent to interested receivers... 13537 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13538 == 0) { 13539 receivers = collectReceiverComponents(intent, resolvedType, users); 13540 } 13541 if (intent.getComponent() == null) { 13542 registeredReceivers = mReceiverResolver.queryIntent(intent, 13543 resolvedType, false, userId); 13544 } 13545 13546 final boolean replacePending = 13547 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13548 13549 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13550 + " replacePending=" + replacePending); 13551 13552 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13553 if (!ordered && NR > 0) { 13554 // If we are not serializing this broadcast, then send the 13555 // registered receivers separately so they don't wait for the 13556 // components to be launched. 13557 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13558 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13559 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13560 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13561 ordered, sticky, false, userId); 13562 if (DEBUG_BROADCAST) Slog.v( 13563 TAG, "Enqueueing parallel broadcast " + r); 13564 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13565 if (!replaced) { 13566 queue.enqueueParallelBroadcastLocked(r); 13567 queue.scheduleBroadcastsLocked(); 13568 } 13569 registeredReceivers = null; 13570 NR = 0; 13571 } 13572 13573 // Merge into one list. 13574 int ir = 0; 13575 if (receivers != null) { 13576 // A special case for PACKAGE_ADDED: do not allow the package 13577 // being added to see this broadcast. This prevents them from 13578 // using this as a back door to get run as soon as they are 13579 // installed. Maybe in the future we want to have a special install 13580 // broadcast or such for apps, but we'd like to deliberately make 13581 // this decision. 13582 String skipPackages[] = null; 13583 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13584 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13585 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13586 Uri data = intent.getData(); 13587 if (data != null) { 13588 String pkgName = data.getSchemeSpecificPart(); 13589 if (pkgName != null) { 13590 skipPackages = new String[] { pkgName }; 13591 } 13592 } 13593 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13594 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13595 } 13596 if (skipPackages != null && (skipPackages.length > 0)) { 13597 for (String skipPackage : skipPackages) { 13598 if (skipPackage != null) { 13599 int NT = receivers.size(); 13600 for (int it=0; it<NT; it++) { 13601 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13602 if (curt.activityInfo.packageName.equals(skipPackage)) { 13603 receivers.remove(it); 13604 it--; 13605 NT--; 13606 } 13607 } 13608 } 13609 } 13610 } 13611 13612 int NT = receivers != null ? receivers.size() : 0; 13613 int it = 0; 13614 ResolveInfo curt = null; 13615 BroadcastFilter curr = null; 13616 while (it < NT && ir < NR) { 13617 if (curt == null) { 13618 curt = (ResolveInfo)receivers.get(it); 13619 } 13620 if (curr == null) { 13621 curr = registeredReceivers.get(ir); 13622 } 13623 if (curr.getPriority() >= curt.priority) { 13624 // Insert this broadcast record into the final list. 13625 receivers.add(it, curr); 13626 ir++; 13627 curr = null; 13628 it++; 13629 NT++; 13630 } else { 13631 // Skip to the next ResolveInfo in the final list. 13632 it++; 13633 curt = null; 13634 } 13635 } 13636 } 13637 while (ir < NR) { 13638 if (receivers == null) { 13639 receivers = new ArrayList(); 13640 } 13641 receivers.add(registeredReceivers.get(ir)); 13642 ir++; 13643 } 13644 13645 if ((receivers != null && receivers.size() > 0) 13646 || resultTo != null) { 13647 BroadcastQueue queue = broadcastQueueForIntent(intent); 13648 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13649 callerPackage, callingPid, callingUid, resolvedType, 13650 requiredPermission, appOp, receivers, resultTo, resultCode, 13651 resultData, map, ordered, sticky, false, userId); 13652 if (DEBUG_BROADCAST) Slog.v( 13653 TAG, "Enqueueing ordered broadcast " + r 13654 + ": prev had " + queue.mOrderedBroadcasts.size()); 13655 if (DEBUG_BROADCAST) { 13656 int seq = r.intent.getIntExtra("seq", -1); 13657 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13658 } 13659 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13660 if (!replaced) { 13661 queue.enqueueOrderedBroadcastLocked(r); 13662 queue.scheduleBroadcastsLocked(); 13663 } 13664 } 13665 13666 return ActivityManager.BROADCAST_SUCCESS; 13667 } 13668 13669 final Intent verifyBroadcastLocked(Intent intent) { 13670 // Refuse possible leaked file descriptors 13671 if (intent != null && intent.hasFileDescriptors() == true) { 13672 throw new IllegalArgumentException("File descriptors passed in Intent"); 13673 } 13674 13675 int flags = intent.getFlags(); 13676 13677 if (!mProcessesReady) { 13678 // if the caller really truly claims to know what they're doing, go 13679 // ahead and allow the broadcast without launching any receivers 13680 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13681 intent = new Intent(intent); 13682 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13683 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13684 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13685 + " before boot completion"); 13686 throw new IllegalStateException("Cannot broadcast before boot completed"); 13687 } 13688 } 13689 13690 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13691 throw new IllegalArgumentException( 13692 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13693 } 13694 13695 return intent; 13696 } 13697 13698 public final int broadcastIntent(IApplicationThread caller, 13699 Intent intent, String resolvedType, IIntentReceiver resultTo, 13700 int resultCode, String resultData, Bundle map, 13701 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13702 enforceNotIsolatedCaller("broadcastIntent"); 13703 synchronized(this) { 13704 intent = verifyBroadcastLocked(intent); 13705 13706 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13707 final int callingPid = Binder.getCallingPid(); 13708 final int callingUid = Binder.getCallingUid(); 13709 final long origId = Binder.clearCallingIdentity(); 13710 int res = broadcastIntentLocked(callerApp, 13711 callerApp != null ? callerApp.info.packageName : null, 13712 intent, resolvedType, resultTo, 13713 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13714 callingPid, callingUid, userId); 13715 Binder.restoreCallingIdentity(origId); 13716 return res; 13717 } 13718 } 13719 13720 int broadcastIntentInPackage(String packageName, int uid, 13721 Intent intent, String resolvedType, IIntentReceiver resultTo, 13722 int resultCode, String resultData, Bundle map, 13723 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13724 synchronized(this) { 13725 intent = verifyBroadcastLocked(intent); 13726 13727 final long origId = Binder.clearCallingIdentity(); 13728 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13729 resultTo, resultCode, resultData, map, requiredPermission, 13730 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13731 Binder.restoreCallingIdentity(origId); 13732 return res; 13733 } 13734 } 13735 13736 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13737 // Refuse possible leaked file descriptors 13738 if (intent != null && intent.hasFileDescriptors() == true) { 13739 throw new IllegalArgumentException("File descriptors passed in Intent"); 13740 } 13741 13742 userId = handleIncomingUser(Binder.getCallingPid(), 13743 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13744 13745 synchronized(this) { 13746 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13747 != PackageManager.PERMISSION_GRANTED) { 13748 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13749 + Binder.getCallingPid() 13750 + ", uid=" + Binder.getCallingUid() 13751 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13752 Slog.w(TAG, msg); 13753 throw new SecurityException(msg); 13754 } 13755 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13756 if (stickies != null) { 13757 ArrayList<Intent> list = stickies.get(intent.getAction()); 13758 if (list != null) { 13759 int N = list.size(); 13760 int i; 13761 for (i=0; i<N; i++) { 13762 if (intent.filterEquals(list.get(i))) { 13763 list.remove(i); 13764 break; 13765 } 13766 } 13767 if (list.size() <= 0) { 13768 stickies.remove(intent.getAction()); 13769 } 13770 } 13771 if (stickies.size() <= 0) { 13772 mStickyBroadcasts.remove(userId); 13773 } 13774 } 13775 } 13776 } 13777 13778 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13779 String resultData, Bundle resultExtras, boolean resultAbort) { 13780 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13781 if (r == null) { 13782 Slog.w(TAG, "finishReceiver called but not found on queue"); 13783 return false; 13784 } 13785 13786 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13787 } 13788 13789 void backgroundServicesFinishedLocked(int userId) { 13790 for (BroadcastQueue queue : mBroadcastQueues) { 13791 queue.backgroundServicesFinishedLocked(userId); 13792 } 13793 } 13794 13795 public void finishReceiver(IBinder who, int resultCode, String resultData, 13796 Bundle resultExtras, boolean resultAbort) { 13797 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13798 13799 // Refuse possible leaked file descriptors 13800 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13801 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13802 } 13803 13804 final long origId = Binder.clearCallingIdentity(); 13805 try { 13806 boolean doNext = false; 13807 BroadcastRecord r; 13808 13809 synchronized(this) { 13810 r = broadcastRecordForReceiverLocked(who); 13811 if (r != null) { 13812 doNext = r.queue.finishReceiverLocked(r, resultCode, 13813 resultData, resultExtras, resultAbort, true); 13814 } 13815 } 13816 13817 if (doNext) { 13818 r.queue.processNextBroadcast(false); 13819 } 13820 trimApplications(); 13821 } finally { 13822 Binder.restoreCallingIdentity(origId); 13823 } 13824 } 13825 13826 // ========================================================= 13827 // INSTRUMENTATION 13828 // ========================================================= 13829 13830 public boolean startInstrumentation(ComponentName className, 13831 String profileFile, int flags, Bundle arguments, 13832 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13833 int userId) { 13834 enforceNotIsolatedCaller("startInstrumentation"); 13835 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13836 userId, false, true, "startInstrumentation", null); 13837 // Refuse possible leaked file descriptors 13838 if (arguments != null && arguments.hasFileDescriptors()) { 13839 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13840 } 13841 13842 synchronized(this) { 13843 InstrumentationInfo ii = null; 13844 ApplicationInfo ai = null; 13845 try { 13846 ii = mContext.getPackageManager().getInstrumentationInfo( 13847 className, STOCK_PM_FLAGS); 13848 ai = AppGlobals.getPackageManager().getApplicationInfo( 13849 ii.targetPackage, STOCK_PM_FLAGS, userId); 13850 } catch (PackageManager.NameNotFoundException e) { 13851 } catch (RemoteException e) { 13852 } 13853 if (ii == null) { 13854 reportStartInstrumentationFailure(watcher, className, 13855 "Unable to find instrumentation info for: " + className); 13856 return false; 13857 } 13858 if (ai == null) { 13859 reportStartInstrumentationFailure(watcher, className, 13860 "Unable to find instrumentation target package: " + ii.targetPackage); 13861 return false; 13862 } 13863 13864 int match = mContext.getPackageManager().checkSignatures( 13865 ii.targetPackage, ii.packageName); 13866 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13867 String msg = "Permission Denial: starting instrumentation " 13868 + className + " from pid=" 13869 + Binder.getCallingPid() 13870 + ", uid=" + Binder.getCallingPid() 13871 + " not allowed because package " + ii.packageName 13872 + " does not have a signature matching the target " 13873 + ii.targetPackage; 13874 reportStartInstrumentationFailure(watcher, className, msg); 13875 throw new SecurityException(msg); 13876 } 13877 13878 final long origId = Binder.clearCallingIdentity(); 13879 // Instrumentation can kill and relaunch even persistent processes 13880 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 13881 "start instr"); 13882 ProcessRecord app = addAppLocked(ai, false); 13883 app.instrumentationClass = className; 13884 app.instrumentationInfo = ai; 13885 app.instrumentationProfileFile = profileFile; 13886 app.instrumentationArguments = arguments; 13887 app.instrumentationWatcher = watcher; 13888 app.instrumentationUiAutomationConnection = uiAutomationConnection; 13889 app.instrumentationResultClass = className; 13890 Binder.restoreCallingIdentity(origId); 13891 } 13892 13893 return true; 13894 } 13895 13896 /** 13897 * Report errors that occur while attempting to start Instrumentation. Always writes the 13898 * error to the logs, but if somebody is watching, send the report there too. This enables 13899 * the "am" command to report errors with more information. 13900 * 13901 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13902 * @param cn The component name of the instrumentation. 13903 * @param report The error report. 13904 */ 13905 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13906 ComponentName cn, String report) { 13907 Slog.w(TAG, report); 13908 try { 13909 if (watcher != null) { 13910 Bundle results = new Bundle(); 13911 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13912 results.putString("Error", report); 13913 watcher.instrumentationStatus(cn, -1, results); 13914 } 13915 } catch (RemoteException e) { 13916 Slog.w(TAG, e); 13917 } 13918 } 13919 13920 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13921 if (app.instrumentationWatcher != null) { 13922 try { 13923 // NOTE: IInstrumentationWatcher *must* be oneway here 13924 app.instrumentationWatcher.instrumentationFinished( 13925 app.instrumentationClass, 13926 resultCode, 13927 results); 13928 } catch (RemoteException e) { 13929 } 13930 } 13931 if (app.instrumentationUiAutomationConnection != null) { 13932 try { 13933 app.instrumentationUiAutomationConnection.shutdown(); 13934 } catch (RemoteException re) { 13935 /* ignore */ 13936 } 13937 // Only a UiAutomation can set this flag and now that 13938 // it is finished we make sure it is reset to its default. 13939 mUserIsMonkey = false; 13940 } 13941 app.instrumentationWatcher = null; 13942 app.instrumentationUiAutomationConnection = null; 13943 app.instrumentationClass = null; 13944 app.instrumentationInfo = null; 13945 app.instrumentationProfileFile = null; 13946 app.instrumentationArguments = null; 13947 13948 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 13949 "finished inst"); 13950 } 13951 13952 public void finishInstrumentation(IApplicationThread target, 13953 int resultCode, Bundle results) { 13954 int userId = UserHandle.getCallingUserId(); 13955 // Refuse possible leaked file descriptors 13956 if (results != null && results.hasFileDescriptors()) { 13957 throw new IllegalArgumentException("File descriptors passed in Intent"); 13958 } 13959 13960 synchronized(this) { 13961 ProcessRecord app = getRecordForAppLocked(target); 13962 if (app == null) { 13963 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13964 return; 13965 } 13966 final long origId = Binder.clearCallingIdentity(); 13967 finishInstrumentationLocked(app, resultCode, results); 13968 Binder.restoreCallingIdentity(origId); 13969 } 13970 } 13971 13972 // ========================================================= 13973 // CONFIGURATION 13974 // ========================================================= 13975 13976 public ConfigurationInfo getDeviceConfigurationInfo() { 13977 ConfigurationInfo config = new ConfigurationInfo(); 13978 synchronized (this) { 13979 config.reqTouchScreen = mConfiguration.touchscreen; 13980 config.reqKeyboardType = mConfiguration.keyboard; 13981 config.reqNavigation = mConfiguration.navigation; 13982 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13983 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13984 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13985 } 13986 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13987 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13988 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13989 } 13990 config.reqGlEsVersion = GL_ES_VERSION; 13991 } 13992 return config; 13993 } 13994 13995 ActivityStack getFocusedStack() { 13996 return mStackSupervisor.getFocusedStack(); 13997 } 13998 13999 public Configuration getConfiguration() { 14000 Configuration ci; 14001 synchronized(this) { 14002 ci = new Configuration(mConfiguration); 14003 } 14004 return ci; 14005 } 14006 14007 public void updatePersistentConfiguration(Configuration values) { 14008 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14009 "updateConfiguration()"); 14010 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14011 "updateConfiguration()"); 14012 if (values == null) { 14013 throw new NullPointerException("Configuration must not be null"); 14014 } 14015 14016 synchronized(this) { 14017 final long origId = Binder.clearCallingIdentity(); 14018 updateConfigurationLocked(values, null, true, false); 14019 Binder.restoreCallingIdentity(origId); 14020 } 14021 } 14022 14023 public void updateConfiguration(Configuration values) { 14024 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14025 "updateConfiguration()"); 14026 14027 synchronized(this) { 14028 if (values == null && mWindowManager != null) { 14029 // sentinel: fetch the current configuration from the window manager 14030 values = mWindowManager.computeNewConfiguration(); 14031 } 14032 14033 if (mWindowManager != null) { 14034 mProcessList.applyDisplaySize(mWindowManager); 14035 } 14036 14037 final long origId = Binder.clearCallingIdentity(); 14038 if (values != null) { 14039 Settings.System.clearConfiguration(values); 14040 } 14041 updateConfigurationLocked(values, null, false, false); 14042 Binder.restoreCallingIdentity(origId); 14043 } 14044 } 14045 14046 /** 14047 * Do either or both things: (1) change the current configuration, and (2) 14048 * make sure the given activity is running with the (now) current 14049 * configuration. Returns true if the activity has been left running, or 14050 * false if <var>starting</var> is being destroyed to match the new 14051 * configuration. 14052 * @param persistent TODO 14053 */ 14054 boolean updateConfigurationLocked(Configuration values, 14055 ActivityRecord starting, boolean persistent, boolean initLocale) { 14056 int changes = 0; 14057 14058 if (values != null) { 14059 Configuration newConfig = new Configuration(mConfiguration); 14060 changes = newConfig.updateFrom(values); 14061 if (changes != 0) { 14062 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14063 Slog.i(TAG, "Updating configuration to: " + values); 14064 } 14065 14066 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14067 14068 if (values.locale != null && !initLocale) { 14069 saveLocaleLocked(values.locale, 14070 !values.locale.equals(mConfiguration.locale), 14071 values.userSetLocale); 14072 } 14073 14074 mConfigurationSeq++; 14075 if (mConfigurationSeq <= 0) { 14076 mConfigurationSeq = 1; 14077 } 14078 newConfig.seq = mConfigurationSeq; 14079 mConfiguration = newConfig; 14080 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14081 14082 final Configuration configCopy = new Configuration(mConfiguration); 14083 14084 // TODO: If our config changes, should we auto dismiss any currently 14085 // showing dialogs? 14086 mShowDialogs = shouldShowDialogs(newConfig); 14087 14088 AttributeCache ac = AttributeCache.instance(); 14089 if (ac != null) { 14090 ac.updateConfiguration(configCopy); 14091 } 14092 14093 // Make sure all resources in our process are updated 14094 // right now, so that anyone who is going to retrieve 14095 // resource values after we return will be sure to get 14096 // the new ones. This is especially important during 14097 // boot, where the first config change needs to guarantee 14098 // all resources have that config before following boot 14099 // code is executed. 14100 mSystemThread.applyConfigurationToResources(configCopy); 14101 14102 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14103 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14104 msg.obj = new Configuration(configCopy); 14105 mHandler.sendMessage(msg); 14106 } 14107 14108 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14109 ProcessRecord app = mLruProcesses.get(i); 14110 try { 14111 if (app.thread != null) { 14112 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14113 + app.processName + " new config " + mConfiguration); 14114 app.thread.scheduleConfigurationChanged(configCopy); 14115 } 14116 } catch (Exception e) { 14117 } 14118 } 14119 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14120 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14121 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14122 | Intent.FLAG_RECEIVER_FOREGROUND); 14123 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14124 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14125 Process.SYSTEM_UID, UserHandle.USER_ALL); 14126 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14127 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14128 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14129 broadcastIntentLocked(null, null, intent, 14130 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14131 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14132 } 14133 } 14134 } 14135 14136 boolean kept = true; 14137 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14138 // mainStack is null during startup. 14139 if (mainStack != null) { 14140 if (changes != 0 && starting == null) { 14141 // If the configuration changed, and the caller is not already 14142 // in the process of starting an activity, then find the top 14143 // activity to check if its configuration needs to change. 14144 starting = mainStack.topRunningActivityLocked(null); 14145 } 14146 14147 if (starting != null) { 14148 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14149 // And we need to make sure at this point that all other activities 14150 // are made visible with the correct configuration. 14151 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14152 } 14153 } 14154 14155 if (values != null && mWindowManager != null) { 14156 mWindowManager.setNewConfiguration(mConfiguration); 14157 } 14158 14159 return kept; 14160 } 14161 14162 /** 14163 * Decide based on the configuration whether we should shouw the ANR, 14164 * crash, etc dialogs. The idea is that if there is no affordnace to 14165 * press the on-screen buttons, we shouldn't show the dialog. 14166 * 14167 * A thought: SystemUI might also want to get told about this, the Power 14168 * dialog / global actions also might want different behaviors. 14169 */ 14170 private static final boolean shouldShowDialogs(Configuration config) { 14171 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14172 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14173 } 14174 14175 /** 14176 * Save the locale. You must be inside a synchronized (this) block. 14177 */ 14178 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14179 if(isDiff) { 14180 SystemProperties.set("user.language", l.getLanguage()); 14181 SystemProperties.set("user.region", l.getCountry()); 14182 } 14183 14184 if(isPersist) { 14185 SystemProperties.set("persist.sys.language", l.getLanguage()); 14186 SystemProperties.set("persist.sys.country", l.getCountry()); 14187 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14188 } 14189 } 14190 14191 @Override 14192 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14193 ActivityRecord srec = ActivityRecord.forToken(token); 14194 return srec != null && srec.task.affinity != null && 14195 srec.task.affinity.equals(destAffinity); 14196 } 14197 14198 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14199 Intent resultData) { 14200 14201 synchronized (this) { 14202 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14203 if (stack != null) { 14204 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14205 } 14206 return false; 14207 } 14208 } 14209 14210 public int getLaunchedFromUid(IBinder activityToken) { 14211 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14212 if (srec == null) { 14213 return -1; 14214 } 14215 return srec.launchedFromUid; 14216 } 14217 14218 public String getLaunchedFromPackage(IBinder activityToken) { 14219 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14220 if (srec == null) { 14221 return null; 14222 } 14223 return srec.launchedFromPackage; 14224 } 14225 14226 // ========================================================= 14227 // LIFETIME MANAGEMENT 14228 // ========================================================= 14229 14230 // Returns which broadcast queue the app is the current [or imminent] receiver 14231 // on, or 'null' if the app is not an active broadcast recipient. 14232 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14233 BroadcastRecord r = app.curReceiver; 14234 if (r != null) { 14235 return r.queue; 14236 } 14237 14238 // It's not the current receiver, but it might be starting up to become one 14239 synchronized (this) { 14240 for (BroadcastQueue queue : mBroadcastQueues) { 14241 r = queue.mPendingBroadcast; 14242 if (r != null && r.curApp == app) { 14243 // found it; report which queue it's in 14244 return queue; 14245 } 14246 } 14247 } 14248 14249 return null; 14250 } 14251 14252 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14253 boolean doingAll, long now) { 14254 if (mAdjSeq == app.adjSeq) { 14255 // This adjustment has already been computed. 14256 return app.curRawAdj; 14257 } 14258 14259 if (app.thread == null) { 14260 app.adjSeq = mAdjSeq; 14261 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14262 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14263 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14264 } 14265 14266 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14267 app.adjSource = null; 14268 app.adjTarget = null; 14269 app.empty = false; 14270 app.cached = false; 14271 14272 final int activitiesSize = app.activities.size(); 14273 14274 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14275 // The max adjustment doesn't allow this app to be anything 14276 // below foreground, so it is not worth doing work for it. 14277 app.adjType = "fixed"; 14278 app.adjSeq = mAdjSeq; 14279 app.curRawAdj = app.maxAdj; 14280 app.foregroundActivities = false; 14281 app.keeping = true; 14282 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14283 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14284 // System process can do UI, and when they do we want to have 14285 // them trim their memory after the user leaves the UI. To 14286 // facilitate this, here we need to determine whether or not it 14287 // is currently showing UI. 14288 app.systemNoUi = true; 14289 if (app == TOP_APP) { 14290 app.systemNoUi = false; 14291 } else if (activitiesSize > 0) { 14292 for (int j = 0; j < activitiesSize; j++) { 14293 final ActivityRecord r = app.activities.get(j); 14294 if (r.visible) { 14295 app.systemNoUi = false; 14296 } 14297 } 14298 } 14299 if (!app.systemNoUi) { 14300 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14301 } 14302 return (app.curAdj=app.maxAdj); 14303 } 14304 14305 app.keeping = false; 14306 app.systemNoUi = false; 14307 14308 // Determine the importance of the process, starting with most 14309 // important to least, and assign an appropriate OOM adjustment. 14310 int adj; 14311 int schedGroup; 14312 int procState; 14313 boolean foregroundActivities = false; 14314 boolean interesting = false; 14315 BroadcastQueue queue; 14316 if (app == TOP_APP) { 14317 // The last app on the list is the foreground app. 14318 adj = ProcessList.FOREGROUND_APP_ADJ; 14319 schedGroup = Process.THREAD_GROUP_DEFAULT; 14320 app.adjType = "top-activity"; 14321 foregroundActivities = true; 14322 interesting = true; 14323 procState = ActivityManager.PROCESS_STATE_TOP; 14324 } else if (app.instrumentationClass != null) { 14325 // Don't want to kill running instrumentation. 14326 adj = ProcessList.FOREGROUND_APP_ADJ; 14327 schedGroup = Process.THREAD_GROUP_DEFAULT; 14328 app.adjType = "instrumentation"; 14329 interesting = true; 14330 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14331 } else if ((queue = isReceivingBroadcast(app)) != null) { 14332 // An app that is currently receiving a broadcast also 14333 // counts as being in the foreground for OOM killer purposes. 14334 // It's placed in a sched group based on the nature of the 14335 // broadcast as reflected by which queue it's active in. 14336 adj = ProcessList.FOREGROUND_APP_ADJ; 14337 schedGroup = (queue == mFgBroadcastQueue) 14338 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14339 app.adjType = "broadcast"; 14340 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14341 } else if (app.executingServices.size() > 0) { 14342 // An app that is currently executing a service callback also 14343 // counts as being in the foreground. 14344 adj = ProcessList.FOREGROUND_APP_ADJ; 14345 schedGroup = app.execServicesFg ? 14346 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14347 app.adjType = "exec-service"; 14348 procState = ActivityManager.PROCESS_STATE_SERVICE; 14349 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14350 } else { 14351 // As far as we know the process is empty. We may change our mind later. 14352 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14353 // At this point we don't actually know the adjustment. Use the cached adj 14354 // value that the caller wants us to. 14355 adj = cachedAdj; 14356 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14357 app.cached = true; 14358 app.empty = true; 14359 app.adjType = "cch-empty"; 14360 } 14361 14362 // Examine all activities if not already foreground. 14363 if (!foregroundActivities && activitiesSize > 0) { 14364 for (int j = 0; j < activitiesSize; j++) { 14365 final ActivityRecord r = app.activities.get(j); 14366 if (r.app != app) { 14367 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14368 + app + "?!?"); 14369 continue; 14370 } 14371 if (r.visible) { 14372 // App has a visible activity; only upgrade adjustment. 14373 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14374 adj = ProcessList.VISIBLE_APP_ADJ; 14375 app.adjType = "visible"; 14376 } 14377 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14378 procState = ActivityManager.PROCESS_STATE_TOP; 14379 } 14380 schedGroup = Process.THREAD_GROUP_DEFAULT; 14381 app.cached = false; 14382 app.empty = false; 14383 foregroundActivities = true; 14384 break; 14385 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14386 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14387 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14388 app.adjType = "pausing"; 14389 } 14390 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14391 procState = ActivityManager.PROCESS_STATE_TOP; 14392 } 14393 schedGroup = Process.THREAD_GROUP_DEFAULT; 14394 app.cached = false; 14395 app.empty = false; 14396 foregroundActivities = true; 14397 } else if (r.state == ActivityState.STOPPING) { 14398 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14399 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14400 app.adjType = "stopping"; 14401 } 14402 // For the process state, we will at this point consider the 14403 // process to be cached. It will be cached either as an activity 14404 // or empty depending on whether the activity is finishing. We do 14405 // this so that we can treat the process as cached for purposes of 14406 // memory trimming (determing current memory level, trim command to 14407 // send to process) since there can be an arbitrary number of stopping 14408 // processes and they should soon all go into the cached state. 14409 if (!r.finishing) { 14410 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14411 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14412 } 14413 } 14414 app.cached = false; 14415 app.empty = false; 14416 foregroundActivities = true; 14417 } else { 14418 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14419 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14420 app.adjType = "cch-act"; 14421 } 14422 } 14423 } 14424 } 14425 14426 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14427 if (app.foregroundServices) { 14428 // The user is aware of this app, so make it visible. 14429 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14430 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14431 app.cached = false; 14432 app.adjType = "fg-service"; 14433 schedGroup = Process.THREAD_GROUP_DEFAULT; 14434 } else if (app.forcingToForeground != null) { 14435 // The user is aware of this app, so make it visible. 14436 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14437 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14438 app.cached = false; 14439 app.adjType = "force-fg"; 14440 app.adjSource = app.forcingToForeground; 14441 schedGroup = Process.THREAD_GROUP_DEFAULT; 14442 } 14443 } 14444 14445 if (app.foregroundServices) { 14446 interesting = true; 14447 } 14448 14449 if (app == mHeavyWeightProcess) { 14450 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14451 // We don't want to kill the current heavy-weight process. 14452 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14453 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14454 app.cached = false; 14455 app.adjType = "heavy"; 14456 } 14457 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14458 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14459 } 14460 } 14461 14462 if (app == mHomeProcess) { 14463 if (adj > ProcessList.HOME_APP_ADJ) { 14464 // This process is hosting what we currently consider to be the 14465 // home app, so we don't want to let it go into the background. 14466 adj = ProcessList.HOME_APP_ADJ; 14467 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14468 app.cached = false; 14469 app.adjType = "home"; 14470 } 14471 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14472 procState = ActivityManager.PROCESS_STATE_HOME; 14473 } 14474 } 14475 14476 if (app == mPreviousProcess && app.activities.size() > 0) { 14477 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14478 // This was the previous process that showed UI to the user. 14479 // We want to try to keep it around more aggressively, to give 14480 // a good experience around switching between two apps. 14481 adj = ProcessList.PREVIOUS_APP_ADJ; 14482 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14483 app.cached = false; 14484 app.adjType = "previous"; 14485 } 14486 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14487 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14488 } 14489 } 14490 14491 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14492 + " reason=" + app.adjType); 14493 14494 // By default, we use the computed adjustment. It may be changed if 14495 // there are applications dependent on our services or providers, but 14496 // this gives us a baseline and makes sure we don't get into an 14497 // infinite recursion. 14498 app.adjSeq = mAdjSeq; 14499 app.curRawAdj = adj; 14500 app.hasStartedServices = false; 14501 14502 if (mBackupTarget != null && app == mBackupTarget.app) { 14503 // If possible we want to avoid killing apps while they're being backed up 14504 if (adj > ProcessList.BACKUP_APP_ADJ) { 14505 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14506 adj = ProcessList.BACKUP_APP_ADJ; 14507 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14508 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14509 } 14510 app.adjType = "backup"; 14511 app.cached = false; 14512 } 14513 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14514 procState = ActivityManager.PROCESS_STATE_BACKUP; 14515 } 14516 } 14517 14518 boolean mayBeTop = false; 14519 14520 for (int is = app.services.size()-1; 14521 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14522 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14523 || procState > ActivityManager.PROCESS_STATE_TOP); 14524 is--) { 14525 ServiceRecord s = app.services.valueAt(is); 14526 if (s.startRequested) { 14527 app.hasStartedServices = true; 14528 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14529 procState = ActivityManager.PROCESS_STATE_SERVICE; 14530 } 14531 if (app.hasShownUi && app != mHomeProcess) { 14532 // If this process has shown some UI, let it immediately 14533 // go to the LRU list because it may be pretty heavy with 14534 // UI stuff. We'll tag it with a label just to help 14535 // debug and understand what is going on. 14536 if (adj > ProcessList.SERVICE_ADJ) { 14537 app.adjType = "cch-started-ui-services"; 14538 } 14539 } else { 14540 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14541 // This service has seen some activity within 14542 // recent memory, so we will keep its process ahead 14543 // of the background processes. 14544 if (adj > ProcessList.SERVICE_ADJ) { 14545 adj = ProcessList.SERVICE_ADJ; 14546 app.adjType = "started-services"; 14547 app.cached = false; 14548 } 14549 } 14550 // If we have let the service slide into the background 14551 // state, still have some text describing what it is doing 14552 // even though the service no longer has an impact. 14553 if (adj > ProcessList.SERVICE_ADJ) { 14554 app.adjType = "cch-started-services"; 14555 } 14556 } 14557 // Don't kill this process because it is doing work; it 14558 // has said it is doing work. 14559 app.keeping = true; 14560 } 14561 for (int conni = s.connections.size()-1; 14562 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14563 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14564 || procState > ActivityManager.PROCESS_STATE_TOP); 14565 conni--) { 14566 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14567 for (int i = 0; 14568 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14569 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14570 || procState > ActivityManager.PROCESS_STATE_TOP); 14571 i++) { 14572 // XXX should compute this based on the max of 14573 // all connected clients. 14574 ConnectionRecord cr = clist.get(i); 14575 if (cr.binding.client == app) { 14576 // Binding to ourself is not interesting. 14577 continue; 14578 } 14579 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14580 ProcessRecord client = cr.binding.client; 14581 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14582 TOP_APP, doingAll, now); 14583 int clientProcState = client.curProcState; 14584 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14585 // If the other app is cached for any reason, for purposes here 14586 // we are going to consider it empty. The specific cached state 14587 // doesn't propagate except under certain conditions. 14588 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14589 } 14590 String adjType = null; 14591 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14592 // Not doing bind OOM management, so treat 14593 // this guy more like a started service. 14594 if (app.hasShownUi && app != mHomeProcess) { 14595 // If this process has shown some UI, let it immediately 14596 // go to the LRU list because it may be pretty heavy with 14597 // UI stuff. We'll tag it with a label just to help 14598 // debug and understand what is going on. 14599 if (adj > clientAdj) { 14600 adjType = "cch-bound-ui-services"; 14601 } 14602 app.cached = false; 14603 clientAdj = adj; 14604 clientProcState = procState; 14605 } else { 14606 if (now >= (s.lastActivity 14607 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14608 // This service has not seen activity within 14609 // recent memory, so allow it to drop to the 14610 // LRU list if there is no other reason to keep 14611 // it around. We'll also tag it with a label just 14612 // to help debug and undertand what is going on. 14613 if (adj > clientAdj) { 14614 adjType = "cch-bound-services"; 14615 } 14616 clientAdj = adj; 14617 } 14618 } 14619 } 14620 if (adj > clientAdj) { 14621 // If this process has recently shown UI, and 14622 // the process that is binding to it is less 14623 // important than being visible, then we don't 14624 // care about the binding as much as we care 14625 // about letting this process get into the LRU 14626 // list to be killed and restarted if needed for 14627 // memory. 14628 if (app.hasShownUi && app != mHomeProcess 14629 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14630 adjType = "cch-bound-ui-services"; 14631 } else { 14632 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14633 |Context.BIND_IMPORTANT)) != 0) { 14634 adj = clientAdj; 14635 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14636 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14637 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14638 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14639 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14640 adj = clientAdj; 14641 } else { 14642 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14643 adj = ProcessList.VISIBLE_APP_ADJ; 14644 } 14645 } 14646 if (!client.cached) { 14647 app.cached = false; 14648 } 14649 if (client.keeping) { 14650 app.keeping = true; 14651 } 14652 adjType = "service"; 14653 } 14654 } 14655 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14656 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14657 schedGroup = Process.THREAD_GROUP_DEFAULT; 14658 } 14659 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14660 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14661 // Special handling of clients who are in the top state. 14662 // We *may* want to consider this process to be in the 14663 // top state as well, but only if there is not another 14664 // reason for it to be running. Being on the top is a 14665 // special state, meaning you are specifically running 14666 // for the current top app. If the process is already 14667 // running in the background for some other reason, it 14668 // is more important to continue considering it to be 14669 // in the background state. 14670 mayBeTop = true; 14671 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14672 } else { 14673 // Special handling for above-top states (persistent 14674 // processes). These should not bring the current process 14675 // into the top state, since they are not on top. Instead 14676 // give them the best state after that. 14677 clientProcState = 14678 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14679 } 14680 } 14681 } else { 14682 if (clientProcState < 14683 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14684 clientProcState = 14685 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14686 } 14687 } 14688 if (procState > clientProcState) { 14689 procState = clientProcState; 14690 } 14691 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14692 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14693 app.pendingUiClean = true; 14694 } 14695 if (adjType != null) { 14696 app.adjType = adjType; 14697 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14698 .REASON_SERVICE_IN_USE; 14699 app.adjSource = cr.binding.client; 14700 app.adjSourceOom = clientAdj; 14701 app.adjTarget = s.name; 14702 } 14703 } 14704 final ActivityRecord a = cr.activity; 14705 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14706 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14707 (a.visible || a.state == ActivityState.RESUMED 14708 || a.state == ActivityState.PAUSING)) { 14709 adj = ProcessList.FOREGROUND_APP_ADJ; 14710 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14711 schedGroup = Process.THREAD_GROUP_DEFAULT; 14712 } 14713 app.cached = false; 14714 app.adjType = "service"; 14715 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14716 .REASON_SERVICE_IN_USE; 14717 app.adjSource = a; 14718 app.adjSourceOom = adj; 14719 app.adjTarget = s.name; 14720 } 14721 } 14722 } 14723 } 14724 } 14725 14726 for (int provi = app.pubProviders.size()-1; 14727 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14728 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14729 || procState > ActivityManager.PROCESS_STATE_TOP); 14730 provi--) { 14731 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14732 for (int i = cpr.connections.size()-1; 14733 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14734 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14735 || procState > ActivityManager.PROCESS_STATE_TOP); 14736 i--) { 14737 ContentProviderConnection conn = cpr.connections.get(i); 14738 ProcessRecord client = conn.client; 14739 if (client == app) { 14740 // Being our own client is not interesting. 14741 continue; 14742 } 14743 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14744 int clientProcState = client.curProcState; 14745 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14746 // If the other app is cached for any reason, for purposes here 14747 // we are going to consider it empty. 14748 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14749 } 14750 if (adj > clientAdj) { 14751 if (app.hasShownUi && app != mHomeProcess 14752 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14753 app.adjType = "cch-ui-provider"; 14754 } else { 14755 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14756 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14757 app.adjType = "provider"; 14758 } 14759 app.cached &= client.cached; 14760 app.keeping |= client.keeping; 14761 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14762 .REASON_PROVIDER_IN_USE; 14763 app.adjSource = client; 14764 app.adjSourceOom = clientAdj; 14765 app.adjTarget = cpr.name; 14766 } 14767 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14768 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14769 // Special handling of clients who are in the top state. 14770 // We *may* want to consider this process to be in the 14771 // top state as well, but only if there is not another 14772 // reason for it to be running. Being on the top is a 14773 // special state, meaning you are specifically running 14774 // for the current top app. If the process is already 14775 // running in the background for some other reason, it 14776 // is more important to continue considering it to be 14777 // in the background state. 14778 mayBeTop = true; 14779 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14780 } else { 14781 // Special handling for above-top states (persistent 14782 // processes). These should not bring the current process 14783 // into the top state, since they are not on top. Instead 14784 // give them the best state after that. 14785 clientProcState = 14786 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14787 } 14788 } 14789 if (procState > clientProcState) { 14790 procState = clientProcState; 14791 } 14792 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14793 schedGroup = Process.THREAD_GROUP_DEFAULT; 14794 } 14795 } 14796 // If the provider has external (non-framework) process 14797 // dependencies, ensure that its adjustment is at least 14798 // FOREGROUND_APP_ADJ. 14799 if (cpr.hasExternalProcessHandles()) { 14800 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14801 adj = ProcessList.FOREGROUND_APP_ADJ; 14802 schedGroup = Process.THREAD_GROUP_DEFAULT; 14803 app.cached = false; 14804 app.keeping = true; 14805 app.adjType = "provider"; 14806 app.adjTarget = cpr.name; 14807 } 14808 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14809 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14810 } 14811 } 14812 } 14813 14814 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14815 // A client of one of our services or providers is in the top state. We 14816 // *may* want to be in the top state, but not if we are already running in 14817 // the background for some other reason. For the decision here, we are going 14818 // to pick out a few specific states that we want to remain in when a client 14819 // is top (states that tend to be longer-term) and otherwise allow it to go 14820 // to the top state. 14821 switch (procState) { 14822 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14823 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14824 case ActivityManager.PROCESS_STATE_SERVICE: 14825 // These all are longer-term states, so pull them up to the top 14826 // of the background states, but not all the way to the top state. 14827 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14828 break; 14829 default: 14830 // Otherwise, top is a better choice, so take it. 14831 procState = ActivityManager.PROCESS_STATE_TOP; 14832 break; 14833 } 14834 } 14835 14836 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14837 // This is a cached process, but with client activities. Mark it so. 14838 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14839 app.adjType = "cch-client-act"; 14840 } 14841 14842 if (adj == ProcessList.SERVICE_ADJ) { 14843 if (doingAll) { 14844 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14845 mNewNumServiceProcs++; 14846 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14847 if (!app.serviceb) { 14848 // This service isn't far enough down on the LRU list to 14849 // normally be a B service, but if we are low on RAM and it 14850 // is large we want to force it down since we would prefer to 14851 // keep launcher over it. 14852 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 14853 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 14854 app.serviceHighRam = true; 14855 app.serviceb = true; 14856 //Slog.i(TAG, "ADJ " + app + " high ram!"); 14857 } else { 14858 mNewNumAServiceProcs++; 14859 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 14860 } 14861 } else { 14862 app.serviceHighRam = false; 14863 } 14864 } 14865 if (app.serviceb) { 14866 adj = ProcessList.SERVICE_B_ADJ; 14867 } 14868 } 14869 14870 app.curRawAdj = adj; 14871 14872 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14873 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14874 if (adj > app.maxAdj) { 14875 adj = app.maxAdj; 14876 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14877 schedGroup = Process.THREAD_GROUP_DEFAULT; 14878 } 14879 } 14880 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 14881 app.keeping = true; 14882 } 14883 14884 // Do final modification to adj. Everything we do between here and applying 14885 // the final setAdj must be done in this function, because we will also use 14886 // it when computing the final cached adj later. Note that we don't need to 14887 // worry about this for max adj above, since max adj will always be used to 14888 // keep it out of the cached vaues. 14889 adj = app.modifyRawOomAdj(adj); 14890 14891 app.curProcState = procState; 14892 14893 int importance = app.memImportance; 14894 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14895 app.curAdj = adj; 14896 app.curSchedGroup = schedGroup; 14897 if (!interesting) { 14898 // For this reporting, if there is not something explicitly 14899 // interesting in this process then we will push it to the 14900 // background importance. 14901 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14902 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 14903 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14904 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14905 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14906 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14907 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14908 } else if (adj >= ProcessList.SERVICE_ADJ) { 14909 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14910 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14911 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14912 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14913 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14914 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14915 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14916 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14917 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14918 } else { 14919 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14920 } 14921 } 14922 14923 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14924 if (foregroundActivities != app.foregroundActivities) { 14925 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14926 } 14927 if (changes != 0) { 14928 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14929 app.memImportance = importance; 14930 app.foregroundActivities = foregroundActivities; 14931 int i = mPendingProcessChanges.size()-1; 14932 ProcessChangeItem item = null; 14933 while (i >= 0) { 14934 item = mPendingProcessChanges.get(i); 14935 if (item.pid == app.pid) { 14936 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14937 break; 14938 } 14939 i--; 14940 } 14941 if (i < 0) { 14942 // No existing item in pending changes; need a new one. 14943 final int NA = mAvailProcessChanges.size(); 14944 if (NA > 0) { 14945 item = mAvailProcessChanges.remove(NA-1); 14946 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14947 } else { 14948 item = new ProcessChangeItem(); 14949 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14950 } 14951 item.changes = 0; 14952 item.pid = app.pid; 14953 item.uid = app.info.uid; 14954 if (mPendingProcessChanges.size() == 0) { 14955 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14956 "*** Enqueueing dispatch processes changed!"); 14957 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14958 } 14959 mPendingProcessChanges.add(item); 14960 } 14961 item.changes |= changes; 14962 item.importance = importance; 14963 item.foregroundActivities = foregroundActivities; 14964 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14965 + Integer.toHexString(System.identityHashCode(item)) 14966 + " " + app.toShortString() + ": changes=" + item.changes 14967 + " importance=" + item.importance 14968 + " foreground=" + item.foregroundActivities 14969 + " type=" + app.adjType + " source=" + app.adjSource 14970 + " target=" + app.adjTarget); 14971 } 14972 14973 return app.curRawAdj; 14974 } 14975 14976 /** 14977 * Schedule PSS collection of a process. 14978 */ 14979 void requestPssLocked(ProcessRecord proc, int procState) { 14980 if (mPendingPssProcesses.contains(proc)) { 14981 return; 14982 } 14983 if (mPendingPssProcesses.size() == 0) { 14984 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14985 } 14986 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 14987 proc.pssProcState = procState; 14988 mPendingPssProcesses.add(proc); 14989 } 14990 14991 /** 14992 * Schedule PSS collection of all processes. 14993 */ 14994 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 14995 if (!always) { 14996 if (now < (mLastFullPssTime + 14997 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 14998 return; 14999 } 15000 } 15001 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15002 mLastFullPssTime = now; 15003 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15004 mPendingPssProcesses.clear(); 15005 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15006 ProcessRecord app = mLruProcesses.get(i); 15007 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15008 app.pssProcState = app.setProcState; 15009 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15010 mSleeping, now); 15011 mPendingPssProcesses.add(app); 15012 } 15013 } 15014 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15015 } 15016 15017 /** 15018 * Ask a given process to GC right now. 15019 */ 15020 final void performAppGcLocked(ProcessRecord app) { 15021 try { 15022 app.lastRequestedGc = SystemClock.uptimeMillis(); 15023 if (app.thread != null) { 15024 if (app.reportLowMemory) { 15025 app.reportLowMemory = false; 15026 app.thread.scheduleLowMemory(); 15027 } else { 15028 app.thread.processInBackground(); 15029 } 15030 } 15031 } catch (Exception e) { 15032 // whatever. 15033 } 15034 } 15035 15036 /** 15037 * Returns true if things are idle enough to perform GCs. 15038 */ 15039 private final boolean canGcNowLocked() { 15040 boolean processingBroadcasts = false; 15041 for (BroadcastQueue q : mBroadcastQueues) { 15042 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15043 processingBroadcasts = true; 15044 } 15045 } 15046 return !processingBroadcasts 15047 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 15048 } 15049 15050 /** 15051 * Perform GCs on all processes that are waiting for it, but only 15052 * if things are idle. 15053 */ 15054 final void performAppGcsLocked() { 15055 final int N = mProcessesToGc.size(); 15056 if (N <= 0) { 15057 return; 15058 } 15059 if (canGcNowLocked()) { 15060 while (mProcessesToGc.size() > 0) { 15061 ProcessRecord proc = mProcessesToGc.remove(0); 15062 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15063 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15064 <= SystemClock.uptimeMillis()) { 15065 // To avoid spamming the system, we will GC processes one 15066 // at a time, waiting a few seconds between each. 15067 performAppGcLocked(proc); 15068 scheduleAppGcsLocked(); 15069 return; 15070 } else { 15071 // It hasn't been long enough since we last GCed this 15072 // process... put it in the list to wait for its time. 15073 addProcessToGcListLocked(proc); 15074 break; 15075 } 15076 } 15077 } 15078 15079 scheduleAppGcsLocked(); 15080 } 15081 } 15082 15083 /** 15084 * If all looks good, perform GCs on all processes waiting for them. 15085 */ 15086 final void performAppGcsIfAppropriateLocked() { 15087 if (canGcNowLocked()) { 15088 performAppGcsLocked(); 15089 return; 15090 } 15091 // Still not idle, wait some more. 15092 scheduleAppGcsLocked(); 15093 } 15094 15095 /** 15096 * Schedule the execution of all pending app GCs. 15097 */ 15098 final void scheduleAppGcsLocked() { 15099 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15100 15101 if (mProcessesToGc.size() > 0) { 15102 // Schedule a GC for the time to the next process. 15103 ProcessRecord proc = mProcessesToGc.get(0); 15104 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15105 15106 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15107 long now = SystemClock.uptimeMillis(); 15108 if (when < (now+GC_TIMEOUT)) { 15109 when = now + GC_TIMEOUT; 15110 } 15111 mHandler.sendMessageAtTime(msg, when); 15112 } 15113 } 15114 15115 /** 15116 * Add a process to the array of processes waiting to be GCed. Keeps the 15117 * list in sorted order by the last GC time. The process can't already be 15118 * on the list. 15119 */ 15120 final void addProcessToGcListLocked(ProcessRecord proc) { 15121 boolean added = false; 15122 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15123 if (mProcessesToGc.get(i).lastRequestedGc < 15124 proc.lastRequestedGc) { 15125 added = true; 15126 mProcessesToGc.add(i+1, proc); 15127 break; 15128 } 15129 } 15130 if (!added) { 15131 mProcessesToGc.add(0, proc); 15132 } 15133 } 15134 15135 /** 15136 * Set up to ask a process to GC itself. This will either do it 15137 * immediately, or put it on the list of processes to gc the next 15138 * time things are idle. 15139 */ 15140 final void scheduleAppGcLocked(ProcessRecord app) { 15141 long now = SystemClock.uptimeMillis(); 15142 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15143 return; 15144 } 15145 if (!mProcessesToGc.contains(app)) { 15146 addProcessToGcListLocked(app); 15147 scheduleAppGcsLocked(); 15148 } 15149 } 15150 15151 final void checkExcessivePowerUsageLocked(boolean doKills) { 15152 updateCpuStatsNow(); 15153 15154 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15155 boolean doWakeKills = doKills; 15156 boolean doCpuKills = doKills; 15157 if (mLastPowerCheckRealtime == 0) { 15158 doWakeKills = false; 15159 } 15160 if (mLastPowerCheckUptime == 0) { 15161 doCpuKills = false; 15162 } 15163 if (stats.isScreenOn()) { 15164 doWakeKills = false; 15165 } 15166 final long curRealtime = SystemClock.elapsedRealtime(); 15167 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15168 final long curUptime = SystemClock.uptimeMillis(); 15169 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15170 mLastPowerCheckRealtime = curRealtime; 15171 mLastPowerCheckUptime = curUptime; 15172 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15173 doWakeKills = false; 15174 } 15175 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15176 doCpuKills = false; 15177 } 15178 int i = mLruProcesses.size(); 15179 while (i > 0) { 15180 i--; 15181 ProcessRecord app = mLruProcesses.get(i); 15182 if (!app.keeping) { 15183 long wtime; 15184 synchronized (stats) { 15185 wtime = stats.getProcessWakeTime(app.info.uid, 15186 app.pid, curRealtime); 15187 } 15188 long wtimeUsed = wtime - app.lastWakeTime; 15189 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15190 if (DEBUG_POWER) { 15191 StringBuilder sb = new StringBuilder(128); 15192 sb.append("Wake for "); 15193 app.toShortString(sb); 15194 sb.append(": over "); 15195 TimeUtils.formatDuration(realtimeSince, sb); 15196 sb.append(" used "); 15197 TimeUtils.formatDuration(wtimeUsed, sb); 15198 sb.append(" ("); 15199 sb.append((wtimeUsed*100)/realtimeSince); 15200 sb.append("%)"); 15201 Slog.i(TAG, sb.toString()); 15202 sb.setLength(0); 15203 sb.append("CPU for "); 15204 app.toShortString(sb); 15205 sb.append(": over "); 15206 TimeUtils.formatDuration(uptimeSince, sb); 15207 sb.append(" used "); 15208 TimeUtils.formatDuration(cputimeUsed, sb); 15209 sb.append(" ("); 15210 sb.append((cputimeUsed*100)/uptimeSince); 15211 sb.append("%)"); 15212 Slog.i(TAG, sb.toString()); 15213 } 15214 // If a process has held a wake lock for more 15215 // than 50% of the time during this period, 15216 // that sounds bad. Kill! 15217 if (doWakeKills && realtimeSince > 0 15218 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15219 synchronized (stats) { 15220 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15221 realtimeSince, wtimeUsed); 15222 } 15223 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15224 + " during " + realtimeSince); 15225 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15226 } else if (doCpuKills && uptimeSince > 0 15227 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15228 synchronized (stats) { 15229 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15230 uptimeSince, cputimeUsed); 15231 } 15232 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15233 + " during " + uptimeSince); 15234 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15235 } else { 15236 app.lastWakeTime = wtime; 15237 app.lastCpuTime = app.curCpuTime; 15238 } 15239 } 15240 } 15241 } 15242 15243 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15244 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15245 boolean success = true; 15246 15247 if (app.curRawAdj != app.setRawAdj) { 15248 if (wasKeeping && !app.keeping) { 15249 // This app is no longer something we want to keep. Note 15250 // its current wake lock time to later know to kill it if 15251 // it is not behaving well. 15252 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15253 synchronized (stats) { 15254 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15255 app.pid, SystemClock.elapsedRealtime()); 15256 } 15257 app.lastCpuTime = app.curCpuTime; 15258 } 15259 15260 app.setRawAdj = app.curRawAdj; 15261 } 15262 15263 if (app.curAdj != app.setAdj) { 15264 ProcessList.setOomAdj(app.pid, app.curAdj); 15265 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15266 TAG, "Set " + app.pid + " " + app.processName + 15267 " adj " + app.curAdj + ": " + app.adjType); 15268 app.setAdj = app.curAdj; 15269 } 15270 15271 if (app.setSchedGroup != app.curSchedGroup) { 15272 app.setSchedGroup = app.curSchedGroup; 15273 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15274 "Setting process group of " + app.processName 15275 + " to " + app.curSchedGroup); 15276 if (app.waitingToKill != null && 15277 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15278 killUnneededProcessLocked(app, app.waitingToKill); 15279 success = false; 15280 } else { 15281 if (true) { 15282 long oldId = Binder.clearCallingIdentity(); 15283 try { 15284 Process.setProcessGroup(app.pid, app.curSchedGroup); 15285 } catch (Exception e) { 15286 Slog.w(TAG, "Failed setting process group of " + app.pid 15287 + " to " + app.curSchedGroup); 15288 e.printStackTrace(); 15289 } finally { 15290 Binder.restoreCallingIdentity(oldId); 15291 } 15292 } else { 15293 if (app.thread != null) { 15294 try { 15295 app.thread.setSchedulingGroup(app.curSchedGroup); 15296 } catch (RemoteException e) { 15297 } 15298 } 15299 } 15300 Process.setSwappiness(app.pid, 15301 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15302 } 15303 } 15304 if (app.repProcState != app.curProcState) { 15305 app.repProcState = app.curProcState; 15306 if (!reportingProcessState && app.thread != null) { 15307 try { 15308 if (false) { 15309 //RuntimeException h = new RuntimeException("here"); 15310 Slog.i(TAG, "Sending new process state " + app.repProcState 15311 + " to " + app /*, h*/); 15312 } 15313 app.thread.setProcessState(app.repProcState); 15314 } catch (RemoteException e) { 15315 } 15316 } 15317 } 15318 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15319 app.setProcState)) { 15320 app.lastStateTime = now; 15321 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15322 mSleeping, now); 15323 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15324 + ProcessList.makeProcStateString(app.setProcState) + " to " 15325 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15326 + (app.nextPssTime-now) + ": " + app); 15327 } else { 15328 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15329 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15330 requestPssLocked(app, app.setProcState); 15331 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15332 mSleeping, now); 15333 } else if (false && DEBUG_PSS) { 15334 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15335 } 15336 } 15337 if (app.setProcState != app.curProcState) { 15338 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15339 "Proc state change of " + app.processName 15340 + " to " + app.curProcState); 15341 app.setProcState = app.curProcState; 15342 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15343 app.notCachedSinceIdle = false; 15344 } 15345 if (!doingAll) { 15346 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15347 } else { 15348 app.procStateChanged = true; 15349 } 15350 } 15351 return success; 15352 } 15353 15354 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15355 if (proc.thread != null && proc.baseProcessTracker != null) { 15356 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15357 } 15358 } 15359 15360 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15361 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15362 if (app.thread == null) { 15363 return false; 15364 } 15365 15366 final boolean wasKeeping = app.keeping; 15367 15368 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15369 15370 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15371 reportingProcessState, now); 15372 } 15373 15374 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15375 boolean oomAdj) { 15376 if (isForeground != proc.foregroundServices) { 15377 proc.foregroundServices = isForeground; 15378 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15379 proc.info.uid); 15380 if (isForeground) { 15381 if (curProcs == null) { 15382 curProcs = new ArrayList<ProcessRecord>(); 15383 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15384 } 15385 if (!curProcs.contains(proc)) { 15386 curProcs.add(proc); 15387 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15388 proc.info.packageName, proc.info.uid); 15389 } 15390 } else { 15391 if (curProcs != null) { 15392 if (curProcs.remove(proc)) { 15393 mBatteryStatsService.noteEvent( 15394 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15395 proc.info.packageName, proc.info.uid); 15396 if (curProcs.size() <= 0) { 15397 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15398 } 15399 } 15400 } 15401 } 15402 if (oomAdj) { 15403 updateOomAdjLocked(); 15404 } 15405 } 15406 } 15407 15408 private final ActivityRecord resumedAppLocked() { 15409 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15410 String pkg; 15411 int uid; 15412 if (act != null) { 15413 pkg = act.packageName; 15414 uid = act.info.applicationInfo.uid; 15415 } else { 15416 pkg = null; 15417 uid = -1; 15418 } 15419 // Has the UID or resumed package name changed? 15420 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15421 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15422 if (mCurResumedPackage != null) { 15423 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15424 mCurResumedPackage, mCurResumedUid); 15425 } 15426 mCurResumedPackage = pkg; 15427 mCurResumedUid = uid; 15428 if (mCurResumedPackage != null) { 15429 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15430 mCurResumedPackage, mCurResumedUid); 15431 } 15432 } 15433 return act; 15434 } 15435 15436 final boolean updateOomAdjLocked(ProcessRecord app) { 15437 return updateOomAdjLocked(app, false); 15438 } 15439 15440 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15441 final ActivityRecord TOP_ACT = resumedAppLocked(); 15442 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15443 final boolean wasCached = app.cached; 15444 15445 mAdjSeq++; 15446 15447 // This is the desired cached adjusment we want to tell it to use. 15448 // If our app is currently cached, we know it, and that is it. Otherwise, 15449 // we don't know it yet, and it needs to now be cached we will then 15450 // need to do a complete oom adj. 15451 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15452 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15453 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15454 SystemClock.uptimeMillis()); 15455 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15456 // Changed to/from cached state, so apps after it in the LRU 15457 // list may also be changed. 15458 updateOomAdjLocked(); 15459 } 15460 return success; 15461 } 15462 15463 final void updateOomAdjLocked() { 15464 final ActivityRecord TOP_ACT = resumedAppLocked(); 15465 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15466 final long now = SystemClock.uptimeMillis(); 15467 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15468 final int N = mLruProcesses.size(); 15469 15470 if (false) { 15471 RuntimeException e = new RuntimeException(); 15472 e.fillInStackTrace(); 15473 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15474 } 15475 15476 mAdjSeq++; 15477 mNewNumServiceProcs = 0; 15478 mNewNumAServiceProcs = 0; 15479 15480 final int emptyProcessLimit; 15481 final int cachedProcessLimit; 15482 if (mProcessLimit <= 0) { 15483 emptyProcessLimit = cachedProcessLimit = 0; 15484 } else if (mProcessLimit == 1) { 15485 emptyProcessLimit = 1; 15486 cachedProcessLimit = 0; 15487 } else { 15488 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15489 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15490 } 15491 15492 // Let's determine how many processes we have running vs. 15493 // how many slots we have for background processes; we may want 15494 // to put multiple processes in a slot of there are enough of 15495 // them. 15496 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15497 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15498 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15499 if (numEmptyProcs > cachedProcessLimit) { 15500 // If there are more empty processes than our limit on cached 15501 // processes, then use the cached process limit for the factor. 15502 // This ensures that the really old empty processes get pushed 15503 // down to the bottom, so if we are running low on memory we will 15504 // have a better chance at keeping around more cached processes 15505 // instead of a gazillion empty processes. 15506 numEmptyProcs = cachedProcessLimit; 15507 } 15508 int emptyFactor = numEmptyProcs/numSlots; 15509 if (emptyFactor < 1) emptyFactor = 1; 15510 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15511 if (cachedFactor < 1) cachedFactor = 1; 15512 int stepCached = 0; 15513 int stepEmpty = 0; 15514 int numCached = 0; 15515 int numEmpty = 0; 15516 int numTrimming = 0; 15517 15518 mNumNonCachedProcs = 0; 15519 mNumCachedHiddenProcs = 0; 15520 15521 // First update the OOM adjustment for each of the 15522 // application processes based on their current state. 15523 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15524 int nextCachedAdj = curCachedAdj+1; 15525 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15526 int nextEmptyAdj = curEmptyAdj+2; 15527 for (int i=N-1; i>=0; i--) { 15528 ProcessRecord app = mLruProcesses.get(i); 15529 if (!app.killedByAm && app.thread != null) { 15530 app.procStateChanged = false; 15531 final boolean wasKeeping = app.keeping; 15532 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15533 15534 // If we haven't yet assigned the final cached adj 15535 // to the process, do that now. 15536 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15537 switch (app.curProcState) { 15538 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15539 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15540 // This process is a cached process holding activities... 15541 // assign it the next cached value for that type, and then 15542 // step that cached level. 15543 app.curRawAdj = curCachedAdj; 15544 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15545 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15546 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15547 + ")"); 15548 if (curCachedAdj != nextCachedAdj) { 15549 stepCached++; 15550 if (stepCached >= cachedFactor) { 15551 stepCached = 0; 15552 curCachedAdj = nextCachedAdj; 15553 nextCachedAdj += 2; 15554 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15555 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15556 } 15557 } 15558 } 15559 break; 15560 default: 15561 // For everything else, assign next empty cached process 15562 // level and bump that up. Note that this means that 15563 // long-running services that have dropped down to the 15564 // cached level will be treated as empty (since their process 15565 // state is still as a service), which is what we want. 15566 app.curRawAdj = curEmptyAdj; 15567 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15568 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15569 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15570 + ")"); 15571 if (curEmptyAdj != nextEmptyAdj) { 15572 stepEmpty++; 15573 if (stepEmpty >= emptyFactor) { 15574 stepEmpty = 0; 15575 curEmptyAdj = nextEmptyAdj; 15576 nextEmptyAdj += 2; 15577 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15578 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15579 } 15580 } 15581 } 15582 break; 15583 } 15584 } 15585 15586 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15587 15588 // Count the number of process types. 15589 switch (app.curProcState) { 15590 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15591 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15592 mNumCachedHiddenProcs++; 15593 numCached++; 15594 if (numCached > cachedProcessLimit) { 15595 killUnneededProcessLocked(app, "cached #" + numCached); 15596 } 15597 break; 15598 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15599 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15600 && app.lastActivityTime < oldTime) { 15601 killUnneededProcessLocked(app, "empty for " 15602 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15603 / 1000) + "s"); 15604 } else { 15605 numEmpty++; 15606 if (numEmpty > emptyProcessLimit) { 15607 killUnneededProcessLocked(app, "empty #" + numEmpty); 15608 } 15609 } 15610 break; 15611 default: 15612 mNumNonCachedProcs++; 15613 break; 15614 } 15615 15616 if (app.isolated && app.services.size() <= 0) { 15617 // If this is an isolated process, and there are no 15618 // services running in it, then the process is no longer 15619 // needed. We agressively kill these because we can by 15620 // definition not re-use the same process again, and it is 15621 // good to avoid having whatever code was running in them 15622 // left sitting around after no longer needed. 15623 killUnneededProcessLocked(app, "isolated not needed"); 15624 } 15625 15626 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15627 && !app.killedByAm) { 15628 numTrimming++; 15629 } 15630 } 15631 } 15632 15633 mNumServiceProcs = mNewNumServiceProcs; 15634 15635 // Now determine the memory trimming level of background processes. 15636 // Unfortunately we need to start at the back of the list to do this 15637 // properly. We only do this if the number of background apps we 15638 // are managing to keep around is less than half the maximum we desire; 15639 // if we are keeping a good number around, we'll let them use whatever 15640 // memory they want. 15641 final int numCachedAndEmpty = numCached + numEmpty; 15642 int memFactor; 15643 if (numCached <= ProcessList.TRIM_CACHED_APPS 15644 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15645 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15646 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15647 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15648 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15649 } else { 15650 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15651 } 15652 } else { 15653 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15654 } 15655 // We always allow the memory level to go up (better). We only allow it to go 15656 // down if we are in a state where that is allowed, *and* the total number of processes 15657 // has gone down since last time. 15658 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15659 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15660 + " last=" + mLastNumProcesses); 15661 if (memFactor > mLastMemoryLevel) { 15662 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15663 memFactor = mLastMemoryLevel; 15664 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15665 } 15666 } 15667 mLastMemoryLevel = memFactor; 15668 mLastNumProcesses = mLruProcesses.size(); 15669 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15670 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15671 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15672 if (mLowRamStartTime == 0) { 15673 mLowRamStartTime = now; 15674 } 15675 int step = 0; 15676 int fgTrimLevel; 15677 switch (memFactor) { 15678 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15679 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15680 break; 15681 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15682 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15683 break; 15684 default: 15685 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15686 break; 15687 } 15688 int factor = numTrimming/3; 15689 int minFactor = 2; 15690 if (mHomeProcess != null) minFactor++; 15691 if (mPreviousProcess != null) minFactor++; 15692 if (factor < minFactor) factor = minFactor; 15693 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15694 for (int i=N-1; i>=0; i--) { 15695 ProcessRecord app = mLruProcesses.get(i); 15696 if (allChanged || app.procStateChanged) { 15697 setProcessTrackerState(app, trackerMemFactor, now); 15698 app.procStateChanged = false; 15699 } 15700 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15701 && !app.killedByAm) { 15702 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15703 try { 15704 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15705 "Trimming memory of " + app.processName 15706 + " to " + curLevel); 15707 app.thread.scheduleTrimMemory(curLevel); 15708 } catch (RemoteException e) { 15709 } 15710 if (false) { 15711 // For now we won't do this; our memory trimming seems 15712 // to be good enough at this point that destroying 15713 // activities causes more harm than good. 15714 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15715 && app != mHomeProcess && app != mPreviousProcess) { 15716 // Need to do this on its own message because the stack may not 15717 // be in a consistent state at this point. 15718 // For these apps we will also finish their activities 15719 // to help them free memory. 15720 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15721 } 15722 } 15723 } 15724 app.trimMemoryLevel = curLevel; 15725 step++; 15726 if (step >= factor) { 15727 step = 0; 15728 switch (curLevel) { 15729 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15730 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15731 break; 15732 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15733 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15734 break; 15735 } 15736 } 15737 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15738 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15739 && app.thread != null) { 15740 try { 15741 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15742 "Trimming memory of heavy-weight " + app.processName 15743 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15744 app.thread.scheduleTrimMemory( 15745 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15746 } catch (RemoteException e) { 15747 } 15748 } 15749 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15750 } else { 15751 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15752 || app.systemNoUi) && app.pendingUiClean) { 15753 // If this application is now in the background and it 15754 // had done UI, then give it the special trim level to 15755 // have it free UI resources. 15756 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15757 if (app.trimMemoryLevel < level && app.thread != null) { 15758 try { 15759 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15760 "Trimming memory of bg-ui " + app.processName 15761 + " to " + level); 15762 app.thread.scheduleTrimMemory(level); 15763 } catch (RemoteException e) { 15764 } 15765 } 15766 app.pendingUiClean = false; 15767 } 15768 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15769 try { 15770 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15771 "Trimming memory of fg " + app.processName 15772 + " to " + fgTrimLevel); 15773 app.thread.scheduleTrimMemory(fgTrimLevel); 15774 } catch (RemoteException e) { 15775 } 15776 } 15777 app.trimMemoryLevel = fgTrimLevel; 15778 } 15779 } 15780 } else { 15781 if (mLowRamStartTime != 0) { 15782 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15783 mLowRamStartTime = 0; 15784 } 15785 for (int i=N-1; i>=0; i--) { 15786 ProcessRecord app = mLruProcesses.get(i); 15787 if (allChanged || app.procStateChanged) { 15788 setProcessTrackerState(app, trackerMemFactor, now); 15789 app.procStateChanged = false; 15790 } 15791 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15792 || app.systemNoUi) && app.pendingUiClean) { 15793 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15794 && app.thread != null) { 15795 try { 15796 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15797 "Trimming memory of ui hidden " + app.processName 15798 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15799 app.thread.scheduleTrimMemory( 15800 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15801 } catch (RemoteException e) { 15802 } 15803 } 15804 app.pendingUiClean = false; 15805 } 15806 app.trimMemoryLevel = 0; 15807 } 15808 } 15809 15810 if (mAlwaysFinishActivities) { 15811 // Need to do this on its own message because the stack may not 15812 // be in a consistent state at this point. 15813 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15814 } 15815 15816 if (allChanged) { 15817 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15818 } 15819 15820 if (mProcessStats.shouldWriteNowLocked(now)) { 15821 mHandler.post(new Runnable() { 15822 @Override public void run() { 15823 synchronized (ActivityManagerService.this) { 15824 mProcessStats.writeStateAsyncLocked(); 15825 } 15826 } 15827 }); 15828 } 15829 15830 if (DEBUG_OOM_ADJ) { 15831 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15832 } 15833 } 15834 15835 final void trimApplications() { 15836 synchronized (this) { 15837 int i; 15838 15839 // First remove any unused application processes whose package 15840 // has been removed. 15841 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15842 final ProcessRecord app = mRemovedProcesses.get(i); 15843 if (app.activities.size() == 0 15844 && app.curReceiver == null && app.services.size() == 0) { 15845 Slog.i( 15846 TAG, "Exiting empty application process " 15847 + app.processName + " (" 15848 + (app.thread != null ? app.thread.asBinder() : null) 15849 + ")\n"); 15850 if (app.pid > 0 && app.pid != MY_PID) { 15851 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 15852 app.processName, app.setAdj, "empty"); 15853 app.killedByAm = true; 15854 Process.killProcessQuiet(app.pid); 15855 } else { 15856 try { 15857 app.thread.scheduleExit(); 15858 } catch (Exception e) { 15859 // Ignore exceptions. 15860 } 15861 } 15862 cleanUpApplicationRecordLocked(app, false, true, -1); 15863 mRemovedProcesses.remove(i); 15864 15865 if (app.persistent) { 15866 if (app.persistent) { 15867 addAppLocked(app.info, false); 15868 } 15869 } 15870 } 15871 } 15872 15873 // Now update the oom adj for all processes. 15874 updateOomAdjLocked(); 15875 } 15876 } 15877 15878 /** This method sends the specified signal to each of the persistent apps */ 15879 public void signalPersistentProcesses(int sig) throws RemoteException { 15880 if (sig != Process.SIGNAL_USR1) { 15881 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 15882 } 15883 15884 synchronized (this) { 15885 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 15886 != PackageManager.PERMISSION_GRANTED) { 15887 throw new SecurityException("Requires permission " 15888 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 15889 } 15890 15891 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15892 ProcessRecord r = mLruProcesses.get(i); 15893 if (r.thread != null && r.persistent) { 15894 Process.sendSignal(r.pid, sig); 15895 } 15896 } 15897 } 15898 } 15899 15900 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 15901 if (proc == null || proc == mProfileProc) { 15902 proc = mProfileProc; 15903 path = mProfileFile; 15904 profileType = mProfileType; 15905 clearProfilerLocked(); 15906 } 15907 if (proc == null) { 15908 return; 15909 } 15910 try { 15911 proc.thread.profilerControl(false, path, null, profileType); 15912 } catch (RemoteException e) { 15913 throw new IllegalStateException("Process disappeared"); 15914 } 15915 } 15916 15917 private void clearProfilerLocked() { 15918 if (mProfileFd != null) { 15919 try { 15920 mProfileFd.close(); 15921 } catch (IOException e) { 15922 } 15923 } 15924 mProfileApp = null; 15925 mProfileProc = null; 15926 mProfileFile = null; 15927 mProfileType = 0; 15928 mAutoStopProfiler = false; 15929 } 15930 15931 public boolean profileControl(String process, int userId, boolean start, 15932 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 15933 15934 try { 15935 synchronized (this) { 15936 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15937 // its own permission. 15938 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15939 != PackageManager.PERMISSION_GRANTED) { 15940 throw new SecurityException("Requires permission " 15941 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15942 } 15943 15944 if (start && fd == null) { 15945 throw new IllegalArgumentException("null fd"); 15946 } 15947 15948 ProcessRecord proc = null; 15949 if (process != null) { 15950 proc = findProcessLocked(process, userId, "profileControl"); 15951 } 15952 15953 if (start && (proc == null || proc.thread == null)) { 15954 throw new IllegalArgumentException("Unknown process: " + process); 15955 } 15956 15957 if (start) { 15958 stopProfilerLocked(null, null, 0); 15959 setProfileApp(proc.info, proc.processName, path, fd, false); 15960 mProfileProc = proc; 15961 mProfileType = profileType; 15962 try { 15963 fd = fd.dup(); 15964 } catch (IOException e) { 15965 fd = null; 15966 } 15967 proc.thread.profilerControl(start, path, fd, profileType); 15968 fd = null; 15969 mProfileFd = null; 15970 } else { 15971 stopProfilerLocked(proc, path, profileType); 15972 if (fd != null) { 15973 try { 15974 fd.close(); 15975 } catch (IOException e) { 15976 } 15977 } 15978 } 15979 15980 return true; 15981 } 15982 } catch (RemoteException e) { 15983 throw new IllegalStateException("Process disappeared"); 15984 } finally { 15985 if (fd != null) { 15986 try { 15987 fd.close(); 15988 } catch (IOException e) { 15989 } 15990 } 15991 } 15992 } 15993 15994 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 15995 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15996 userId, true, true, callName, null); 15997 ProcessRecord proc = null; 15998 try { 15999 int pid = Integer.parseInt(process); 16000 synchronized (mPidsSelfLocked) { 16001 proc = mPidsSelfLocked.get(pid); 16002 } 16003 } catch (NumberFormatException e) { 16004 } 16005 16006 if (proc == null) { 16007 ArrayMap<String, SparseArray<ProcessRecord>> all 16008 = mProcessNames.getMap(); 16009 SparseArray<ProcessRecord> procs = all.get(process); 16010 if (procs != null && procs.size() > 0) { 16011 proc = procs.valueAt(0); 16012 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16013 for (int i=1; i<procs.size(); i++) { 16014 ProcessRecord thisProc = procs.valueAt(i); 16015 if (thisProc.userId == userId) { 16016 proc = thisProc; 16017 break; 16018 } 16019 } 16020 } 16021 } 16022 } 16023 16024 return proc; 16025 } 16026 16027 public boolean dumpHeap(String process, int userId, boolean managed, 16028 String path, ParcelFileDescriptor fd) throws RemoteException { 16029 16030 try { 16031 synchronized (this) { 16032 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16033 // its own permission (same as profileControl). 16034 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16035 != PackageManager.PERMISSION_GRANTED) { 16036 throw new SecurityException("Requires permission " 16037 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16038 } 16039 16040 if (fd == null) { 16041 throw new IllegalArgumentException("null fd"); 16042 } 16043 16044 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16045 if (proc == null || proc.thread == null) { 16046 throw new IllegalArgumentException("Unknown process: " + process); 16047 } 16048 16049 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16050 if (!isDebuggable) { 16051 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16052 throw new SecurityException("Process not debuggable: " + proc); 16053 } 16054 } 16055 16056 proc.thread.dumpHeap(managed, path, fd); 16057 fd = null; 16058 return true; 16059 } 16060 } catch (RemoteException e) { 16061 throw new IllegalStateException("Process disappeared"); 16062 } finally { 16063 if (fd != null) { 16064 try { 16065 fd.close(); 16066 } catch (IOException e) { 16067 } 16068 } 16069 } 16070 } 16071 16072 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16073 public void monitor() { 16074 synchronized (this) { } 16075 } 16076 16077 void onCoreSettingsChange(Bundle settings) { 16078 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16079 ProcessRecord processRecord = mLruProcesses.get(i); 16080 try { 16081 if (processRecord.thread != null) { 16082 processRecord.thread.setCoreSettings(settings); 16083 } 16084 } catch (RemoteException re) { 16085 /* ignore */ 16086 } 16087 } 16088 } 16089 16090 // Multi-user methods 16091 16092 /** 16093 * Start user, if its not already running, but don't bring it to foreground. 16094 */ 16095 @Override 16096 public boolean startUserInBackground(final int userId) { 16097 return startUser(userId, /* foreground */ false); 16098 } 16099 16100 @Override 16101 public boolean switchUser(final int userId) { 16102 return startUser(userId, /* foregound */ true); 16103 } 16104 16105 private boolean startUser(final int userId, boolean foreground) { 16106 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16107 != PackageManager.PERMISSION_GRANTED) { 16108 String msg = "Permission Denial: switchUser() from pid=" 16109 + Binder.getCallingPid() 16110 + ", uid=" + Binder.getCallingUid() 16111 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16112 Slog.w(TAG, msg); 16113 throw new SecurityException(msg); 16114 } 16115 16116 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16117 16118 final long ident = Binder.clearCallingIdentity(); 16119 try { 16120 synchronized (this) { 16121 final int oldUserId = mCurrentUserId; 16122 if (oldUserId == userId) { 16123 return true; 16124 } 16125 16126 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16127 if (userInfo == null) { 16128 Slog.w(TAG, "No user info for user #" + userId); 16129 return false; 16130 } 16131 16132 if (foreground) { 16133 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16134 R.anim.screen_user_enter); 16135 } 16136 16137 boolean needStart = false; 16138 16139 // If the user we are switching to is not currently started, then 16140 // we need to start it now. 16141 if (mStartedUsers.get(userId) == null) { 16142 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16143 updateStartedUserArrayLocked(); 16144 needStart = true; 16145 } 16146 16147 final Integer userIdInt = Integer.valueOf(userId); 16148 mUserLru.remove(userIdInt); 16149 mUserLru.add(userIdInt); 16150 16151 if (foreground) { 16152 mCurrentUserId = userId; 16153 mWindowManager.setCurrentUser(userId); 16154 // Once the internal notion of the active user has switched, we lock the device 16155 // with the option to show the user switcher on the keyguard. 16156 mWindowManager.lockNow(null); 16157 } else { 16158 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16159 mUserLru.remove(currentUserIdInt); 16160 mUserLru.add(currentUserIdInt); 16161 } 16162 16163 final UserStartedState uss = mStartedUsers.get(userId); 16164 16165 // Make sure user is in the started state. If it is currently 16166 // stopping, we need to knock that off. 16167 if (uss.mState == UserStartedState.STATE_STOPPING) { 16168 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16169 // so we can just fairly silently bring the user back from 16170 // the almost-dead. 16171 uss.mState = UserStartedState.STATE_RUNNING; 16172 updateStartedUserArrayLocked(); 16173 needStart = true; 16174 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16175 // This means ACTION_SHUTDOWN has been sent, so we will 16176 // need to treat this as a new boot of the user. 16177 uss.mState = UserStartedState.STATE_BOOTING; 16178 updateStartedUserArrayLocked(); 16179 needStart = true; 16180 } 16181 16182 if (foreground) { 16183 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16184 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16185 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16186 oldUserId, userId, uss)); 16187 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16188 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16189 } 16190 16191 if (needStart) { 16192 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16193 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16194 | Intent.FLAG_RECEIVER_FOREGROUND); 16195 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16196 broadcastIntentLocked(null, null, intent, 16197 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16198 false, false, MY_PID, Process.SYSTEM_UID, userId); 16199 } 16200 16201 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16202 if (userId != 0) { 16203 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16204 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16205 broadcastIntentLocked(null, null, intent, null, 16206 new IIntentReceiver.Stub() { 16207 public void performReceive(Intent intent, int resultCode, 16208 String data, Bundle extras, boolean ordered, 16209 boolean sticky, int sendingUser) { 16210 userInitialized(uss, userId); 16211 } 16212 }, 0, null, null, null, AppOpsManager.OP_NONE, 16213 true, false, MY_PID, Process.SYSTEM_UID, 16214 userId); 16215 uss.initializing = true; 16216 } else { 16217 getUserManagerLocked().makeInitialized(userInfo.id); 16218 } 16219 } 16220 16221 if (foreground) { 16222 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16223 if (homeInFront) { 16224 startHomeActivityLocked(userId); 16225 } else { 16226 mStackSupervisor.resumeTopActivitiesLocked(); 16227 } 16228 EventLogTags.writeAmSwitchUser(userId); 16229 getUserManagerLocked().userForeground(userId); 16230 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16231 } 16232 16233 if (needStart) { 16234 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16235 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16236 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16237 broadcastIntentLocked(null, null, intent, 16238 null, new IIntentReceiver.Stub() { 16239 @Override 16240 public void performReceive(Intent intent, int resultCode, String data, 16241 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16242 throws RemoteException { 16243 } 16244 }, 0, null, null, 16245 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16246 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16247 } 16248 } 16249 } finally { 16250 Binder.restoreCallingIdentity(ident); 16251 } 16252 16253 return true; 16254 } 16255 16256 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16257 long ident = Binder.clearCallingIdentity(); 16258 try { 16259 Intent intent; 16260 if (oldUserId >= 0) { 16261 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16262 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16263 | Intent.FLAG_RECEIVER_FOREGROUND); 16264 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16265 broadcastIntentLocked(null, null, intent, 16266 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16267 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16268 } 16269 if (newUserId >= 0) { 16270 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16271 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16272 | Intent.FLAG_RECEIVER_FOREGROUND); 16273 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16274 broadcastIntentLocked(null, null, intent, 16275 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16276 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16277 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16278 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16279 | Intent.FLAG_RECEIVER_FOREGROUND); 16280 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16281 broadcastIntentLocked(null, null, intent, 16282 null, null, 0, null, null, 16283 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16284 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16285 } 16286 } finally { 16287 Binder.restoreCallingIdentity(ident); 16288 } 16289 } 16290 16291 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16292 final int newUserId) { 16293 final int N = mUserSwitchObservers.beginBroadcast(); 16294 if (N > 0) { 16295 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16296 int mCount = 0; 16297 @Override 16298 public void sendResult(Bundle data) throws RemoteException { 16299 synchronized (ActivityManagerService.this) { 16300 if (mCurUserSwitchCallback == this) { 16301 mCount++; 16302 if (mCount == N) { 16303 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16304 } 16305 } 16306 } 16307 } 16308 }; 16309 synchronized (this) { 16310 uss.switching = true; 16311 mCurUserSwitchCallback = callback; 16312 } 16313 for (int i=0; i<N; i++) { 16314 try { 16315 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16316 newUserId, callback); 16317 } catch (RemoteException e) { 16318 } 16319 } 16320 } else { 16321 synchronized (this) { 16322 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16323 } 16324 } 16325 mUserSwitchObservers.finishBroadcast(); 16326 } 16327 16328 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16329 synchronized (this) { 16330 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16331 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16332 } 16333 } 16334 16335 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16336 mCurUserSwitchCallback = null; 16337 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16338 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16339 oldUserId, newUserId, uss)); 16340 } 16341 16342 void userInitialized(UserStartedState uss, int newUserId) { 16343 completeSwitchAndInitalize(uss, newUserId, true, false); 16344 } 16345 16346 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16347 completeSwitchAndInitalize(uss, newUserId, false, true); 16348 } 16349 16350 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16351 boolean clearInitializing, boolean clearSwitching) { 16352 boolean unfrozen = false; 16353 synchronized (this) { 16354 if (clearInitializing) { 16355 uss.initializing = false; 16356 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16357 } 16358 if (clearSwitching) { 16359 uss.switching = false; 16360 } 16361 if (!uss.switching && !uss.initializing) { 16362 mWindowManager.stopFreezingScreen(); 16363 unfrozen = true; 16364 } 16365 } 16366 if (unfrozen) { 16367 final int N = mUserSwitchObservers.beginBroadcast(); 16368 for (int i=0; i<N; i++) { 16369 try { 16370 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16371 } catch (RemoteException e) { 16372 } 16373 } 16374 mUserSwitchObservers.finishBroadcast(); 16375 } 16376 } 16377 16378 void scheduleStartRelatedUsersLocked() { 16379 if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) { 16380 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG), 16381 DateUtils.SECOND_IN_MILLIS); 16382 } 16383 } 16384 16385 void startRelatedUsersLocked() { 16386 if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked"); 16387 List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId); 16388 List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size()); 16389 for (UserInfo relatedUser : relatedUsers) { 16390 if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) { 16391 toStart.add(relatedUser); 16392 } 16393 } 16394 final int n = toStart.size(); 16395 int i = 0; 16396 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16397 startUserInBackground(toStart.get(i).id); 16398 } 16399 if (i < n) { 16400 Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS"); 16401 } 16402 } 16403 16404 void finishUserSwitch(UserStartedState uss) { 16405 synchronized (this) { 16406 if (uss.mState == UserStartedState.STATE_BOOTING 16407 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16408 uss.mState = UserStartedState.STATE_RUNNING; 16409 final int userId = uss.mHandle.getIdentifier(); 16410 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16411 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16412 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16413 broadcastIntentLocked(null, null, intent, 16414 null, null, 0, null, null, 16415 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16416 true, false, MY_PID, Process.SYSTEM_UID, userId); 16417 } 16418 16419 startRelatedUsersLocked(); 16420 16421 int num = mUserLru.size(); 16422 int i = 0; 16423 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16424 Integer oldUserId = mUserLru.get(i); 16425 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16426 if (oldUss == null) { 16427 // Shouldn't happen, but be sane if it does. 16428 mUserLru.remove(i); 16429 num--; 16430 continue; 16431 } 16432 if (oldUss.mState == UserStartedState.STATE_STOPPING 16433 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16434 // This user is already stopping, doesn't count. 16435 num--; 16436 i++; 16437 continue; 16438 } 16439 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16440 // Owner and current can't be stopped, but count as running. 16441 i++; 16442 continue; 16443 } 16444 // This is a user to be stopped. 16445 stopUserLocked(oldUserId, null); 16446 num--; 16447 i++; 16448 } 16449 } 16450 } 16451 16452 @Override 16453 public int stopUser(final int userId, final IStopUserCallback callback) { 16454 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16455 != PackageManager.PERMISSION_GRANTED) { 16456 String msg = "Permission Denial: switchUser() from pid=" 16457 + Binder.getCallingPid() 16458 + ", uid=" + Binder.getCallingUid() 16459 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16460 Slog.w(TAG, msg); 16461 throw new SecurityException(msg); 16462 } 16463 if (userId <= 0) { 16464 throw new IllegalArgumentException("Can't stop primary user " + userId); 16465 } 16466 synchronized (this) { 16467 return stopUserLocked(userId, callback); 16468 } 16469 } 16470 16471 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16472 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16473 if (mCurrentUserId == userId) { 16474 return ActivityManager.USER_OP_IS_CURRENT; 16475 } 16476 16477 final UserStartedState uss = mStartedUsers.get(userId); 16478 if (uss == null) { 16479 // User is not started, nothing to do... but we do need to 16480 // callback if requested. 16481 if (callback != null) { 16482 mHandler.post(new Runnable() { 16483 @Override 16484 public void run() { 16485 try { 16486 callback.userStopped(userId); 16487 } catch (RemoteException e) { 16488 } 16489 } 16490 }); 16491 } 16492 return ActivityManager.USER_OP_SUCCESS; 16493 } 16494 16495 if (callback != null) { 16496 uss.mStopCallbacks.add(callback); 16497 } 16498 16499 if (uss.mState != UserStartedState.STATE_STOPPING 16500 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16501 uss.mState = UserStartedState.STATE_STOPPING; 16502 updateStartedUserArrayLocked(); 16503 16504 long ident = Binder.clearCallingIdentity(); 16505 try { 16506 // We are going to broadcast ACTION_USER_STOPPING and then 16507 // once that is done send a final ACTION_SHUTDOWN and then 16508 // stop the user. 16509 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16510 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16511 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16512 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16513 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16514 // This is the result receiver for the final shutdown broadcast. 16515 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16516 @Override 16517 public void performReceive(Intent intent, int resultCode, String data, 16518 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16519 finishUserStop(uss); 16520 } 16521 }; 16522 // This is the result receiver for the initial stopping broadcast. 16523 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16524 @Override 16525 public void performReceive(Intent intent, int resultCode, String data, 16526 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16527 // On to the next. 16528 synchronized (ActivityManagerService.this) { 16529 if (uss.mState != UserStartedState.STATE_STOPPING) { 16530 // Whoops, we are being started back up. Abort, abort! 16531 return; 16532 } 16533 uss.mState = UserStartedState.STATE_SHUTDOWN; 16534 } 16535 broadcastIntentLocked(null, null, shutdownIntent, 16536 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16537 true, false, MY_PID, Process.SYSTEM_UID, userId); 16538 } 16539 }; 16540 // Kick things off. 16541 broadcastIntentLocked(null, null, stoppingIntent, 16542 null, stoppingReceiver, 0, null, null, 16543 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16544 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16545 } finally { 16546 Binder.restoreCallingIdentity(ident); 16547 } 16548 } 16549 16550 return ActivityManager.USER_OP_SUCCESS; 16551 } 16552 16553 void finishUserStop(UserStartedState uss) { 16554 final int userId = uss.mHandle.getIdentifier(); 16555 boolean stopped; 16556 ArrayList<IStopUserCallback> callbacks; 16557 synchronized (this) { 16558 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16559 if (mStartedUsers.get(userId) != uss) { 16560 stopped = false; 16561 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16562 stopped = false; 16563 } else { 16564 stopped = true; 16565 // User can no longer run. 16566 mStartedUsers.remove(userId); 16567 mUserLru.remove(Integer.valueOf(userId)); 16568 updateStartedUserArrayLocked(); 16569 16570 // Clean up all state and processes associated with the user. 16571 // Kill all the processes for the user. 16572 forceStopUserLocked(userId, "finish user"); 16573 } 16574 } 16575 16576 for (int i=0; i<callbacks.size(); i++) { 16577 try { 16578 if (stopped) callbacks.get(i).userStopped(userId); 16579 else callbacks.get(i).userStopAborted(userId); 16580 } catch (RemoteException e) { 16581 } 16582 } 16583 16584 mStackSupervisor.removeUserLocked(userId); 16585 } 16586 16587 @Override 16588 public UserInfo getCurrentUser() { 16589 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16590 != PackageManager.PERMISSION_GRANTED) && ( 16591 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16592 != PackageManager.PERMISSION_GRANTED)) { 16593 String msg = "Permission Denial: getCurrentUser() from pid=" 16594 + Binder.getCallingPid() 16595 + ", uid=" + Binder.getCallingUid() 16596 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16597 Slog.w(TAG, msg); 16598 throw new SecurityException(msg); 16599 } 16600 synchronized (this) { 16601 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16602 } 16603 } 16604 16605 int getCurrentUserIdLocked() { 16606 return mCurrentUserId; 16607 } 16608 16609 @Override 16610 public boolean isUserRunning(int userId, boolean orStopped) { 16611 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16612 != PackageManager.PERMISSION_GRANTED) { 16613 String msg = "Permission Denial: isUserRunning() from pid=" 16614 + Binder.getCallingPid() 16615 + ", uid=" + Binder.getCallingUid() 16616 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16617 Slog.w(TAG, msg); 16618 throw new SecurityException(msg); 16619 } 16620 synchronized (this) { 16621 return isUserRunningLocked(userId, orStopped); 16622 } 16623 } 16624 16625 boolean isUserRunningLocked(int userId, boolean orStopped) { 16626 UserStartedState state = mStartedUsers.get(userId); 16627 if (state == null) { 16628 return false; 16629 } 16630 if (orStopped) { 16631 return true; 16632 } 16633 return state.mState != UserStartedState.STATE_STOPPING 16634 && state.mState != UserStartedState.STATE_SHUTDOWN; 16635 } 16636 16637 @Override 16638 public int[] getRunningUserIds() { 16639 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16640 != PackageManager.PERMISSION_GRANTED) { 16641 String msg = "Permission Denial: isUserRunning() from pid=" 16642 + Binder.getCallingPid() 16643 + ", uid=" + Binder.getCallingUid() 16644 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16645 Slog.w(TAG, msg); 16646 throw new SecurityException(msg); 16647 } 16648 synchronized (this) { 16649 return mStartedUserArray; 16650 } 16651 } 16652 16653 private void updateStartedUserArrayLocked() { 16654 int num = 0; 16655 for (int i=0; i<mStartedUsers.size(); i++) { 16656 UserStartedState uss = mStartedUsers.valueAt(i); 16657 // This list does not include stopping users. 16658 if (uss.mState != UserStartedState.STATE_STOPPING 16659 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16660 num++; 16661 } 16662 } 16663 mStartedUserArray = new int[num]; 16664 num = 0; 16665 for (int i=0; i<mStartedUsers.size(); i++) { 16666 UserStartedState uss = mStartedUsers.valueAt(i); 16667 if (uss.mState != UserStartedState.STATE_STOPPING 16668 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16669 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16670 num++; 16671 } 16672 } 16673 } 16674 16675 @Override 16676 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16677 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16678 != PackageManager.PERMISSION_GRANTED) { 16679 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16680 + Binder.getCallingPid() 16681 + ", uid=" + Binder.getCallingUid() 16682 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16683 Slog.w(TAG, msg); 16684 throw new SecurityException(msg); 16685 } 16686 16687 mUserSwitchObservers.register(observer); 16688 } 16689 16690 @Override 16691 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16692 mUserSwitchObservers.unregister(observer); 16693 } 16694 16695 private boolean userExists(int userId) { 16696 if (userId == 0) { 16697 return true; 16698 } 16699 UserManagerService ums = getUserManagerLocked(); 16700 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16701 } 16702 16703 int[] getUsersLocked() { 16704 UserManagerService ums = getUserManagerLocked(); 16705 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16706 } 16707 16708 UserManagerService getUserManagerLocked() { 16709 if (mUserManager == null) { 16710 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16711 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16712 } 16713 return mUserManager; 16714 } 16715 16716 private int applyUserId(int uid, int userId) { 16717 return UserHandle.getUid(userId, uid); 16718 } 16719 16720 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16721 if (info == null) return null; 16722 ApplicationInfo newInfo = new ApplicationInfo(info); 16723 newInfo.uid = applyUserId(info.uid, userId); 16724 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16725 + info.packageName; 16726 return newInfo; 16727 } 16728 16729 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16730 if (aInfo == null 16731 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16732 return aInfo; 16733 } 16734 16735 ActivityInfo info = new ActivityInfo(aInfo); 16736 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16737 return info; 16738 } 16739} 16740